From 72d1faa03ea545ba19fb09049e75c067e72737c2 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 24 May 2021 16:55:34 +0200 Subject: [PATCH] WIP PrintRegion refactoring: Squashed some bugs. --- src/libslic3r/Layer.hpp | 1 + src/libslic3r/Print.hpp | 8 ++--- src/libslic3r/PrintApply.cpp | 50 ++++++++++++++++------------ src/libslic3r/PrintObjectSlice.cpp | 14 ++++++-- src/libslic3r/TriangleMeshSlicer.cpp | 5 +-- src/libslic3r/TriangleMeshSlicer.hpp | 6 ++-- 6 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 14f34dbc6..a7c0e0d7b 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -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() {} diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 1cc87d9d9..ac5d2e5a9 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -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 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; diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index e5218ba3a..bc1741fa0 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -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(std::move(config), hash)); + all_regions.emplace_back(std::make_unique(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 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(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)) diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 1b54cfb77..e9c30c08e 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -162,12 +162,12 @@ static std::vector slice_volumes_inner( slicing_ranges.reserve(layer_ranges.size()); MeshSlicingParamsEx params_base; - params_base.closing_radius = scaled(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(print_config.resolution.value); + params_base.resolution = print_config.resolution.value; - const auto extra_offset = print_object_config.xy_size_compensation > 0 ? scaled(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([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 &pr : m_shared_regions->all_regions) + layer->m_regions.emplace_back(new LayerRegion(layer, pr.get())); + } + std::vector slice_zs = zs_from_layers(m_layers); Transform3d trafo = this->trafo(); trafo.pretranslate(Vec3d(- unscale(m_center_offset.x()), - unscale(m_center_offset.y()), 0)); diff --git a/src/libslic3r/TriangleMeshSlicer.cpp b/src/libslic3r/TriangleMeshSlicer.cpp index dac931724..f62585812 100644 --- a/src/libslic3r/TriangleMeshSlicer.cpp +++ b/src/libslic3r/TriangleMeshSlicer.cpp @@ -1169,6 +1169,7 @@ std::vector slice_mesh_ex( tbb::blocked_range(0, layers_p.size()), [&layers_p, ¶ms, &layers, throw_on_cancel] (const tbb::blocked_range& range) { + auto resolution = scaled(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 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"; diff --git a/src/libslic3r/TriangleMeshSlicer.hpp b/src/libslic3r/TriangleMeshSlicer.hpp index 4b8740d48..f6ac698cc 100644 --- a/src/libslic3r/TriangleMeshSlicer.hpp +++ b/src/libslic3r/TriangleMeshSlicer.hpp @@ -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 }; };