mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Further refactor and simplification of slice index and print data.
This commit is contained in:
		
							parent
							
								
									b4ea43a6b0
								
							
						
					
					
						commit
						57e28b53f2
					
				
					 3 changed files with 105 additions and 96 deletions
				
			
		|  | @ -698,7 +698,7 @@ void SLAPrint::process() | |||
|             id < po.m_model_slices.size() && mit != po.m_slice_index.end(); | ||||
|             id++) | ||||
|         { | ||||
|             mit->set_model_slice_idx(id); ++mit; | ||||
|             mit->set_model_slice_idx(po, id); ++mit; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|  | @ -894,7 +894,7 @@ void SLAPrint::process() | |||
|             i < sd->support_slices.size() && i < po.m_slice_index.size(); | ||||
|             ++i) | ||||
|         { | ||||
|             po.m_slice_index[i].set_support_slice_idx(i); | ||||
|             po.m_slice_index[i].set_support_slice_idx(po, i); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|  | @ -924,7 +924,7 @@ void SLAPrint::process() | |||
|         for(SLAPrintObject * o : m_objects) { | ||||
|             coord_t gndlvl = o->get_slice_index().front().print_level() - ilhs; | ||||
| 
 | ||||
|             for(auto& slicerecord : o->get_slice_index()) { | ||||
|             for(const SliceRecord& slicerecord : o->get_slice_index()) { | ||||
|                 coord_t lvlid = slicerecord.print_level() - gndlvl; | ||||
| 
 | ||||
|                 // Neat trick to round the layer levels to the grid.
 | ||||
|  | @ -932,21 +932,13 @@ void SLAPrint::process() | |||
| 
 | ||||
|                 auto it = std::lower_bound(m_printer_input.begin(), | ||||
|                                            m_printer_input.end(), | ||||
|                                            LayerRefs(lvlid)); | ||||
|                                            PrintLayer(lvlid)); | ||||
| 
 | ||||
|                 if(it == m_printer_input.end() || it->level != lvlid) | ||||
|                     it = m_printer_input.insert(it, LayerRefs(lvlid)); | ||||
|                     it = m_printer_input.insert(it, PrintLayer(lvlid)); | ||||
| 
 | ||||
|                 auto& lyrs = *it; | ||||
| 
 | ||||
|                 const ExPolygons& objslices = o->get_slices_from_record(slicerecord, soModel); | ||||
|                 const ExPolygons& supslices = o->get_slices_from_record(slicerecord, soSupport); | ||||
| 
 | ||||
|                 if(!objslices.empty()) | ||||
|                     lyrs.refs.emplace_back(objslices, o->instances()); | ||||
| 
 | ||||
|                 if(!supslices.empty()) | ||||
|                     lyrs.refs.emplace_back(supslices, o->instances()); | ||||
|                 it->slices.emplace_back(std::cref(slicerecord)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|  | @ -998,25 +990,40 @@ void SLAPrint::process() | |||
|         { | ||||
|             if(canceled()) return; | ||||
| 
 | ||||
|             LayerRefs& lrange = m_printer_input[level_id]; | ||||
|             PrintLayer& lrange = m_printer_input[level_id]; | ||||
| 
 | ||||
|             // Switch to the appropriate layer in the printer
 | ||||
|             printer.begin_layer(level_id); | ||||
| 
 | ||||
|             for(auto& lyrref : lrange.refs) { // for all layers in the current level
 | ||||
|             for(const SliceRecord& slrecord : lrange.slices) | ||||
|             { // for all layers in the current level
 | ||||
| 
 | ||||
|                 if(canceled()) break; | ||||
|                 const Layer& sl = lyrref.lref;   // get the layer reference
 | ||||
|                 const LayerCopies& copies = lyrref.copies; | ||||
| 
 | ||||
|                 // get the layer reference
 | ||||
|                 const ExPolygons& objslice = slrecord.get_slice(soModel); | ||||
|                 const ExPolygons& supslice = slrecord.get_slice(soModel); | ||||
|                 const SLAPrintObject *po = slrecord.print_obj(); | ||||
|                 assert(po != nullptr); | ||||
| 
 | ||||
|                 // Draw all the polygons in the slice to the actual layer.
 | ||||
|                 for(auto& cp : copies) { | ||||
|                     for(ExPolygon slice : sl) { | ||||
|                 for(const SLAPrintObject::Instance& tr : po->instances()) { | ||||
|                     for(ExPolygon poly : objslice) { | ||||
|                         // The order is important here:
 | ||||
|                         // apply rotation before translation...
 | ||||
|                         slice.rotate(double(cp.rotation)); | ||||
|                         slice.translate(cp.shift(X), cp.shift(Y)); | ||||
|                         if(flpXY) swapXY(slice); | ||||
|                         printer.draw_polygon(slice, level_id); | ||||
|                         poly.rotate(double(tr.rotation)); | ||||
|                         poly.translate(tr.shift(X), tr.shift(Y)); | ||||
|                         if(flpXY) swapXY(poly); | ||||
|                         printer.draw_polygon(poly, level_id); | ||||
|                     } | ||||
| 
 | ||||
|                     for(ExPolygon poly : supslice) { | ||||
|                         // The order is important here:
 | ||||
|                         // apply rotation before translation...
 | ||||
|                         poly.rotate(double(tr.rotation)); | ||||
|                         poly.translate(tr.shift(X), tr.shift(Y)); | ||||
|                         if(flpXY) swapXY(poly); | ||||
|                         printer.draw_polygon(poly, level_id); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -1026,11 +1033,13 @@ void SLAPrint::process() | |||
| 
 | ||||
|             // Status indication guarded with the spinlock
 | ||||
|             auto st = ist + unsigned(sd*level_id*slot/m_printer_input.size()); | ||||
|             { std::lock_guard<SpinMutex> lck(slck); | ||||
|             if( st > pst) { | ||||
|                 report_status(*this, int(st), PRINT_STEP_LABELS[slapsRasterize]); | ||||
|                 pst = st; | ||||
|             } | ||||
|             { | ||||
|                 std::lock_guard<SpinMutex> lck(slck); | ||||
|                 if( st > pst) { | ||||
|                     report_status(*this, int(st), | ||||
|                                   PRINT_STEP_LABELS[slapsRasterize]); | ||||
|                     pst = st; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|  | @ -1290,11 +1299,11 @@ void SLAPrint::fill_statistics() | |||
|                 record = &slr; | ||||
|             } | ||||
| 
 | ||||
|             const ExPolygons &modelslices = po->get_slices_from_record(*record, soModel); | ||||
|             const ExPolygons &modelslices = record->get_slice(soModel); | ||||
|             if (!modelslices.empty()) | ||||
|                 append(model_polygons, get_all_polygons(modelslices, po->instances())); | ||||
| 
 | ||||
|             const ExPolygons &supportslices = po->get_slices_from_record(*record, soSupport); | ||||
|             const ExPolygons &supportslices = record->get_slice(soSupport); | ||||
|             if (!supportslices.empty()) | ||||
|                 append(supports_polygons, get_all_polygons(supportslices, po->instances())); | ||||
|         } | ||||
|  | @ -1515,15 +1524,15 @@ 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 | ||||
| const ExPolygons &SliceRecord::get_slice(SliceOrigin o) const | ||||
| { | ||||
|     size_t idx = o == soModel ? rec.get_model_slice_idx() : | ||||
|                                 rec.get_support_slice_idx(); | ||||
|     size_t idx = o == soModel ? m_model_slices_idx : | ||||
|                                 m_support_slices_idx; | ||||
| 
 | ||||
|     const std::vector<ExPolygons>& v = o == soModel? get_model_slices() : | ||||
|                                                      get_support_slices(); | ||||
|     if(m_po == nullptr) return EMPTY_SLICE; | ||||
| 
 | ||||
|     const std::vector<ExPolygons>& v = o == soModel? m_po->get_model_slices() : | ||||
|                                                      m_po->get_support_slices(); | ||||
| 
 | ||||
|     if(idx >= v.size()) return EMPTY_SLICE; | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,8 +38,9 @@ using _SLAPrintObjectBase = | |||
| 
 | ||||
| enum SliceOrigin { soSupport, soModel }; | ||||
| 
 | ||||
| class SLAPrintObject; | ||||
| 
 | ||||
| // 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: | ||||
|     // this will be the max limit of size_t
 | ||||
|  | @ -54,6 +55,7 @@ private: | |||
| 
 | ||||
|     size_t m_model_slices_idx = NONE; | ||||
|     size_t m_support_slices_idx = NONE; | ||||
|     const SLAPrintObject *m_po = nullptr; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|  | @ -61,38 +63,28 @@ public: | |||
|         m_print_z(key), m_slice_z(slicez), m_height(height) {} | ||||
| 
 | ||||
|     // The key will be the integer height level of the top of the layer.
 | ||||
|     inline coord_t print_level() const { return m_print_z; } | ||||
|     coord_t print_level() const { return m_print_z; } | ||||
| 
 | ||||
|     // Returns the exact floating point Z coordinate of the slice
 | ||||
|     inline float slice_level() const { return m_slice_z; } | ||||
|     float slice_level() const { return m_slice_z; } | ||||
| 
 | ||||
|     // Returns the current layer height
 | ||||
|     inline float layer_height() const { return m_height; } | ||||
|     float layer_height() const { return m_height; } | ||||
| 
 | ||||
|     bool is_valid() const { return std::isnan(m_slice_z); } | ||||
| 
 | ||||
|     template <class T> inline T level() const { | ||||
|         static_assert(std::is_integral<T>::value || | ||||
|                       std::is_floating_point<T>::value, | ||||
|                       "Slice record level is only valid for numeric types!"); | ||||
|         if (std::is_integral<T>::value) return T(print_level()); | ||||
|         else return T(slice_level()); | ||||
|     } | ||||
| 
 | ||||
|     template <class T> inline static SliceRecord create(T val) { | ||||
|         static_assert(std::is_integral<T>::value || | ||||
|                       std::is_floating_point<T>::value, | ||||
|                       "Slice record level is only valid for numeric types!"); | ||||
|         if (std::is_integral<T>::value) return { coord_t(val), 0.f, 0.f }; | ||||
|         else return { 0, float(val), 0.f }; | ||||
|     } | ||||
|     const SLAPrintObject* print_obj() const { return m_po; } | ||||
| 
 | ||||
|     // 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; } | ||||
|     void set_model_slice_idx(const SLAPrintObject &po, size_t id) { | ||||
|         m_po = &po; m_model_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; } | ||||
|     void set_support_slice_idx(const SLAPrintObject& po, size_t id) { | ||||
|         m_po = &po; m_support_slices_idx = id; | ||||
|     } | ||||
| 
 | ||||
|     const ExPolygons& get_slice(SliceOrigin o) const; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -153,6 +145,16 @@ public: | |||
| 
 | ||||
| private: | ||||
| 
 | ||||
|     template <class T> inline static T level(const SliceRecord& sr) { | ||||
|         static_assert(std::is_arithmetic<T>::value, "Arithmetic only!"); | ||||
|         return std::is_integral<T>::value ? T(sr.print_level()) : T(sr.slice_level()); | ||||
|     } | ||||
| 
 | ||||
|     template <class T> inline static SliceRecord create_slice_record(T val) { | ||||
|         static_assert(std::is_arithmetic<T>::value, "Arithmetic only!"); | ||||
|         return std::is_integral<T>::value ? SliceRecord{ coord_t(val), 0.f, 0.f } : SliceRecord{ 0, float(val), 0.f }; | ||||
|     } | ||||
| 
 | ||||
|     // This is a template method for searching the slice index either by
 | ||||
|     // an integer key: print_level or a floating point key: slice_level.
 | ||||
|     // The eps parameter gives the max deviation in + or - direction.
 | ||||
|  | @ -162,23 +164,23 @@ private: | |||
|     static auto closest_slice_record(Container& cont, T lvl, T eps) -> decltype (cont.begin()) | ||||
|     { | ||||
|         if(cont.empty()) return cont.end(); | ||||
|         if(cont.size() == 1 && std::abs(cont.front().template level<T>() - lvl) > eps) | ||||
|         if(cont.size() == 1 && std::abs(level<T>(cont.front()) - lvl) > eps) | ||||
|             return cont.end(); | ||||
| 
 | ||||
|         SliceRecord query = SliceRecord::create(lvl); | ||||
|         SliceRecord query = create_slice_record(lvl); | ||||
| 
 | ||||
|         auto it = std::lower_bound(cont.begin(), cont.end(), query, | ||||
|                                    [](const SliceRecord& r1, | ||||
|                                       const SliceRecord& r2) | ||||
|         { | ||||
|             return r1.level<T>() < r2.level<T>(); | ||||
|             return level<T>(r1) < level<T>(r2); | ||||
|         }); | ||||
| 
 | ||||
|         T diff = std::abs(it->template level<T>() - lvl); | ||||
|         T diff = std::abs(level<T>(*it) - lvl); | ||||
| 
 | ||||
|         if(it != cont.begin()) { | ||||
|             auto it_prev = std::prev(it); | ||||
|             T diff_prev = std::abs(it_prev->template level<T>() - lvl); | ||||
|             T diff_prev = std::abs(level<T>(*it_prev) - lvl); | ||||
|             if(diff_prev < diff) { diff = diff_prev; it = it_prev; } | ||||
|         } | ||||
| 
 | ||||
|  | @ -226,9 +228,6 @@ public: | |||
|         return *it; | ||||
|     } | ||||
| 
 | ||||
|     // Get the actual slice polygons using a valid slice record.
 | ||||
|     const ExPolygons& get_slices_from_record( | ||||
|             const SliceRecord& rec, SliceOrigin o) const; | ||||
| protected: | ||||
|     // to be called from SLAPrint only.
 | ||||
|     friend class SLAPrint; | ||||
|  | @ -327,6 +326,24 @@ private: // Prevents erroneous use by other classes. | |||
|     typedef PrintBaseWithState<SLAPrintStep, slapsCount> Inherited; | ||||
| 
 | ||||
| public: | ||||
| 
 | ||||
|     // An aggregation of SliceRecord-s from all the print objects for each
 | ||||
|     // occupied layer. Slice record levels dont have to match exactly.
 | ||||
|     // They are unified if the level difference is within +/- SCALED_EPSILON
 | ||||
|     struct PrintLayer { | ||||
|         coord_t level; | ||||
| 
 | ||||
|         // The collection of slice records for the current level.
 | ||||
|         std::vector<std::reference_wrapper<const SliceRecord>> slices; | ||||
| 
 | ||||
|         explicit PrintLayer(coord_t lvl) : level(lvl) {} | ||||
| 
 | ||||
|         // for being sorted in their container (see m_printer_input)
 | ||||
|         bool operator<(const PrintLayer& other) const { | ||||
|             return level < other.level; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     SLAPrint(): m_stepmask(slapsCount, true) {} | ||||
| 
 | ||||
|     virtual ~SLAPrint() override { this->clear(); } | ||||
|  | @ -360,6 +377,10 @@ public: | |||
| 
 | ||||
|     std::string validate() const override; | ||||
| 
 | ||||
|     // The aggregated and leveled print records from various objects.
 | ||||
|     // TODO: use this structure for the preview in the future.
 | ||||
|     const std::vector<PrintLayer>& print_layers() const { return m_printer_input; } | ||||
| 
 | ||||
| private: | ||||
|     using SLAPrinter = FilePrinter<FilePrinterFormat::SLA_PNGZIP>; | ||||
|     using SLAPrinterPtr = std::unique_ptr<SLAPrinter>; | ||||
|  | @ -377,29 +398,8 @@ private: | |||
|     PrintObjects                    m_objects; | ||||
|     std::vector<bool>               m_stepmask; | ||||
| 
 | ||||
|     // Definition of the print input map. It consists of the slices indexed
 | ||||
|     // with scaled (clipper) Z coordinates. Also contains the instance
 | ||||
|     // transformations in scaled and filtered version. This is enough for the
 | ||||
|     // rasterizer to be able to draw every layer in the right position
 | ||||
|     using Layer = ExPolygons; | ||||
|     using LayerCopies = std::vector<SLAPrintObject::Instance>; | ||||
|     struct LayerRef { | ||||
|         std::reference_wrapper<const Layer> lref; | ||||
|         std::reference_wrapper<const LayerCopies> copies; | ||||
|         LayerRef(const Layer& lyr, const LayerCopies& cp) : | ||||
|             lref(std::cref(lyr)), copies(std::cref(cp)) {} | ||||
|     }; | ||||
| 
 | ||||
|     // One level may contain multiple slices from multiple objects and their
 | ||||
|     // supports
 | ||||
|     struct LayerRefs { | ||||
|         coord_t level; | ||||
|         std::vector<LayerRef> refs; | ||||
|         bool operator<(const LayerRefs& other) const { return level < other.level; } | ||||
|         explicit LayerRefs(coord_t lvl) : level(lvl) {} | ||||
|     }; | ||||
| 
 | ||||
|     std::vector<LayerRefs>                  m_printer_input; | ||||
|     // Ready-made data for rasterization.
 | ||||
|     std::vector<PrintLayer>                 m_printer_input; | ||||
| 
 | ||||
|     // The printer itself
 | ||||
|     SLAPrinterPtr                           m_printer; | ||||
|  |  | |||
|  | @ -5021,8 +5021,8 @@ void GLCanvas3D::_render_sla_slices() const | |||
|             SliceRecord slice_high = obj->closest_slice_to_print_level(key_high, coord_t(SCALED_EPSILON)); | ||||
|      | ||||
|             if (! slice_low.is_valid()) { | ||||
|                 const ExPolygons& obj_bottom = obj->get_slices_from_record(slice_low, soModel); | ||||
|                 const ExPolygons& sup_bottom = obj->get_slices_from_record(slice_low, soSupport); | ||||
|                 const ExPolygons& obj_bottom = slice_low.get_slice(soModel); | ||||
|                 const ExPolygons& sup_bottom = slice_low.get_slice(soSupport); | ||||
|                 // calculate model bottom cap
 | ||||
|                 if (bottom_obj_triangles.empty() && !obj_bottom.empty()) | ||||
|                     bottom_obj_triangles = triangulate_expolygons_3d(obj_bottom, clip_min_z, true); | ||||
|  | @ -5032,8 +5032,8 @@ void GLCanvas3D::_render_sla_slices() const | |||
|             } | ||||
| 
 | ||||
|             if (! slice_high.is_valid()) { | ||||
|                 const ExPolygons& obj_top = obj->get_slices_from_record(slice_high, soModel); | ||||
|                 const ExPolygons& sup_top = obj->get_slices_from_record(slice_high, soSupport); | ||||
|                 const ExPolygons& obj_top = slice_high.get_slice(soModel); | ||||
|                 const ExPolygons& sup_top = slice_high.get_slice(soSupport); | ||||
|                 // calculate model top cap
 | ||||
|                 if (top_obj_triangles.empty() && !obj_top.empty()) | ||||
|                     top_obj_triangles = triangulate_expolygons_3d(obj_top, clip_max_z, false); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 tamasmeszaros
						tamasmeszaros