From 74e01b5759a3afd9314ef0b7ba8090e834aebf11 Mon Sep 17 00:00:00 2001 From: supermerill Date: Tue, 4 Jan 2022 22:54:36 +0100 Subject: [PATCH] Don't consider top surface as safe for 'only_retract_when_crossing_perimeters' supermerill/SuperSlicer#2128 --- src/libslic3r/GCode.cpp | 13 ++++++++++--- src/libslic3r/GCode.hpp | 7 +++++-- src/libslic3r/SurfaceCollection.hpp | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 527034f39..d30716ad3 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -4432,13 +4432,20 @@ bool GCode::can_cross_perimeter(const Polyline& travel, bool offset) //if (inside) { //contained inside at least one bb //construct m_layer_slices_offseted if needed - if (m_layer_slices_offseted.layer != m_layer && offset) { + if (m_layer_slices_offseted.layer != m_layer) { m_layer_slices_offseted.layer = m_layer; m_layer_slices_offseted.diameter = scale_t(EXTRUDER_CONFIG_WITH_DEFAULT(nozzle_diameter, 0.4)); - m_layer_slices_offseted.slices = offset_ex(m_layer->lslices, -m_layer_slices_offseted.diameter * 1.5f); + m_layer_slices_offseted.slices = m_layer->lslices; + m_layer_slices_offseted.slices_offsetted = offset_ex(m_layer->lslices, -m_layer_slices_offseted.diameter * 1.5f); + //remove top surfaces + for (const LayerRegion* reg : m_layer->regions()) { + m_layer_slices_offseted.slices_offsetted = diff_ex(m_layer_slices_offseted.slices_offsetted, to_expolygons(reg->fill_surfaces.filter_by_type_flag(SurfaceType::stPosTop))); + m_layer_slices_offseted.slices = diff_ex(m_layer_slices_offseted.slices, to_expolygons(reg->fill_surfaces.filter_by_type_flag(SurfaceType::stPosTop))); + } + } // test if a expoly contains the entire travel - for (const ExPolygon &poly : offset ? m_layer_slices_offseted.slices : m_layer->lslices) + for (const ExPolygon &poly : offset ? m_layer_slices_offseted.slices_offsetted : m_layer_slices_offseted.slices) if (poly.contains(travel)) { return false; } diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index bfa644595..0aa3414c8 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -367,8 +367,11 @@ private: // For crossing perimeter retraction detection (contain the layer & nozzle widdth used to construct it) // !!!! not thread-safe !!!! if threaded per layer, please store it in the thread. struct SliceOffsetted { - ExPolygons slices; const Layer* layer; coord_t diameter; - } m_layer_slices_offseted{ {},nullptr, 0}; + ExPolygons slices; + ExPolygons slices_offsetted; + const Layer* layer; + coord_t diameter; + } m_layer_slices_offseted{ {},{},nullptr, 0}; double m_volumetric_speed; // Support for the extrusion role markers. Which marker is active? ExtrusionRole m_last_extrusion_role; diff --git a/src/libslic3r/SurfaceCollection.hpp b/src/libslic3r/SurfaceCollection.hpp index 12677be72..b9e1747f7 100644 --- a/src/libslic3r/SurfaceCollection.hpp +++ b/src/libslic3r/SurfaceCollection.hpp @@ -19,7 +19,9 @@ public: operator ExPolygons() const; void simplify(double tolerance); void group(std::vector *retval); + // get all surfaces that have this exact SurfaceType SurfacesConstPtr filter_by_type(const SurfaceType type) const; + // get all surfaces that have this SurfaceType flag in their SurfaceType SurfacesConstPtr filter_by_type_flag(const SurfaceType allowed, const SurfaceType not_allowed = stNone) const; SurfacesConstPtr filter_by_types(const SurfaceType *types, int ntypes) const; void keep_type(const SurfaceType type);