From 11bd1e68e21865d9563b907c98a860fa91fc5049 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 5 Nov 2014 01:16:26 +0100 Subject: [PATCH] Fixed some regressions in retracts and wipe. Includes regression test --- lib/Slic3r/GCode.pm | 65 ++++++++++++++++++++++++--------------------- t/retraction.t | 12 ++++++++- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 742d24e81..27c1ccd35 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -192,7 +192,7 @@ sub extrude_loop { # reset acceleration $gcode .= $self->writer->set_acceleration($self->config->default_acceleration); - $self->_wipe_path($paths[-1]->polyline->clone) if $self->enable_wipe; # TODO: don't limit wipe to last path + $self->_wipe_path($paths[0]->polyline->clone) if $self->enable_wipe; # TODO: don't limit wipe to last path # make a little move inwards before leaving loop if ($paths[-1]->role == EXTR_ROLE_EXTERNAL_PERIMETER && defined $self->layer && $self->config->perimeters > 1) { @@ -422,39 +422,41 @@ sub retract { # get the retraction length my $length = $toolchange - ? $self->writer->extruder->retract_length - : $self->writer->extruder->retract_length_toolchange; + ? $self->writer->extruder->retract_length_toolchange + : $self->writer->extruder->retract_length; - # Calculate how long we need to travel in order to consume the required - # amount of retraction. In other words, how far do we move in XY at $wipe_speed - # for the time needed to consume retract_length at retract_speed? - my $wipe_dist = scale($length / $self->writer->extruder->retract_speed * $wipe_speed); + if ($length) { + # Calculate how long we need to travel in order to consume the required + # amount of retraction. In other words, how far do we move in XY at $wipe_speed + # for the time needed to consume retract_length at retract_speed? + my $wipe_dist = scale($length / $self->writer->extruder->retract_speed * $wipe_speed); - # Take the stored wipe path and replace first point with the current actual position - # (they might be different, for example, in case of loop clipping). - my $wipe_path = Slic3r::Polyline->new( - $self->last_pos, - @{$self->_wipe_path}[1..$#{$self->_wipe_path}], - ); - # - $wipe_path->clip_end($wipe_path->length - $wipe_dist); - - # subdivide the retraction in segments - my $retracted = 0; - foreach my $line (@{$wipe_path->lines}) { - my $segment_length = $line->length; - # Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one - # due to rounding (TODO: test and/or better math for this) - my $dE = $length * ($segment_length / $wipe_dist) * 0.95; - $gcode .= $self->writer->set_speed($wipe_speed*60); - $gcode .= $self->writer->extrude_to_xy( - $self->point_to_gcode($line->b), - -$dE, - 'retract' . ($self->enable_cooling_markers ? ';_WIPE' : ''), + # Take the stored wipe path and replace first point with the current actual position + # (they might be different, for example, in case of loop clipping). + my $wipe_path = Slic3r::Polyline->new( + $self->last_pos, + @{$self->_wipe_path}[1..$#{$self->_wipe_path}], ); - $retracted += $dE; + # + $wipe_path->clip_end($wipe_path->length - $wipe_dist); + + # subdivide the retraction in segments + my $retracted = 0; + foreach my $line (@{$wipe_path->lines}) { + my $segment_length = $line->length; + # Reduce retraction length a bit to avoid effective retraction speed to be greater than the configured one + # due to rounding (TODO: test and/or better math for this) + my $dE = $length * ($segment_length / $wipe_dist) * 0.95; + $gcode .= $self->writer->set_speed($wipe_speed*60); + $gcode .= $self->writer->extrude_to_xy( + $self->point_to_gcode($line->b), + -$dE, + 'retract' . ($self->enable_cooling_markers ? ';_WIPE' : ''), + ); + $retracted += $dE; + } + $self->writer->extruder->set_retracted($self->writer->extruder->retracted + $retracted); } - $self->writer->extruder->set_retracted($self->writer->extruder->retracted + $retracted); } # The parent class will decide whether we need to perform an actual retraction @@ -464,7 +466,8 @@ sub retract { $gcode .= $toolchange ? $self->writer->retract_for_toolchange : $self->writer->retract; $gcode .= $self->writer->reset_e; - $gcode .= $self->writer->lift; + $gcode .= $self->writer->lift + if $self->writer->extruder->retract_length > 0; return $gcode; } diff --git a/t/retraction.t b/t/retraction.t index 815b3ea64..abbb0f7cc 100644 --- a/t/retraction.t +++ b/t/retraction.t @@ -1,4 +1,4 @@ -use Test::More tests => 14; +use Test::More tests => 16; use strict; use warnings; @@ -127,16 +127,21 @@ use Slic3r::Test qw(_eq); { my $config = Slic3r::Config->new_from_defaults; + $config->set('start_gcode', ''); # prevent any default priming Z move from affecting our lift detection + $config->set('retract_length', [0]); $config->set('retract_layer_change', [0]); + $config->set('retract_lift', [0.2]); my $print = Slic3r::Test::init_print('20mm_cube', config => $config); my $retracted = 0; my $layer_changes_with_retraction = 0; + my $retractions = my $z_restores = 0; Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { my ($self, $cmd, $args, $info) = @_; if ($info->{retracting}) { $retracted = 1; + $retractions++; } elsif ($info->{extruding} && $retracted) { $retracted = 0; } @@ -144,9 +149,14 @@ use Slic3r::Test qw(_eq); if ($info->{dist_Z} && $retracted) { $layer_changes_with_retraction++; } + if ($info->{dist_Z} && $args->{Z} < $self->Z) { + $z_restores++; + } }); is $layer_changes_with_retraction, 0, 'no retraction on layer change'; + is $retractions, 0, 'no retractions'; + is $z_restores, 0, 'no lift'; } {