diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index a6c160acb..03b568339 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -814,7 +814,7 @@ END }, 'retract_lift' => { label => 'Lift Z', - tooltip => 'If you set this to a positive value, Z is quickly raised every time a retraction is triggered.', + tooltip => 'If you set this to a positive value, Z is quickly raised every time a retraction is triggered. When using multiple extruders, only the setting for the first extruder will be considered.', sidetext => 'mm', cli => 'retract-lift=f@', type => 'f', diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index b06294056..1df6e8a79 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -3,7 +3,7 @@ use Moo; use List::Util qw(min max first); use Slic3r::ExtrusionPath ':roles'; -use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y B); +use Slic3r::Geometry qw(epsilon scale unscale scaled_epsilon points_coincide PI X Y B); use Slic3r::Geometry::Clipper qw(union_ex); use Slic3r::Surface ':types'; @@ -128,12 +128,23 @@ sub move_z { my $gcode = ""; my $current_z = $self->z; - if (!defined $current_z || $current_z != ($z + $self->lifted)) { + if (!defined $self->z || $z > $self->z) { + # if we're going over the current Z we won't be lifted anymore + $self->lifted(0); + + # this retraction may alter $self->z $gcode .= $self->retract(move_z => $z) if $self->extruder->retract_layer_change; + $self->speed('travel'); $gcode .= $self->G0(undef, $z, 0, $comment || ('move to next layer (' . $self->layer->id . ')')) - unless ($current_z // -1) != ($self->z // -1); + unless !defined $current_z || $self->z != $current_z; $gcode .= $self->move_z_callback->() if defined $self->move_z_callback; + } elsif ($z < $self->z && $z > ($self->z - $self->lifted + epsilon)) { + # we're moving to a layer height which is greater than the nominal current one + # (nominal = actual - lifted) and less than the actual one. we're basically + # advancing to next layer, whose nominal Z is still lower than the previous + # layer Z with lift. + $self->lifted($self->z - $z); } return $gcode; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 531197582..8c62d1a48 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -73,6 +73,9 @@ sub _trigger_config { $self->config->set('support_material_enforce_layers', 0); $self->config->set('retract_layer_change', [0]); # TODO: only apply this to the spiral layers } + + # force all retraction lift values to be the same + $self->config->set('retract_lift', [ map $self->config->retract_lift->[0], @{$self->config->retract_lift} ]); } sub _build_has_support_material { diff --git a/t/retraction.t b/t/retraction.t index cb1366776..08276ad6e 100644 --- a/t/retraction.t +++ b/t/retraction.t @@ -48,8 +48,9 @@ my $test = sub { } if ($info->{dist_Z} < 0) { fail 'going down only after lifting' if !$lifted; - fail 'going down by the same amount of the lift' - if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift); + fail 'going down by the same amount of the lift or by the amount needed to get to next layer' + if !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift) + && !_eq($info->{dist_Z}, -$print->extruders->[$tool]->retract_lift + $conf->layer_height); $lifted = 0; } fail 'move Z at travel speed' if ($args->{F} // $self->F) != $conf->travel_speed * 60; @@ -123,6 +124,8 @@ $retract_tests->(' (G0 and duplicate)'); $config->set('duplicate', 1); $config->set('g0', 0); $config->set('infill_extruder', 2); -$retract_tests->(' (dual extruder)'); +$config->set('skirts', 4); +$config->set('skirt_height', 3); +$retract_tests->(' (dual extruder with multiple skirt layers)'); __END__