diff --git a/src/libslic3r/MTUtils.hpp b/src/libslic3r/MTUtils.hpp index 1e0fb426aa..1f6ca1a237 100644 --- a/src/libslic3r/MTUtils.hpp +++ b/src/libslic3r/MTUtils.hpp @@ -56,6 +56,113 @@ public: } }; +template +class IndexBasedIterator { + static const size_t NONE = size_t(-1); + + std::reference_wrapper m_index_ref; + size_t m_idx = NONE; +public: + + using value_type = Value; + using pointer = Value *; + using reference = Value &; + using difference_type = long; + using iterator_category = std::random_access_iterator_tag; + + inline explicit + IndexBasedIterator(Vector& index, size_t idx): + m_index_ref(index), m_idx(idx) {} + + // Post increment + inline IndexBasedIterator operator++(int) { + IndexBasedIterator cpy(*this); ++m_idx; return cpy; + } + + inline IndexBasedIterator operator--(int) { + IndexBasedIterator cpy(*this); --m_idx; return cpy; + } + + inline IndexBasedIterator& operator++() { + ++m_idx; return *this; + } + + inline IndexBasedIterator& operator--() { + --m_idx; return *this; + } + + inline IndexBasedIterator& operator+=(difference_type l) { + m_idx += size_t(l); return *this; + } + + inline IndexBasedIterator operator+(difference_type l) { + auto cpy = *this; cpy += l; return cpy; + } + + inline IndexBasedIterator& operator-=(difference_type l) { + m_idx -= size_t(l); return *this; + } + + inline IndexBasedIterator operator-(difference_type l) { + auto cpy = *this; cpy -= l; return cpy; + } + + operator difference_type() { return difference_type(m_idx); } + + inline bool is_end() const { return m_idx >= m_index_ref.get().size();} + + inline Value & operator*() const { + assert(m_idx < m_index_ref.get().size()); + return m_index_ref.get().operator[](m_idx); + } + + inline Value * operator->() const { + assert(m_idx < m_index_ref.get().size()); + return &m_index_ref.get().operator[](m_idx); + } + + 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); + } + + inline bool operator !=(const IndexBasedIterator& other) { + return !(*this == other); + } + + inline bool operator <=(const IndexBasedIterator& other) { + return (m_idx < other.m_idx) || (*this == other); + } + + inline bool operator <(const IndexBasedIterator& other) { + return m_idx < other.m_idx && (*this != other); + } + + inline bool operator >=(const IndexBasedIterator& other) { + return m_idx > other.m_idx || *this == other; + } + + inline bool operator >(const IndexBasedIterator& other) { + return m_idx > other.m_idx && *this != other; + } +}; + +template class Range { + It from, to; +public: + It begin() const { return from; } + It end() const { return to; } + using Type = It; + + Range() = default; + Range(It &&b, It &&e): + from(std::forward(b)), to(std::forward(e)) {} + + inline size_t size() const { return end() - begin(); } + inline bool empty() const { return size() == 0; } +}; + } #endif // MTUTILS_HPP diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp index 58386c0bdb..4d34b8e7d4 100644 --- a/src/libslic3r/SLAPrint.cpp +++ b/src/libslic3r/SLAPrint.cpp @@ -626,8 +626,8 @@ void SLAPrint::process() double lhd = m_objects.front()->m_config.layer_height.getFloat(); float lh = float(lhd); - LevelID ilhs = ilhd / SCALING_FACTOR; - LevelID lhs = lhd / SCALING_FACTOR; + 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 @@ -657,17 +657,15 @@ void SLAPrint::process() double minZ = bb3d.min(Z) - po.get_elevation(); double maxZ = bb3d.max(Z); - LevelID minZs = minZ / SCALING_FACTOR; - LevelID maxZs = maxZ / SCALING_FACTOR; - - auto slh = [](float h) { return LevelID( double(h) / SCALING_FACTOR); }; + auto minZs = LevelID(minZ / SCALING_FACTOR); + auto maxZs = LevelID(maxZ / SCALING_FACTOR); po.m_slice_index.clear(); po.m_slice_index.reserve(size_t(maxZs - (minZs + ilhs) / lhs) + 1); - po.m_slice_index.emplace_back(minZs + ilhs, minZ + ilh / 2.f, ilh); + po.m_slice_index.emplace_back(minZs + ilhs, float(minZ) + ilh / 2.f, ilh); for(LevelID h = minZs + ilhs + lhs; h <= maxZs; h += lhs) { - po.m_slice_index.emplace_back(h, h*SCALING_FACTOR - lh / 2.f, lh); + po.m_slice_index.emplace_back(h, float(h*SCALING_FACTOR) - lh / 2.f, lh); } auto slindex_it = po.search_slice_index(float(bb3d.min(Z))); @@ -867,8 +865,10 @@ void SLAPrint::process() // be part of the slices) auto slice_supports = [](SLAPrintObject& po) { auto& sd = po.m_supportdata; + + if(sd) sd->support_slices.clear(); + if(sd && sd->support_tree_ptr) { - sd->support_slices.clear(); std::vector heights; heights.reserve(po.m_slice_index.size()); @@ -891,75 +891,6 @@ void SLAPrint::process() // We have the layer polygon collection but we need to unite them into // an index where the key is the height level in discrete levels (clipper) auto index_slices = [this/*, ilhd*/](SLAPrintObject& /*po*/) { -// po.m_slice_index.clear(); -// auto sih = LevelID(scale_(ilhd)); - -// // Establish the slice grid boundaries -// auto bb = po.transformed_mesh().bounding_box(); -// double modelgnd = bb.min(Z); -// double elevation = po.get_elevation(); -// double lh = po.m_config.layer_height.getFloat(); -// double minZ = modelgnd - elevation; - -// // scaled values: -// auto sminZ = LevelID(scale_(minZ)); -// auto smaxZ = LevelID(scale_(bb.max(Z))); -// auto smodelgnd = LevelID(scale_(modelgnd)); -// auto slh = LevelID(scale_(lh)); - -// // It is important that the next levels match the levels in -// // model_slice method. Only difference is that here it works with -// // scaled coordinates -// po.m_level_ids.clear(); -// for(LevelID h = sminZ + sih; h < smaxZ; h += slh) -// if(h >= smodelgnd) po.m_level_ids.emplace_back(h); - -// std::vector& oslices = po.m_model_slices; - -// // If everything went well this code should not run at all, but -// // let's be robust... -// // assert(levelids.size() == oslices.size()); -// if(po.m_level_ids.size() < oslices.size()) { // extend the levels until... - -// BOOST_LOG_TRIVIAL(warning) -// << "Height level mismatch at rasterization!\n"; - -// LevelID lastlvl = po.m_level_ids.back(); -// while(po.m_level_ids.size() < oslices.size()) { -// lastlvl += slh; -// po.m_level_ids.emplace_back(lastlvl); -// } -// } - -// for(size_t i = 0; i < oslices.size(); ++i) { -// LevelID h = po.m_level_ids[i]; - -// float fh = float(double(h) * SCALING_FACTOR); - -// // now for the public slice index: -// SLAPrintObject::SliceRecord& sr = po.m_slice_index[fh]; -// // There should be only one slice layer for each print object -// assert(sr.model_slices_idx == SLAPrintObject::SliceRecord::NONE); -// sr.model_slices_idx = i; -// } - -// if(po.m_supportdata) { // deal with the support slices if present -// std::vector& sslices = po.m_supportdata->support_slices; -// po.m_supportdata->level_ids.clear(); -// po.m_supportdata->level_ids.reserve(sslices.size()); - -// for(int i = 0; i < int(sslices.size()); ++i) { -// LevelID h = sminZ + sih + i * slh; -// po.m_supportdata->level_ids.emplace_back(h); - -// float fh = float(double(h) * SCALING_FACTOR); - -// SLAPrintObject::SliceRecord& sr = po.m_slice_index[fh]; -// assert(sr.support_slices_idx == SLAPrintObject::SliceRecord::NONE); -// sr.support_slices_idx = SLAPrintObject::SliceRecord::Idx(i); -// } -// } - // Using RELOAD_SLA_PREVIEW to tell the Plater to pass the update status to the 3D preview to load the SLA slices. report_status(*this, -2, "", SlicingStatus::RELOAD_SLA_PREVIEW); }; @@ -975,41 +906,16 @@ void SLAPrint::process() LevelID gndlvl = o->get_slice_index().front().key(); for(auto& slicerecord : o->get_slice_index()) { auto& lyrs = m_printer_input[slicerecord.key() - gndlvl]; - auto objslit = slicerecord.get_slices(*o, soModel); - auto supslit = slicerecord.get_slices(*o, soSupport); - if(objslit != o->get_model_slices().end()) - lyrs.emplace_back(*objslit, o->instances()); + const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel); + const ExPolygons& supslices = o->get_slices_from_record(slicerecord, soSupport); - if(supslit != o->get_support_slices().end()) - lyrs.emplace_back(*supslit, o->instances()); + if(!objslices.empty()) + lyrs.emplace_back(objslices, o->instances()); + + if(!supslices.empty()) + lyrs.emplace_back(supslices, o->instances()); } - -// auto& po = *o; -// std::vector& oslices = po.m_model_slices; - -// // We need to adjust the min Z level of the slices to be zero -// LevelID smfirst = -// po.m_supportdata && !po.m_supportdata->level_ids.empty() ? -// po.m_supportdata->level_ids.front() : 0; -// LevelID mfirst = po.m_level_ids.empty()? 0 : po.m_level_ids.front(); -// LevelID gndlvl = -(std::min(smfirst, mfirst)); - -// // now merge this object's support and object slices with the rest -// // of the print object slices - -// for(size_t i = 0; i < oslices.size(); ++i) { -// auto& lyrs = m_printer_input[gndlvl + po.m_level_ids[i]]; -// lyrs.emplace_back(oslices[i], po.m_instances); -// } - -// if(!po.m_supportdata) continue; -// std::vector& sslices = po.m_supportdata->support_slices; -// for(size_t i = 0; i < sslices.size(); ++i) { -// LayerRefs& lyrs = -// m_printer_input[gndlvl + po.m_supportdata->level_ids[i]]; -// lyrs.emplace_back(sslices[i], po.m_instances); -// } } // collect all the keys @@ -1355,13 +1261,13 @@ void SLAPrint::fill_statistics() record = &(*it); } - auto modelslice_it = record->get_slices(*po, soModel); - if (modelslice_it != po->get_model_slices().end()) - append(model_polygons, get_all_polygons(*modelslice_it, po->instances())); - - auto supportslice_it = record->get_slices(*po, soSupport); - if (supportslice_it != po->get_support_slices().end()) - append(supports_polygons, get_all_polygons(*supportslice_it, po->instances())); + const ExPolygons &modelslices = po->get_slices_from_record(*record, soModel); + if (!modelslices.empty()) + append(model_polygons, get_all_polygons(modelslices, po->instances())); + + const ExPolygons &supportslices = po->get_slices_from_record(*record, soSupport); + if (!supportslices.empty()) + append(supports_polygons, get_all_polygons(supportslices, po->instances())); } model_polygons = union_(model_polygons); @@ -1561,6 +1467,7 @@ double SLAPrintObject::get_current_elevation() const namespace { // dummy empty static containers for return values in some methods const std::vector EMPTY_SLICES; const TriangleMesh EMPTY_MESH; +const ExPolygons EMPTY_SLICE; } const std::vector& SLAPrintObject::get_support_points() const @@ -1597,7 +1504,8 @@ SLAPrintObject::search_slice_index(float slice_level) const } SLAPrintObject::SliceIndex::iterator -SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) +SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key, + bool exact) { _SliceRecord query(key, 0.f, 0.f); auto it = std::lower_bound(m_slice_index.begin(), m_slice_index.end(), @@ -1608,13 +1516,15 @@ SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) }); // Return valid iterator only if the keys really match - if(it != m_slice_index.end() && it->key() != key) it = m_slice_index.end(); + if(exact && it != m_slice_index.end() && it->key() != key) + it = m_slice_index.end(); return it; } SLAPrintObject::SliceIndex::const_iterator -SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) const +SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key, + bool exact) const { _SliceRecord query(key, 0.f, 0.f); auto it = std::lower_bound(m_slice_index.cbegin(), m_slice_index.cend(), @@ -1625,28 +1535,12 @@ SLAPrintObject::search_slice_index(SLAPrintObject::_SliceRecord::Key key) const }); // Return valid iterator only if the keys really match - if(it != m_slice_index.end() && it->key() != key) it = m_slice_index.end(); + if(exact && it != m_slice_index.end() && it->key() != key) + it = m_slice_index.end(); return it; } -SliceRange SLAPrintObject::get_slices(SliceOrigin so, - float from_level, - float to_level) const -{ - auto it_from = search_slice_index(from_level); - auto it_to = search_slice_index(to_level); - - SliceRange ret; - - auto endit = so == soModel? get_model_slices().end() : get_support_slices().end(); - - ret.from = it_from == m_slice_index.end() ? endit : it_from->get_slices(*this, so); - ret.to = it_to == m_slice_index.end() ? endit : it_to->get_slices(*this, so); - - return ret; -} - const std::vector &SLAPrintObject::get_support_slices() const { // assert(is_step_done(slaposSliceSupports)); @@ -1654,6 +1548,28 @@ const std::vector &SLAPrintObject::get_support_slices() const return m_supportdata->support_slices; } +const ExPolygons &SLAPrintObject::get_slices_from_record( + const _SliceRecord &rec, + SliceOrigin o) const +{ + size_t idx = o == soModel ? rec.get_model_slice_idx() : + rec.get_support_slice_idx(); + + const std::vector& v = o == soModel? get_model_slices() : + get_support_slices(); + + if(idx >= v.size()) return EMPTY_SLICE; + + return idx >= v.size() ? EMPTY_SLICE : v[idx]; +} + +const ExPolygons &SLAPrintObject::get_slices_from_record( + SLAPrintObject::SliceRecordConstIterator it, SliceOrigin o) const +{ + if(it.is_end()) return EMPTY_SLICE; + return get_slices_from_record(*it, o); +} + const std::vector& SLAPrintObject::get_slice_index() const { @@ -1778,18 +1694,4 @@ std::string SLAPrintStatistics::finalize_output_path(const std::string &path_in) return final_path; } -SliceIterator SLAPrintObject::_SliceRecord::get_slices(const SLAPrintObject &po, - SliceOrigin so) const -{ - - const std::vector& v = so == soModel? po.get_model_slices() : - po.get_support_slices(); - - size_t idx = so == soModel ? m_model_slices_idx : m_support_slices_idx; - - using DiffT = std::vector::const_iterator::difference_type; - - return idx == NONE? v.end() : v.begin() + DiffT(idx); -} - } // namespace Slic3r diff --git a/src/libslic3r/SLAPrint.hpp b/src/libslic3r/SLAPrint.hpp index b33bfdeb08..ff715fb5ed 100644 --- a/src/libslic3r/SLAPrint.hpp +++ b/src/libslic3r/SLAPrint.hpp @@ -6,6 +6,7 @@ #include "PrintExport.hpp" #include "Point.hpp" #include "MTUtils.hpp" +#include namespace Slic3r { @@ -35,23 +36,8 @@ using _SLAPrintObjectBase = // the printer (rasterizer) in the SLAPrint class. using LevelID = long long; -template struct Range { - It from, to; - It begin() const { return from; } - It end() const { return to; } - using Type = It; - - Range() = default; - explicit Range(It &&b, It &&e): - from(std::forward(b)), to(std::forward(e)) {} -}; - enum SliceOrigin { soSupport, soModel }; -using SliceStore = std::vector; -using SliceIterator = SliceStore::const_iterator; -using SliceRange = Range; - class SLAPrintObject : public _SLAPrintObjectBase { private: // Prevents erroneous use by other classes. @@ -107,12 +93,14 @@ public: // This method returns the support points of this SLAPrintObject. const std::vector& get_support_points() const; + // The public Slice record structure. It corresponds to one printable layer. + // To get the sliced polygons, use SLAPrintObject::get_slices_from_record class SliceRecord { public: using Key = LevelID; private: - LevelID m_print_z = 0; // Top of the layer + Key m_print_z = 0; // Top of the layer float m_slice_z = 0.f; // Exact level of the slice float m_height = 0.f; // Height of the sliced layer @@ -139,8 +127,9 @@ private: // levels of the model in scaled-clipper coordinates. The levels correspond // to the z coordinate of the object coordinate system. class _SliceRecord: public SliceRecord { - private: + public: static const size_t NONE = size_t(-1); // this will be the max limit of size_t + private: size_t m_model_slices_idx = NONE; size_t m_support_slices_idx = NONE; @@ -148,14 +137,12 @@ private: _SliceRecord(Key key, float slicez, float height): SliceRecord(key, slicez, height) {} - // Returns the slices for either the model or the supports. The return - // value is an iterator to po.get_model_slices() or po.get_support_slices - // depending on the SliceOrigin parameter. - SliceIterator get_slices(const SLAPrintObject& po, SliceOrigin so) const; - - // Methods for setting the indixes into the slice vectors. + // Methods for setting the indices into the slice vectors. void set_model_slice_idx(size_t id) { m_model_slices_idx = id; } void set_support_slice_idx(size_t id) { m_support_slices_idx = id; } + + inline size_t get_model_slice_idx() const { return m_model_slices_idx; } + inline size_t get_support_slice_idx() const { return m_support_slices_idx; } }; // Slice index will be a plain vector sorted by the integer height levels @@ -171,37 +158,78 @@ 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() - SliceIndex::iterator search_slice_index(_SliceRecord::Key key); - SliceIndex::const_iterator search_slice_index(_SliceRecord::Key key) const; + // This behavior can be suppressed by the second parameter. If it is true + // 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; + + const std::vector& get_model_slices() const; + const std::vector& get_support_slices() const; public: - // ///////////////////////////////////////////////////////////////////////// - // The following methods can be used after the model and the support slicing - // steps have been succesfully finished. - // ///////////////////////////////////////////////////////////////////////// - - // Getting slices (model or supports) for a Z coordinate range. The returned - // iterators should include the slices for the given boundaries as well. - SliceRange get_slices( - SliceOrigin so, - float from_level, - float to_level = std::numeric_limits::infinity()) const; + // Should work as a polymorphic bidirectional iterator to the slice records + using SliceRecordConstIterator = + IndexBasedIterator; + // ///////////////////////////////////////////////////////////////////////// + // // These two methods should be callable on the client side (e.g. UI thread) // when the appropriate steps slaposObjectSlice and slaposSliceSupports // are ready. All the print objects are processed before slapsRasterize so // it is safe to call them during and/or after slapsRasterize. - const std::vector& get_model_slices() const; - const std::vector& get_support_slices() const; + // + // ///////////////////////////////////////////////////////////////////////// - // Returns the total number of slices in the slice grid (model and supports) - inline size_t get_slice_count() const { return m_slice_index.size(); } + // Get the slice records from a range of slice levels (inclusive). Floating + // point keys are the levels where the model was sliced with the mesh + // slicer. Integral keys are the keys of the slice records, which + // correspond to the top of each layer.. The end() method of the returned + // range points *after* the last valid element. This is for being + // consistent with std and makeing range based for loops work. use + // std::prev(range.end()) or --range.end() to get the last element. + template Range + get_slice_records(Key from, Key to = std::numeric_limits::max()) const + { + SliceIndex::const_iterator it_from, it_to; + if(std::is_integral::value) { + it_from = search_slice_index(SliceRecord::Key(from)); + it_to = search_slice_index(SliceRecord::Key(to)); + } else if(std::is_floating_point::value) { + it_from = search_slice_index(float(from)); + it_to = search_slice_index(float(to)); + } else return { + SliceRecordConstIterator(m_slice_index, _SliceRecord::NONE ), + SliceRecordConstIterator(m_slice_index, _SliceRecord::NONE ), + }; - inline const SliceRecord& get_slice_record(size_t idx) const { - return m_slice_index[idx]; + auto start = m_slice_index.begin(); + + size_t bidx = it_from == m_slice_index.end() ? _SliceRecord::NONE : + size_t(it_from - start); + + size_t eidx = it_to == m_slice_index.end() ? _SliceRecord::NONE : + size_t(it_to - start) + 1; + + return { + SliceRecordConstIterator(m_slice_index, bidx), + SliceRecordConstIterator(m_slice_index, eidx), + }; } + // Get all the slice records as a range. + inline Range get_slice_records() const { + return { + SliceRecordConstIterator(m_slice_index, 0), + SliceRecordConstIterator(m_slice_index, m_slice_index.size()) + }; + } + + const ExPolygons& get_slices_from_record(SliceRecordConstIterator it, + SliceOrigin o) const; + + const ExPolygons& get_slices_from_record(const _SliceRecord& rec, + SliceOrigin o) const; protected: // to be called from SLAPrint only. friend class SLAPrint; @@ -242,7 +270,7 @@ private: // Exact (float) height levels mapped to the slices. Each record contains // the index to the model and the support slice vectors. - std::vector<_SliceRecord> m_slice_index; + std::vector<_SliceRecord> m_slice_index; std::vector m_model_height_levels; @@ -335,11 +363,6 @@ private: // Invalidate steps based on a set of parameters changed. bool invalidate_state_by_config_options(const std::vector &opt_keys); - std::vector calculate_heights(const BoundingBoxf3& bb, - float elevation, - float initial_layer_height, - float layer_height) const; - void fill_statistics(); SLAPrintConfig m_print_config; diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 0f1e15b76c..8acb5ad537 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5014,26 +5014,28 @@ void GLCanvas3D::_render_sla_slices() const if ((bottom_obj_triangles.empty() || bottom_sup_triangles.empty() || top_obj_triangles.empty() || top_sup_triangles.empty()) && obj->is_step_done(slaposIndexSlices)) { // FIXME: is this all right (by Tamas)? - SliceRange obj_range = obj->get_slices(soModel, float(min_z), float(max_z)); - SliceRange sup_range = obj->get_slices(soSupport, float(min_z), float(max_z)); - auto obj_end = obj->get_model_slices().end(); - auto sup_end = obj->get_support_slices().end(); + auto slice_range = obj->get_slice_records(coord_t(min_z / SCALING_FACTOR), + coord_t(max_z / SCALING_FACTOR)); + const ExPolygons& obj_bottom = obj->get_slices_from_record(slice_range.begin(), soModel); + const ExPolygons& obj_top = obj->get_slices_from_record(std::prev(slice_range.end()), soModel); + const ExPolygons& sup_bottom = obj->get_slices_from_record(slice_range.begin(), soSupport); + const ExPolygons& sup_top = obj->get_slices_from_record(std::prev(slice_range.end()), soSupport); // calculate model bottom cap - if(bottom_obj_triangles.empty() && obj_range.from != obj_end) - bottom_obj_triangles = triangulate_expolygons_3d(*obj_range.from, min_z, true); + if(bottom_obj_triangles.empty() && !obj_bottom.empty()) + bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, min_z, true); // calculate support bottom cap - if(bottom_sup_triangles.empty() && sup_range.from != sup_end) - bottom_sup_triangles = triangulate_expolygons_3d(*sup_range.from, min_z, true); + if(bottom_sup_triangles.empty() && !sup_bottom.empty()) + bottom_sup_triangles = triangulate_expolygons_3d(sup_bottom, min_z, true); // calculate model top cap - if(top_obj_triangles.empty() && obj_range.to != obj_end) - top_obj_triangles = triangulate_expolygons_3d(*obj_range.to, max_z, false); + if(top_obj_triangles.empty() && !obj_top.empty()) + top_obj_triangles = triangulate_expolygons_3d(obj_top, max_z, false); // calculate support top cap - if(top_sup_triangles.empty() && sup_range.to != sup_end) - top_sup_triangles = triangulate_expolygons_3d(*sup_range.to, max_z, false); + if(top_sup_triangles.empty() && !sup_top.empty()) + top_sup_triangles = triangulate_expolygons_3d(sup_top, max_z, false); // const std::vector& model_slices = obj->get_model_slices(); // const std::vector& support_slices = obj->get_support_slices(); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 10a4a12c7e..5edca6c969 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -775,10 +775,10 @@ void Preview::load_print_as_sla() double shift_z = obj->get_current_elevation(); if (obj->is_step_done(slaposIndexSlices)) { - size_t cnt = obj->get_slice_count(); - for (size_t i = 0; i < cnt; i++) + auto slicerecords = obj->get_slice_records(); + for (auto& rec : slicerecords) { - zs.insert(shift_z + obj->get_slice_record(i).key() * SCALING_FACTOR); + zs.insert(shift_z + /*rec.slice_level()*/ rec.key() * SCALING_FACTOR); } } }