mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	Refactoring changes to the slice index.
This commit is contained in:
		
							parent
							
								
									5e646562cd
								
							
						
					
					
						commit
						d165dbb498
					
				
					 5 changed files with 249 additions and 215 deletions
				
			
		|  | @ -56,6 +56,113 @@ public: | |||
|     } | ||||
| }; | ||||
| 
 | ||||
| template<class Vector, | ||||
|          class Value = typename Vector::value_type> | ||||
| class IndexBasedIterator { | ||||
|     static const size_t NONE = size_t(-1); | ||||
| 
 | ||||
|     std::reference_wrapper<Vector> 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 It> 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<It>(b)), to(std::forward<It>(e)) {} | ||||
| 
 | ||||
|     inline size_t size() const { return end() - begin(); } | ||||
|     inline bool empty() const { return size() == 0; } | ||||
| }; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| #endif // MTUTILS_HPP
 | ||||
|  |  | |||
|  | @ -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<float> 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<ExPolygons>& 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<ExPolygons>& 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<ExPolygons>& 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<ExPolygons>& 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<ExPolygons> EMPTY_SLICES; | ||||
| const TriangleMesh EMPTY_MESH; | ||||
| const ExPolygons EMPTY_SLICE; | ||||
| } | ||||
| 
 | ||||
| const std::vector<sla::SupportPoint>& 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<ExPolygons> &SLAPrintObject::get_support_slices() const | ||||
| { | ||||
|     // assert(is_step_done(slaposSliceSupports));
 | ||||
|  | @ -1654,6 +1548,28 @@ const std::vector<ExPolygons> &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<ExPolygons>& 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::_SliceRecord>& | ||||
| 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<ExPolygons>& 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<ExPolygons>::const_iterator::difference_type; | ||||
| 
 | ||||
|     return idx == NONE? v.end() : v.begin() + DiffT(idx); | ||||
| } | ||||
| 
 | ||||
| } // namespace Slic3r
 | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
| #include "PrintExport.hpp" | ||||
| #include "Point.hpp" | ||||
| #include "MTUtils.hpp" | ||||
| #include <iterator> | ||||
| 
 | ||||
| namespace Slic3r { | ||||
| 
 | ||||
|  | @ -35,23 +36,8 @@ using _SLAPrintObjectBase = | |||
| // the printer (rasterizer) in the SLAPrint class.
 | ||||
| using LevelID = long long; | ||||
| 
 | ||||
| template<class It> 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<It>(b)), to(std::forward<It>(e)) {} | ||||
| }; | ||||
| 
 | ||||
| enum SliceOrigin { soSupport, soModel }; | ||||
| 
 | ||||
| using SliceStore = std::vector<ExPolygons>; | ||||
| using SliceIterator = SliceStore::const_iterator; | ||||
| using SliceRange = Range<SliceIterator>; | ||||
| 
 | ||||
| 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<sla::SupportPoint>& 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<ExPolygons>& get_model_slices() const; | ||||
|     const std::vector<ExPolygons>& 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<float>::infinity()) const; | ||||
|     // Should work as a polymorphic bidirectional iterator to the slice records
 | ||||
|     using SliceRecordConstIterator = | ||||
|         IndexBasedIterator<const SliceIndex, const _SliceRecord>; | ||||
| 
 | ||||
|     // /////////////////////////////////////////////////////////////////////////
 | ||||
|     //
 | ||||
|     // 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<ExPolygons>& get_model_slices() const; | ||||
|     const std::vector<ExPolygons>& 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<class Key> Range<SliceRecordConstIterator> | ||||
|     get_slice_records(Key from, Key to = std::numeric_limits<Key>::max()) const | ||||
|     { | ||||
|         SliceIndex::const_iterator it_from, it_to; | ||||
|         if(std::is_integral<Key>::value) { | ||||
|             it_from = search_slice_index(SliceRecord::Key(from)); | ||||
|             it_to   = search_slice_index(SliceRecord::Key(to)); | ||||
|         } else if(std::is_floating_point<Key>::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<SliceRecordConstIterator> 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<float>                      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<t_config_option_key> &opt_keys); | ||||
| 
 | ||||
|     std::vector<float> calculate_heights(const BoundingBoxf3& bb, | ||||
|                                          float elevation, | ||||
|                                          float initial_layer_height, | ||||
|                                          float layer_height) const; | ||||
| 
 | ||||
|     void fill_statistics(); | ||||
| 
 | ||||
|     SLAPrintConfig                  m_print_config; | ||||
|  |  | |||
|  | @ -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<ExPolygons>& model_slices = obj->get_model_slices();
 | ||||
| //            const std::vector<ExPolygons>& support_slices = obj->get_support_slices();
 | ||||
|  |  | |||
|  | @ -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); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros