diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index ffffd9d319..07031d7e46 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2308,7 +2308,8 @@ void GCode::process_layer_single_object( ExtrusionEntitiesPtr temp_fill_extrusions; if (const Layer *layer = layer_to_print.object_layer; layer) - for (const LayerSlice &lslice : layer->lslices_ex) { + for (size_t idx : layer->lslice_indices_sorted_by_print_order) { + const LayerSlice &lslice = layer->lslices_ex[idx]; auto extrude_infill_range = [&]( const LayerRegion &layerm, const ExtrusionEntityCollection &fills, LayerExtrusionRanges::const_iterator it_fill_ranges_begin, LayerExtrusionRanges::const_iterator it_fill_ranges_end, bool ironing) { diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 9b0004e989..378352be7d 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -38,32 +38,37 @@ LayerRegion* Layer::add_region(const PrintRegion *print_region) // merge all regions' slices to get islands void Layer::make_slices() { - ExPolygons slices; - if (m_regions.size() == 1) { - // optimization: if we only have one region, take its slices - slices = to_expolygons(m_regions.front()->slices().surfaces); - } else { - Polygons slices_p; - for (LayerRegion *layerm : m_regions) - polygons_append(slices_p, to_polygons(layerm->slices().surfaces)); - slices = union_safety_offset_ex(slices_p); + { + ExPolygons slices; + if (m_regions.size() == 1) { + // optimization: if we only have one region, take its slices + slices = to_expolygons(m_regions.front()->slices().surfaces); + } else { + Polygons slices_p; + for (LayerRegion *layerm : m_regions) + polygons_append(slices_p, to_polygons(layerm->slices().surfaces)); + slices = union_safety_offset_ex(slices_p); + } + // lslices are sorted by topological order from outside to inside from the clipper union used above + this->lslices = slices; } - - this->lslices.clear(); - this->lslices.reserve(slices.size()); - + + // 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(slices.size()); - for (const ExPolygon &ex : slices) + 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->lslices.emplace_back(std::move(slices[i])); + for (size_t i : order) { + this->lslice_indices_sorted_by_print_order.emplace_back(i); + } } // used by Layer::build_up_down_graph() diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index cfeace67be..11193828cc 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -336,6 +336,7 @@ public: // These lslices are also used to detect overhangs and overlaps between successive layers, therefore it is important // that the 1st lslice is not compensated by the Elephant foot compensation algorithm. ExPolygons lslices; + std::vector lslice_indices_sorted_by_print_order; LayerSlices lslices_ex; size_t region_count() const { return m_regions.size(); } diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 81e21f305d..0d950b93ed 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -799,7 +799,7 @@ void PrintObject::slice_volumes() layer->m_regions[region_id]->trim_surfaces(trimming); } } - // Merge all regions' slices to get islands, chain them by a shortest path. + // Merge all regions' slices to get islands sorted topologically, chain them by a shortest path in separate index list layer->make_slices(); } }); diff --git a/src/libslic3r/SupportSpotsGenerator.cpp b/src/libslic3r/SupportSpotsGenerator.cpp index 9bf9dbdef2..47e7228d4d 100644 --- a/src/libslic3r/SupportSpotsGenerator.cpp +++ b/src/libslic3r/SupportSpotsGenerator.cpp @@ -1175,13 +1175,6 @@ void raise_alerts_for_issues(const SupportPoints PartialObjects &partial_objects, std::function alert_fn) { - for (const SupportPoint &sp : support_points) { - if (sp.cause == SupportPointCause::SeparationFromBed) { - alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed); - break; - } - } - std::reverse(partial_objects.begin(), partial_objects.end()); std::sort(partial_objects.begin(), partial_objects.end(), [](const PartialObject &left, const PartialObject &right) { return left.volume > right.volume; }); @@ -1231,21 +1224,29 @@ void raise_alerts_for_issues(const SupportPoints } } - if (ext_supp_points.size() > 5) { - alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion); - } - for (const SupportPoint &sp : support_points) { - if (sp.cause == SupportPointCause::LongBridge) { - alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge); - break; + if (sp.cause == SupportPointCause::SeparationFromBed) { + alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::SeparationFromBed); + return; } } for (const SupportPoint &sp : support_points) { if (sp.cause == SupportPointCause::WeakObjectPart) { alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::WeakObjectPart); - break; + return; + } + } + + if (ext_supp_points.size() > 5) { + alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::FloatingExtrusion); + return; + } + + for (const SupportPoint &sp : support_points) { + if (sp.cause == SupportPointCause::LongBridge) { + alert_fn(PrintStateBase::WarningLevel::NON_CRITICAL, SupportPointCause::LongBridge); + return; } } }