mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	WIP PrintRegion refactoring: Squashed some bugs.
This commit is contained in:
		
							parent
							
								
									c8bdc62af4
								
							
						
					
					
						commit
						72d1faa03e
					
				
					 6 changed files with 50 additions and 34 deletions
				
			
		|  | @ -87,6 +87,7 @@ public: | |||
| 
 | ||||
| protected: | ||||
|     friend class Layer; | ||||
|     friend class PrintObject; | ||||
| 
 | ||||
|     LayerRegion(Layer *layer, const PrintRegion *region) : m_layer(layer), m_region(region) {} | ||||
|     ~LayerRegion() {} | ||||
|  |  | |||
|  | @ -63,9 +63,9 @@ class PrintRegion | |||
| public: | ||||
|     PrintRegion() = default; | ||||
|     PrintRegion(const PrintRegionConfig &config); | ||||
|     PrintRegion(const PrintRegionConfig &config, const size_t config_hash) : m_config(config), m_config_hash(config_hash) {} | ||||
|     PrintRegion(const PrintRegionConfig &config, const size_t config_hash, int print_object_region_id = -1) : m_config(config), m_config_hash(config_hash), m_print_object_region_id(print_object_region_id) {} | ||||
|     PrintRegion(PrintRegionConfig &&config); | ||||
|     PrintRegion(PrintRegionConfig &&config, const size_t config_hash) : m_config(std::move(config)), m_config_hash(config_hash) {} | ||||
|     PrintRegion(PrintRegionConfig &&config, const size_t config_hash, int print_object_region_id = -1) : m_config(std::move(config)), m_config_hash(config_hash), m_print_object_region_id(print_object_region_id) {} | ||||
|     ~PrintRegion() = default; | ||||
| 
 | ||||
| // Methods NOT modifying the PrintRegion's state:
 | ||||
|  | @ -209,7 +209,7 @@ public: | |||
|         std::vector<PaintedRegion>  painted_regions; | ||||
| 
 | ||||
|         bool has_volume(const ObjectID id) const { | ||||
|             auto it = lower_bound_by_predicate(this->volumes.begin(), this->volumes.end(), [id](const VolumeExtents& v) { return v.volume_id == id; }); | ||||
|             auto it = lower_bound_by_predicate(this->volumes.begin(), this->volumes.end(), [id](const VolumeExtents &l) { return l.volume_id < id; }); | ||||
|             return it != this->volumes.end() && it->volume_id == id; | ||||
|         } | ||||
|     }; | ||||
|  | @ -380,7 +380,7 @@ private: | |||
| 
 | ||||
|     // Object split into layer ranges and regions with their associated configurations.
 | ||||
|     // Shared among PrintObjects created for the same ModelObject.
 | ||||
|     PrintObjectRegions                     *m_shared_regions; | ||||
|     PrintObjectRegions                     *m_shared_regions { nullptr }; | ||||
| 
 | ||||
|     SlicingParameters                       m_slicing_params; | ||||
|     LayerPtrs                               m_layers; | ||||
|  |  | |||
|  | @ -474,7 +474,7 @@ static inline bool trafos_differ_in_rotation_and_mirroring_by_z_only(const Trans | |||
|         return false; | ||||
|     // Verify whether the vectors x, y are still perpendicular.
 | ||||
|     double   d   = x.dot(y); | ||||
|     return std::abs(d) > EPSILON; | ||||
|     return std::abs(d * d) < EPSILON * lx2 * ly2; | ||||
| } | ||||
| 
 | ||||
| static BoundingBoxf3 transformed_its_bbox2d(const indexed_triangle_set &its, const Matrix3f &m, float offset) | ||||
|  | @ -778,7 +778,7 @@ static PrintObjectRegions* generate_print_object_regions( | |||
|         // Verify that the old ranges match the new ranges.
 | ||||
|         assert(model_layer_ranges.size() == layer_ranges_regions.size()); | ||||
|         for (const auto &range : model_layer_ranges) { | ||||
|             const PrintObjectRegions::LayerRangeRegions &r = layer_ranges_regions[&range - &*(model_layer_ranges.end())]; | ||||
|             const PrintObjectRegions::LayerRangeRegions &r = layer_ranges_regions[&range - &*model_layer_ranges.begin()]; | ||||
|             assert(range.layer_height_range == r.layer_height_range); | ||||
|             assert(range.config == r.config); | ||||
|             assert(r.volume_regions.empty()); | ||||
|  | @ -799,10 +799,10 @@ static PrintObjectRegions* generate_print_object_regions( | |||
|         size_t hash = config.hash(); | ||||
|         auto it = Slic3r::lower_bound_by_predicate(region_set.begin(), region_set.end(), [&config, hash](const PrintRegion* l) { | ||||
|             return l->config_hash() < hash || (l->config_hash() == hash && l->config() < config); }); | ||||
|         if ((*it)->config_hash() == hash && (*it)->config() == config) | ||||
|         if (it != region_set.end() && (*it)->config_hash() == hash && (*it)->config() == config) | ||||
|             return *it; | ||||
|         // Insert into a sorted array, it has O(n) complexity, but the calling algorithm has an O(n^2*log(n)) complexity anyways.
 | ||||
|         all_regions.emplace_back(std::make_unique<PrintRegion>(std::move(config), hash)); | ||||
|         all_regions.emplace_back(std::make_unique<PrintRegion>(std::move(config), hash, int(all_regions.size()))); | ||||
|         PrintRegion *region = all_regions.back().get(); | ||||
|         region_set.emplace(it, region); | ||||
|         return region; | ||||
|  | @ -1060,21 +1060,24 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ | |||
|                 model_object_status.print_object_regions->clear(); | ||||
|             // Copy content of the ModelObject including its ID, do not change the parent.
 | ||||
|             model_object.assign_copy(model_object_new); | ||||
|         } else if (supports_differ || model_custom_supports_data_changed(model_object, model_object_new)) { | ||||
|             // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list.
 | ||||
|             if (supports_differ) { | ||||
|                 this->call_cancel_callback(); | ||||
|                 update_apply_status(false); | ||||
|         } else {  | ||||
|             model_object_status.print_object_regions_status = ModelObjectStatus::PrintObjectRegionsStatus::Valid; | ||||
|             if (supports_differ || model_custom_supports_data_changed(model_object, model_object_new)) { | ||||
|                 // First stop background processing before shuffling or deleting the ModelVolumes in the ModelObject's list.
 | ||||
|                 if (supports_differ) { | ||||
|                     this->call_cancel_callback(); | ||||
|                     update_apply_status(false); | ||||
|                 } | ||||
|                 // Invalidate just the supports step.
 | ||||
|                 for (const PrintObjectStatus &print_object_status : print_objects_range) | ||||
|                     update_apply_status(print_object_status.print_object->invalidate_step(posSupportMaterial)); | ||||
|                 if (supports_differ) { | ||||
|                     // Copy just the support volumes.
 | ||||
|                     model_volume_list_update_supports(model_object, model_object_new); | ||||
|                 } | ||||
|             } else if (model_custom_seam_data_changed(model_object, model_object_new)) { | ||||
|                 update_apply_status(this->invalidate_step(psGCodeExport)); | ||||
|             } | ||||
|             // Invalidate just the supports step.
 | ||||
|             for (const PrintObjectStatus &print_object_status : print_objects_range) | ||||
|                 update_apply_status(print_object_status.print_object->invalidate_step(posSupportMaterial)); | ||||
|             if (supports_differ) { | ||||
|                 // Copy just the support volumes.
 | ||||
|                 model_volume_list_update_supports(model_object, model_object_new); | ||||
|             } | ||||
|         } else if (model_custom_seam_data_changed(model_object, model_object_new)) { | ||||
|             update_apply_status(this->invalidate_step(psGCodeExport)); | ||||
|         } | ||||
|         if (! model_parts_differ && ! modifiers_differ) { | ||||
|             // Synchronize Object's config.
 | ||||
|  | @ -1213,15 +1216,18 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ | |||
|     const std::vector<unsigned int> painting_extruders; | ||||
|     for (auto it_print_object = m_objects.begin(); it_print_object != m_objects.end();) { | ||||
|         // Find the range of PrintObjects sharing the same associated ModelObject.
 | ||||
|         auto                it_print_object_end  = m_objects.begin(); | ||||
|         auto                it_print_object_end  = it_print_object; | ||||
|         PrintObject        &print_object         = *(*it_print_object); | ||||
|         const ModelObject  &model_object         = *print_object.model_object(); | ||||
|         ModelObjectStatus  &model_object_status  = const_cast<ModelObjectStatus&>(model_object_status_db.reuse(model_object)); | ||||
|         PrintObjectRegions *print_object_regions = model_object_status.print_object_regions; | ||||
|         for (++ it_print_object_end; it_print_object != m_objects.end() && (*it_print_object)->model_object() == (*it_print_object_end)->model_object(); ++ it_print_object_end) | ||||
|         for (++ it_print_object_end; it_print_object_end != m_objects.end() && (*it_print_object)->model_object() == (*it_print_object_end)->model_object(); ++ it_print_object_end) | ||||
|             assert((*it_print_object_end)->m_shared_regions == nullptr || (*it_print_object_end)->m_shared_regions == print_object_regions); | ||||
|         if (print_object_regions == nullptr) | ||||
|             print_object_regions = new PrintObjectRegions {}; | ||||
|         if (print_object_regions == nullptr) { | ||||
|             print_object_regions = new PrintObjectRegions{}; | ||||
|             model_object_status.print_object_regions = print_object_regions; | ||||
|             print_object_regions->ref_cnt_inc(); | ||||
|         } | ||||
|         if (model_object_status.print_object_regions_status == ModelObjectStatus::PrintObjectRegionsStatus::Valid) { | ||||
|             // Verify that the trafo for regions & volume bounding boxes thus for regions is still applicable.
 | ||||
|             if (print_object_regions && ! trafos_differ_in_rotation_and_mirroring_by_z_only(print_object_regions->trafo_bboxes, model_object_status.print_instances.front().trafo)) | ||||
|  |  | |||
|  | @ -162,12 +162,12 @@ static std::vector<VolumeSlices> slice_volumes_inner( | |||
|         slicing_ranges.reserve(layer_ranges.size()); | ||||
| 
 | ||||
|     MeshSlicingParamsEx params_base; | ||||
|     params_base.closing_radius = scaled<float>(print_object_config.slice_closing_radius.value); | ||||
|     params_base.closing_radius = print_object_config.slice_closing_radius.value; | ||||
|     params_base.extra_offset   = 0; | ||||
|     params_base.trafo          = object_trafo; | ||||
|     params_base.resolution     = scaled<double>(print_config.resolution.value); | ||||
|     params_base.resolution     = print_config.resolution.value; | ||||
| 
 | ||||
|     const auto extra_offset = print_object_config.xy_size_compensation > 0 ? scaled<float>(print_object_config.xy_size_compensation.value) : 0.f; | ||||
|     const auto extra_offset = std::max(0.f, float(print_object_config.xy_size_compensation.value)); | ||||
| 
 | ||||
|     for (const ModelVolume *model_volume : model_volumes) | ||||
|         if (model_volume_needs_slicing(*model_volume)) { | ||||
|  | @ -549,6 +549,14 @@ void PrintObject::slice_volumes() | |||
|     const bool   spiral_vase                = print->config().spiral_vase; | ||||
|     const auto   throw_on_cancel_callback   = std::function<void()>([print](){ print->throw_if_canceled(); }); | ||||
| 
 | ||||
|     // Clear old LayerRegions, allocate for new PrintRegions.
 | ||||
|     for (Layer* layer : m_layers) { | ||||
|         layer->m_regions.clear(); | ||||
|         layer->m_regions.reserve(m_shared_regions->all_regions.size()); | ||||
|         for (const std::unique_ptr<PrintRegion> &pr : m_shared_regions->all_regions) | ||||
|             layer->m_regions.emplace_back(new LayerRegion(layer, pr.get())); | ||||
|     } | ||||
| 
 | ||||
|     std::vector<float>                   slice_zs      = zs_from_layers(m_layers); | ||||
|     Transform3d                          trafo         = this->trafo(); | ||||
|     trafo.pretranslate(Vec3d(- unscale<float>(m_center_offset.x()), - unscale<float>(m_center_offset.y()), 0)); | ||||
|  |  | |||
|  | @ -1169,6 +1169,7 @@ std::vector<ExPolygons> slice_mesh_ex( | |||
|         tbb::blocked_range<size_t>(0, layers_p.size()), | ||||
|         [&layers_p, ¶ms, &layers, throw_on_cancel] | ||||
|         (const tbb::blocked_range<size_t>& range) { | ||||
|             auto resolution = scaled<float>(params.resolution); | ||||
|             for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) { | ||||
|                 throw_on_cancel(); | ||||
|                 ExPolygons &expolygons = layers[layer_id]; | ||||
|  | @ -1177,9 +1178,9 @@ std::vector<ExPolygons> slice_mesh_ex( | |||
|                 const auto this_mode = layer_id < params.slicing_mode_normal_below_layer ? params.mode_below : params.mode; | ||||
|                 if (this_mode == MeshSlicingParams::SlicingMode::PositiveLargestContour) | ||||
|                     keep_largest_contour_only(expolygons); | ||||
|                 if (params.resolution != 0.) | ||||
|                 if (resolution != 0.) | ||||
|                     for (ExPolygon &ex : expolygons) | ||||
|                         ex.simplify(params.resolution); | ||||
|                         ex.simplify(resolution); | ||||
|             } | ||||
|         }); | ||||
| //    BOOST_LOG_TRIVIAL(debug) << "slice_mesh make_expolygons in parallel - end";
 | ||||
|  |  | |||
|  | @ -32,11 +32,11 @@ struct MeshSlicingParams | |||
| 
 | ||||
| struct MeshSlicingParamsEx : public MeshSlicingParams | ||||
| { | ||||
|     // Morphological closing operation when creating output expolygons, scaled!
 | ||||
|     // Morphological closing operation when creating output expolygons, unscaled.
 | ||||
|     float         closing_radius { 0 }; | ||||
|     // Positive offset applied when creating output expolygons, scaled!
 | ||||
|     // Positive offset applied when creating output expolygons, unscaled.
 | ||||
|     float         extra_offset { 0 }; | ||||
|     // Resolution for contour simplification, scaled!
 | ||||
|     // Resolution for contour simplification, unscaled.
 | ||||
|     // 0 = don't simplify.
 | ||||
|     double        resolution { 0 }; | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vojtech Bubnik
						Vojtech Bubnik