diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index c8b72a8ad..0f322ca15 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -344,8 +344,7 @@ sub travel_to { if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id) || ($self->config->only_retract_when_crossing_perimeters && $self->config->fill_density > 0 - && $self->layer->slices->contains_line($travel) - && (!$self->layer->has_upper_layer || $self->layer->upper_layer->slices->contains_line($travel))) + && $self->layer->any_internal_region_slice_contains_line($travel)) || (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands->contains_line($travel)) ) { # Just perform a straight travel move without any retraction. @@ -608,8 +607,7 @@ sub _plan { # if the path is not contained in a single island we need to retract $gcode .= $gcodegen->retract if !$gcodegen->config->only_retract_when_crossing_perimeters - || !$gcodegen->layer->slices->contains_polyline($travel) - || ($gcodegen->layer->has_upper_layer && !$gcodegen->layer->upper_layer->slices->contains_polyline($travel)); + || !$gcodegen->layer->any_internal_region_slice_contains_polyline($travel); # append the actual path and return # use G1 because we rely on paths being straight (G0 may make round paths) diff --git a/xs/src/libslic3r/Layer.cpp b/xs/src/libslic3r/Layer.cpp index 17747d06d..26e9ab7f8 100644 --- a/xs/src/libslic3r/Layer.cpp +++ b/xs/src/libslic3r/Layer.cpp @@ -120,6 +120,18 @@ Layer::make_slices() } } +template <class T> +bool +Layer::any_internal_region_slice_contains(const T &item) const +{ + FOREACH_LAYERREGION(this, layerm) { + if ((*layerm)->slices.any_internal_contains(item)) return true; + } + return false; +} +template bool Layer::any_internal_region_slice_contains<Line>(const Line &item) const; +template bool Layer::any_internal_region_slice_contains<Polyline>(const Polyline &item) const; + #ifdef SLIC3RXS REGISTER_CLASS(Layer, "Layer"); diff --git a/xs/src/libslic3r/Layer.hpp b/xs/src/libslic3r/Layer.hpp index cd0250089..ff8cca1d9 100644 --- a/xs/src/libslic3r/Layer.hpp +++ b/xs/src/libslic3r/Layer.hpp @@ -90,6 +90,7 @@ class Layer { LayerRegion* add_region(PrintRegion* print_region); void make_slices(); + template <class T> bool any_internal_region_slice_contains(const T &item) const; protected: int _id; // sequential number of layer, 0-based diff --git a/xs/src/libslic3r/Surface.cpp b/xs/src/libslic3r/Surface.cpp index 3ea6429af..e4625f799 100644 --- a/xs/src/libslic3r/Surface.cpp +++ b/xs/src/libslic3r/Surface.cpp @@ -26,6 +26,15 @@ Surface::is_external() const || this->surface_type == stBottomBridge; } +bool +Surface::is_internal() const +{ + return this->surface_type == stInternal + || this->surface_type == stInternalBridge + || this->surface_type == stInternalSolid + || this->surface_type == stInternalVoid; +} + bool Surface::is_bottom() const { diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp index c98567cf0..28a90799a 100644 --- a/xs/src/libslic3r/Surface.hpp +++ b/xs/src/libslic3r/Surface.hpp @@ -24,6 +24,7 @@ class Surface double area() const; bool is_solid() const; bool is_external() const; + bool is_internal() const; bool is_bottom() const; bool is_bridge() const; diff --git a/xs/src/libslic3r/SurfaceCollection.cpp b/xs/src/libslic3r/SurfaceCollection.cpp index 1590e7a21..027138818 100644 --- a/xs/src/libslic3r/SurfaceCollection.cpp +++ b/xs/src/libslic3r/SurfaceCollection.cpp @@ -68,6 +68,18 @@ SurfaceCollection::group(std::vector<SurfacesPtr> *retval) } } +template <class T> +bool +SurfaceCollection::any_internal_contains(const T &item) const +{ + for (Surfaces::const_iterator surface = this->surfaces.begin(); surface != this->surfaces.end(); ++surface) { + if (surface->is_internal() && surface->expolygon.contains(item)) return true; + } + return false; +} +template bool SurfaceCollection::any_internal_contains<Line>(const Line &item) const; +template bool SurfaceCollection::any_internal_contains<Polyline>(const Polyline &item) const; + #ifdef SLIC3RXS REGISTER_CLASS(SurfaceCollection, "Surface::Collection"); #endif diff --git a/xs/src/libslic3r/SurfaceCollection.hpp b/xs/src/libslic3r/SurfaceCollection.hpp index fe3fae8c6..494bb1a21 100644 --- a/xs/src/libslic3r/SurfaceCollection.hpp +++ b/xs/src/libslic3r/SurfaceCollection.hpp @@ -15,6 +15,7 @@ class SurfaceCollection operator ExPolygons() const; void simplify(double tolerance); void group(std::vector<SurfacesPtr> *retval); + template <class T> bool any_internal_contains(const T &item) const; }; } diff --git a/xs/xsp/Layer.xsp b/xs/xsp/Layer.xsp index e0f7e8a17..a84d4464f 100644 --- a/xs/xsp/Layer.xsp +++ b/xs/xsp/Layer.xsp @@ -69,6 +69,10 @@ %code%{ RETVAL = (int)(intptr_t)THIS; %}; void make_slices(); + bool any_internal_region_slice_contains_line(Line* line) + %code%{ RETVAL = THIS->any_internal_region_slice_contains(*line); %}; + bool any_internal_region_slice_contains_polyline(Polyline* polyline) + %code%{ RETVAL = THIS->any_internal_region_slice_contains(*polyline); %}; }; %name{Slic3r::Layer::Support} class SupportLayer { @@ -114,4 +118,9 @@ Ref<ExPolygonCollection> slices() %code%{ RETVAL = &THIS->slices; %}; + + bool any_internal_region_slice_contains_line(Line* line) + %code%{ RETVAL = THIS->any_internal_region_slice_contains(*line); %}; + bool any_internal_region_slice_contains_polyline(Polyline* polyline) + %code%{ RETVAL = THIS->any_internal_region_slice_contains(*polyline); %}; };