From 2d4e3ef4feda8ae076e2abe58a9bd48f74336e01 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Fri, 17 Feb 2023 14:02:52 +0100 Subject: [PATCH] Fixed inconsistency between 1st layer islands and ordering vector leading to crashes. Fixes SPE-1495 --- src/libslic3r/Layer.cpp | 17 +---------------- src/libslic3r/Layer.hpp | 5 +++-- src/libslic3r/PrintObjectSlice.cpp | 22 +++++++++++++++++++--- src/libslic3r/ShortestPath.cpp | 9 +++++++++ src/libslic3r/ShortestPath.hpp | 4 ++++ 5 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index d60e077af..6655b6764 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -53,22 +53,7 @@ void Layer::make_slices() this->lslices = slices; } - // prepare lslices ordered by print order - this->lslice_indices_sorted_by_print_order.clear(); - this->lslice_indices_sorted_by_print_order.reserve(lslices.size()); - // prepare ordering points - Points ordering_points; - ordering_points.reserve( this->lslices.size()); - for (const ExPolygon &ex : this->lslices) - ordering_points.push_back(ex.contour.first_point()); - - // sort slices - std::vector order = chain_points(ordering_points); - - // populate slices vector - for (size_t i : order) { - this->lslice_indices_sorted_by_print_order.emplace_back(i); - } + this->lslice_indices_sorted_by_print_order = chain_expolygons(this->lslices); } // used by Layer::build_up_down_graph() diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index 11193828c..e9c8ecbac 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -318,7 +318,7 @@ public: Layer *upper_layer; Layer *lower_layer; - bool slicing_errors; +// bool slicing_errors; coordf_t slice_z; // Z used for slicing in unscaled coordinates coordf_t print_z; // Z used for printing in unscaled coordinates coordf_t height; // layer height in unscaled coordinates @@ -387,7 +387,8 @@ protected: friend std::string fix_slicing_errors(LayerPtrs&, const std::function&); Layer(size_t id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) : - upper_layer(nullptr), lower_layer(nullptr), slicing_errors(false), + upper_layer(nullptr), lower_layer(nullptr), + //slicing_errors(false), slice_z(slice_z), print_z(print_z), height(height), m_id(id), m_object(object) {} virtual ~Layer(); diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 9dd74bfd7..4cc5adff0 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -1,9 +1,10 @@ +#include "ClipperUtils.hpp" #include "ElephantFootCompensation.hpp" #include "I18N.hpp" #include "Layer.hpp" #include "MultiMaterialSegmentation.hpp" #include "Print.hpp" -#include "ClipperUtils.hpp" +#include "ShortestPath.hpp" #include @@ -398,6 +399,10 @@ static std::vector> slices_to_regions( return slices_by_region; } +// Layer::slicing_errors is no more set since 1.41.1 or possibly earlier, thus this code +// was not really functional for a long day and nobody missed it. +// Could we reuse this fixing code one day? +/* std::string fix_slicing_errors(LayerPtrs &layers, const std::function &throw_if_canceled) { // Collect layers with slicing errors. @@ -480,6 +485,7 @@ std::string fix_slicing_errors(LayerPtrs &layers, const std::function &t "The model has overlapping or self-intersecting facets. I tried to repair it, " "however you might want to check the results or repair the input file and retry.\n"; } +*/ // Called by make_perimeters() // 1) Decides Z positions of the layers, @@ -502,12 +508,18 @@ void PrintObject::slice() m_layers = new_layers(this, generate_object_layers(m_slicing_params, layer_height_profile)); this->slice_volumes(); m_print->throw_if_canceled(); +#if 0 + // Layer::slicing_errors is no more set since 1.41.1 or possibly earlier, thus this code + // was not really functional for a long day and nobody missed it. + // Could we reuse this fixing code one day? + // Fix the model. //FIXME is this the right place to do? It is done repeateadly at the UI and now here at the backend. std::string warning = fix_slicing_errors(m_layers, [this](){ m_print->throw_if_canceled(); }); m_print->throw_if_canceled(); if (! warning.empty()) BOOST_LOG_TRIVIAL(info) << warning; +#endif // Update bounding boxes, back up raw slices of complex models. tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), @@ -799,8 +811,12 @@ void PrintObject::slice_volumes() if (elephant_foot_compensation_scaled > 0.f && ! m_layers.empty()) { // The Elephant foot has been compensated, therefore the 1st layer's lslices are shrank with the Elephant foot compensation value. // Store the uncompensated value there. - assert(m_layers.front()->id() == 0); - m_layers.front()->lslices = std::move(lslices_1st_layer); + //FIXME is this operation needed? MMU painting and brim now have to do work arounds to work with compensated layer, not with the uncompensated layer. + // There may be subtle issues removing this block such as support raft sticking too well with the first object layer. + Layer &layer = *m_layers.front(); + assert(layer.id() == 0); + layer.lslices = std::move(lslices_1st_layer); + layer.lslice_indices_sorted_by_print_order = chain_expolygons(layer.lslices); } } diff --git a/src/libslic3r/ShortestPath.cpp b/src/libslic3r/ShortestPath.cpp index 72bfe1f30..da1a44ec7 100644 --- a/src/libslic3r/ShortestPath.cpp +++ b/src/libslic3r/ShortestPath.cpp @@ -1076,6 +1076,15 @@ std::vector chain_points(const Points &points, Point *start_near) return out; } +std::vector chain_expolygons(const ExPolygons &expolygons, Point *start_near) +{ + Points ordering_points; + ordering_points.reserve(expolygons.size()); + for (const ExPolygon &ex : expolygons) + ordering_points.push_back(ex.contour.first_point()); + return chain_points(ordering_points); +} + #ifndef NDEBUG // #define DEBUG_SVG_OUTPUT #endif /* NDEBUG */ diff --git a/src/libslic3r/ShortestPath.hpp b/src/libslic3r/ShortestPath.hpp index 14912ee85..c84349217 100644 --- a/src/libslic3r/ShortestPath.hpp +++ b/src/libslic3r/ShortestPath.hpp @@ -12,7 +12,11 @@ namespace ClipperLib { class PolyNode; } namespace Slic3r { +class ExPolygon; +using ExPolygons = std::vector; + std::vector chain_points(const Points &points, Point *start_near = nullptr); +std::vector chain_expolygons(const ExPolygons &expolygons, Point *start_near = nullptr); std::vector> chain_extrusion_entities(std::vector &entities, const Point *start_near = nullptr); void reorder_extrusion_entities(std::vector &entities, const std::vector> &chain);