diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 8881cf0cd..ae1ea0453 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -334,41 +334,6 @@ sub travel_to { return $gcode; } -sub needs_retraction { - my ($self, $travel, $role) = @_; - - if ($travel->length < scale $self->config->get_at('retract_before_travel', $self->writer->extruder->id)) { - # skip retraction if the move is shorter than the configured threshold - return 0; - } - - if (defined $role && $role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->as_support_layer->support_islands->contains_polyline($travel)) { - # skip retraction if this is a travel move inside a support material island - return 0; - } - - if ($self->config->only_retract_when_crossing_perimeters && $self->has_layer) { - if ($self->config->fill_density > 0 - && $self->layer->any_internal_region_slice_contains_polyline($travel)) { - # skip retraction if travel is contained in an internal slice *and* - # internal infill is enabled (so that stringing is entirely not visible) - return 0; - } elsif ($self->layer->any_bottom_region_slice_contains_polyline($travel) - && defined $self->layer->upper_layer - && $self->layer->upper_layer->slices->contains_polyline($travel) - && ($self->config->bottom_solid_layers >= 2 || $self->config->fill_density > 0)) { - # skip retraction if travel is contained in an *infilled* bottom slice - # but only if it's also covered by an *infilled* upper layer's slice - # so that it's not visible from above (a bottom surface might not have an - # upper slice in case of a thin membrane) - return 0; - } - } - - # retract if only_retract_when_crossing_perimeters is disabled or doesn't apply - return 1; -} - sub set_extruder { my ($self, $extruder_id) = @_; diff --git a/xs/src/libslic3r/GCode.cpp b/xs/src/libslic3r/GCode.cpp index 9acfe47d3..d7b2fcbfd 100644 --- a/xs/src/libslic3r/GCode.cpp +++ b/xs/src/libslic3r/GCode.cpp @@ -1,4 +1,5 @@ #include "GCode.hpp" +#include "ExtrusionEntity.hpp" namespace Slic3r { @@ -213,6 +214,44 @@ GCode::preamble() return gcode; } +bool +GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) +{ + if (travel.length() < scale_(this->config.retract_before_travel.get_at(this->writer.extruder()->id))) { + // skip retraction if the move is shorter than the configured threshold + return false; + } + + if (role == erSupportMaterial) { + SupportLayer* support_layer = dynamic_cast(this->layer); + if (support_layer->support_islands.contains(travel)) { + // skip retraction if this is a travel move inside a support material island + return false; + } + } + + if (this->config.only_retract_when_crossing_perimeters && this->layer != NULL) { + if (this->config.fill_density.value > 0 + && this->layer->any_internal_region_slice_contains(travel)) { + /* skip retraction if travel is contained in an internal slice *and* + internal infill is enabled (so that stringing is entirely not visible) */ + return false; + } else if (this->layer->any_bottom_region_slice_contains(travel) + && this->layer->upper_layer != NULL + && this->layer->upper_layer->slices.contains(travel) + && (this->config.bottom_solid_layers.value >= 2 || this->config.fill_density.value > 0)) { + /* skip retraction if travel is contained in an *infilled* bottom slice + but only if it's also covered by an *infilled* upper layer's slice + so that it's not visible from above (a bottom surface might not have an + upper slice in case of a thin membrane) */ + return false; + } + } + + // retract if only_retract_when_crossing_perimeters is disabled or doesn't apply + return true; +} + std::string GCode::retract(bool toolchange) { diff --git a/xs/src/libslic3r/GCode.hpp b/xs/src/libslic3r/GCode.hpp index 8b37386e9..2dbbebddb 100644 --- a/xs/src/libslic3r/GCode.hpp +++ b/xs/src/libslic3r/GCode.hpp @@ -87,6 +87,7 @@ class GCode { void apply_print_config(const PrintConfig &print_config); void set_origin(const Pointf &pointf); std::string preamble(); + bool needs_retraction(const Polyline &travel, ExtrusionRole role); std::string retract(bool toolchange = false); std::string unretract(); Pointf point_to_gcode(const Point &point); diff --git a/xs/xsp/GCode.xsp b/xs/xsp/GCode.xsp index 41bdbc042..fdfc3d894 100644 --- a/xs/xsp/GCode.xsp +++ b/xs/xsp/GCode.xsp @@ -152,6 +152,8 @@ void set_origin(Pointf* pointf) %code{% THIS->set_origin(*pointf); %}; std::string preamble(); + bool needs_retraction(Polyline* travel, ExtrusionRole role) + %code{% RETVAL = THIS->needs_retraction(*travel, role); %}; std::string retract(bool toolchange = false); std::string unretract(); Clone point_to_gcode(Point* point)