diff --git a/src/libslic3r/MTUtils.hpp b/src/libslic3r/MTUtils.hpp index 1f6ca1a237..7e91ace328 100644 --- a/src/libslic3r/MTUtils.hpp +++ b/src/libslic3r/MTUtils.hpp @@ -56,8 +56,18 @@ public: } }; -template +/// An std compatible random access iterator which uses indices to the source +/// vector thus resistant to invalidation caused by relocations. It also "knows" +/// its container. No comparison is neccesary to the container "end()" iterator. +/// The template can be instantiated with a different value type than that of +/// the container's but the types must be compatible. E.g. a base class of the +/// contained objects is compatible. +/// +/// For a constant iterator, one can instantiate this template with a value +/// type preceded with 'const'. +template class IndexBasedIterator { static const size_t NONE = size_t(-1); @@ -110,6 +120,8 @@ public: operator difference_type() { return difference_type(m_idx); } + /// Tesing the end of the container... this is not possible with std + /// iterators. inline bool is_end() const { return m_idx >= m_index_ref.get().size();} inline Value & operator*() const { @@ -122,6 +134,7 @@ public: return &m_index_ref.get().operator[](m_idx); } + /// If both iterators point past the container, they are equal... inline bool operator ==(const IndexBasedIterator& other) { size_t e = m_index_ref.get().size(); return m_idx == other.m_idx || (m_idx >= e && other.m_idx >= e); @@ -148,17 +161,23 @@ public: } }; +/// A very simple range concept implementation with iterator-like objects. template class Range { It from, to; public: + + // The class is ready for range based for loops. It begin() const { return from; } It end() const { return to; } + + // The iterator type can be obtained this way. using Type = It; Range() = default; Range(It &&b, It &&e): from(std::forward(b)), to(std::forward(e)) {} + // Some useful container-like methods... inline size_t size() const { return end() - begin(); } inline bool empty() const { return size() == 0; } }; diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 79834908f2..c49ea417ce 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -623,11 +623,8 @@ void SLAPrint::process() // shortcut to initial layer height double ilhd = m_material_config.initial_layer_height.getFloat(); auto ilh = float(ilhd); - double lhd = m_objects.front()->m_config.layer_height.getFloat(); - float lh = float(lhd); auto ilhs = LevelID(ilhd / SCALING_FACTOR); - auto lhs = LevelID(lhd / SCALING_FACTOR); const size_t objcount = m_objects.size(); const unsigned min_objstatus = 0; // where the per object operations start @@ -648,11 +645,15 @@ void SLAPrint::process() // Slicing the model object. This method is oversimplified and needs to // be compared with the fff slicing algorithm for verification - auto slice_model = [this, ilhs, lhs, ilh, lh](SLAPrintObject& po) { + auto slice_model = [this, ilhs, ilh](SLAPrintObject& po) { TriangleMesh mesh = po.transformed_mesh(); // We need to prepare the slice index... + double lhd = m_objects.front()->m_config.layer_height.getFloat(); + float lh = float(lhd); + auto lhs = LevelID(lhd / SCALING_FACTOR); + auto&& bb3d = mesh.bounding_box(); double minZ = bb3d.min(Z) - po.get_elevation(); double maxZ = bb3d.max(Z); @@ -716,6 +717,12 @@ void SLAPrint::process() // into the backend cache. if (mo.sla_points_status != sla::PointsStatus::UserModified) { + // Hypotetical use of the slice index: + // auto bb = po.transformed_mesh().bounding_box(); + // auto range = po.get_slice_records(bb.min(Z)); + // std::vector heights; heights.reserve(range.size()); + // for(auto& record : range) heights.emplace_back(record.slice_level()); + // calculate heights of slices (slices are calculated already) const std::vector& heights = po.m_model_height_levels; @@ -896,15 +903,22 @@ void SLAPrint::process() }; // Rasterizing the model objects, and their supports - auto rasterize = [this, max_objstatus]() { + auto rasterize = [this, max_objstatus, ilhs]() { if(canceled()) return; // clear the rasterizer input m_printer_input.clear(); + auto eps = LevelID(EPSILON / SCALING_FACTOR); for(SLAPrintObject * o : m_objects) { - LevelID gndlvl = o->get_slice_index().front().key(); + LevelID gndlvl = o->get_slice_index().front().key() - ilhs; + for(auto& slicerecord : o->get_slice_index()) { + LevelID lvlid = slicerecord.key() - gndlvl; + + // Neat trick to round the layer levels to the grid. + lvlid = eps * (lvlid / eps); + auto& lyrs = m_printer_input[slicerecord.key() - gndlvl]; const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel); diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index fbe2821b21..a22696032a 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -158,7 +158,7 @@ private: // Search the slice index for a particular level in integer coordinates. // If no such layer is present, it will return m_slice_index.end() - // This behavior can be suppressed by the second parameter. If it is true + // This behavior can be suppressed by the second parameter. If it is false // the method will return the closest (non-equal) record SliceIndex::iterator search_slice_index(_SliceRecord::Key key, bool exact = false); SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key, bool = false) const;