diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index d59674251..90bf13edf 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -52,6 +52,7 @@ use Slic3r::GCode::ArcFitting; use Slic3r::GCode::CoolingBuffer; use Slic3r::GCode::Layer; use Slic3r::GCode::MotionPlanner; +use Slic3r::GCode::OozePrevention; use Slic3r::GCode::PlaceholderParser; use Slic3r::GCode::Reader; use Slic3r::GCode::SpiralVase; diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index f78e39b59..1d35aa06b 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -186,7 +186,7 @@ extends 'Slic3r::GCode::Base'; has 'config' => (is => 'ro', default => sub { Slic3r::Config::Full->new }); has 'placeholder_parser' => (is => 'rw', default => sub { Slic3r::GCode::PlaceholderParser->new }); -has 'standby_points' => (is => 'rw'); +has 'ooze_prevention' => (is => 'rw'); has 'enable_loop_clipping' => (is => 'rw', default => sub {1}); has 'enable_wipe' => (is => 'rw', default => sub {0}); # at least one extruder has wipe enabled has 'layer_count' => (is => 'ro'); @@ -761,36 +761,17 @@ sub set_extruder { }); } - # set the current extruder to the standby temperature - if ($self->standby_points && defined $self->_extruder) { - # move to the nearest standby point - { - my $last_pos = $self->last_pos->clone; - $last_pos->translate(scale +$self->shift_x, scale +$self->shift_y); - my $standby_point = $last_pos->nearest_point($self->standby_points); - $standby_point->translate(scale -$self->shift_x, scale -$self->shift_y); - $gcode .= $self->travel_to($standby_point); - } - - if ($self->config->standby_temperature_delta != 0) { - my $temp = defined $self->layer && $self->layer->id == 0 - ? $self->_extruder->first_layer_temperature - : $self->_extruder->temperature; - # we assume that heating is always slower than cooling, so no need to block - $gcode .= $self->set_temperature($temp + $self->config->standby_temperature_delta, 0); - } - } + # if ooze prevention is enabled, park current extruder in the nearest + # standby point and set it to the standby temperature + $gcode .= $self->ooze_prevention->pre_toolchange($self) + if $self->ooze_prevention && defined $self->_extruder; # append the toolchange command $gcode .= $self->_toolchange($extruder_id); # set the new extruder to the operating temperature - if ($self->config->ooze_prevention && $self->config->standby_temperature_delta != 0) { - my $temp = defined $self->layer && $self->layer->id == 0 - ? $self->_extruder->first_layer_temperature - : $self->_extruder->temperature; - $gcode .= $self->set_temperature($temp, 1); - } + $gcode .= $self->ooze_prevention->post_toolchange($self) + if $self->ooze_prevention; return $gcode; } diff --git a/lib/Slic3r/GCode/OozePrevention.pm b/lib/Slic3r/GCode/OozePrevention.pm new file mode 100644 index 000000000..5533d2ea0 --- /dev/null +++ b/lib/Slic3r/GCode/OozePrevention.pm @@ -0,0 +1,48 @@ +package Slic3r::GCode::OozePrevention; +use Moo; + +use Slic3r::Geometry qw(scale); + +has 'standby_points' => (is => 'rw', required => 1); + +sub pre_toolchange { + my ($self, $gcodegen) = @_; + + my $gcode = ""; + + # move to the nearest standby point + if (@{$self->standby_points}) { + my $last_pos = $gcodegen->last_pos->clone; + $last_pos->translate(scale +$gcodegen->shift_x, scale +$gcodegen->shift_y); + my $standby_point = $last_pos->nearest_point($self->standby_points); + $standby_point->translate(scale -$gcodegen->shift_x, scale -$gcodegen->shift_y); + $gcode .= $gcodegen->travel_to($standby_point); + } + + if ($gcodegen->config->standby_temperature_delta != 0) { + my $temp = defined $gcodegen->layer && $gcodegen->layer->id == 0 + ? $gcodegen->_extruder->first_layer_temperature + : $gcodegen->_extruder->temperature; + # we assume that heating is always slower than cooling, so no need to block + $gcode .= $gcodegen->set_temperature($temp + $gcodegen->config->standby_temperature_delta, 0); + } + + return $gcode; +} + +sub post_toolchange { + my ($self, $gcodegen) = @_; + + my $gcode = ""; + + if ($gcodegen->config->standby_temperature_delta != 0) { + my $temp = defined $gcodegen->layer && $gcodegen->layer->id == 0 + ? $gcodegen->_extruder->first_layer_temperature + : $gcodegen->_extruder->temperature; + $gcode .= $gcodegen->set_temperature($temp, 1); + } + + return $gcode; +} + +1; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 110d19878..4234f57df 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -842,7 +842,11 @@ sub write_gcode { $s->translate(map scale($_), @{$self->config->get_at('extruder_offset', $extruder_id)}); } my $convex_hull = convex_hull([ map @$_, @skirts ]); - $gcodegen->standby_points([ map $_->clone, map @$_, map $_->subdivide(scale 10), @{offset([$convex_hull], scale 3)} ]); + + my $oozeprev = Slic3r::GCode::OozePrevention->new( + standby_points => [ map $_->clone, map @$_, map $_->subdivide(scale 10), @{offset([$convex_hull], scale 3)} ], + ); + $gcodegen->ooze_prevention($oozeprev); } }