Fix regression causing complete_objects to skip Z moves after first object is complete. Includes regression test. #1582 #1541
This commit is contained in:
parent
f4d12b5930
commit
00e8ba4781
@ -130,25 +130,33 @@ sub change_layer {
|
|||||||
sub move_z {
|
sub move_z {
|
||||||
my ($self, $z, $comment) = @_;
|
my ($self, $z, $comment) = @_;
|
||||||
|
|
||||||
$z += $self->config->z_offset;
|
|
||||||
|
|
||||||
my $gcode = "";
|
my $gcode = "";
|
||||||
|
|
||||||
|
$z += $self->config->z_offset;
|
||||||
my $current_z = $self->z;
|
my $current_z = $self->z;
|
||||||
if (!defined $self->z || $z > $self->z) {
|
my $nominal_z = defined $current_z ? ($current_z - $self->lifted) : undef;
|
||||||
# if we're going over the current Z we won't be lifted anymore
|
|
||||||
|
if (!defined $current_z || $z > $current_z || $z < $nominal_z) {
|
||||||
|
# we're moving above the current actual Z (so above the lift height of the current
|
||||||
|
# layer if any) or below the current nominal layer
|
||||||
|
|
||||||
|
# in both cases, we're going to the nominal Z of the next layer
|
||||||
$self->lifted(0);
|
$self->lifted(0);
|
||||||
|
|
||||||
|
if ($self->extruder->retract_layer_change) {
|
||||||
# this retraction may alter $self->z
|
# this retraction may alter $self->z
|
||||||
$gcode .= $self->retract(move_z => $z) if $self->extruder->retract_layer_change;
|
$gcode .= $self->retract(move_z => $z);
|
||||||
|
$current_z = $self->z; # update current z in case retract() changed it
|
||||||
|
$nominal_z = defined $current_z ? ($current_z - $self->lifted) : undef;
|
||||||
|
}
|
||||||
$self->speed('travel');
|
$self->speed('travel');
|
||||||
$gcode .= $self->G0(undef, $z, 0, $comment || ('move to next layer (' . $self->layer->id . ')'))
|
$gcode .= $self->G0(undef, $z, 0, $comment || ('move to next layer (' . $self->layer->id . ')'))
|
||||||
if !defined $self->z || abs($z - ($self->z - $self->lifted)) > epsilon;
|
if !defined $current_z || abs($z - $nominal_z) > epsilon;
|
||||||
} elsif ($z < $self->z && $z > ($self->z - $self->lifted + epsilon)) {
|
} elsif ($z < $current_z) {
|
||||||
# we're moving to a layer height which is greater than the nominal current one
|
# we're moving above the current nominal layer height and below the current actual one.
|
||||||
# (nominal = actual - lifted) and less than the actual one. we're basically
|
# we're basically advancing to next layer, whose nominal Z is still lower than the previous
|
||||||
# advancing to next layer, whose nominal Z is still lower than the previous
|
|
||||||
# layer Z with lift.
|
# layer Z with lift.
|
||||||
$self->lifted($self->z - $z);
|
$self->lifted($current_z - $z);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $gcode;
|
return $gcode;
|
||||||
|
16
t/gcode.t
16
t/gcode.t
@ -1,4 +1,4 @@
|
|||||||
use Test::More tests => 4;
|
use Test::More tests => 6;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
@ -43,16 +43,30 @@ use Slic3r::Test;
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
# This tests the following behavior:
|
||||||
|
# - complete objects does not crash
|
||||||
|
# - no hard-coded "E" are generated
|
||||||
|
# - Z moves are correctly generated for both objects
|
||||||
my $config = Slic3r::Config->new_from_defaults;
|
my $config = Slic3r::Config->new_from_defaults;
|
||||||
$config->set('complete_objects', 1);
|
$config->set('complete_objects', 1);
|
||||||
$config->set('duplicate', 2);
|
$config->set('duplicate', 2);
|
||||||
$config->set('extrusion_axis', 'A');
|
$config->set('extrusion_axis', 'A');
|
||||||
|
$config->set('start_gcode', ''); # prevent any default extra Z move
|
||||||
|
$config->set('layer_height', 0.4);
|
||||||
|
$config->set('first_layer_height', 0.4);
|
||||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||||
ok my $gcode = Slic3r::Test::gcode($print), "complete_objects";
|
ok my $gcode = Slic3r::Test::gcode($print), "complete_objects";
|
||||||
|
my @z_moves = ();
|
||||||
Slic3r::GCode::Reader->new->parse($gcode, sub {
|
Slic3r::GCode::Reader->new->parse($gcode, sub {
|
||||||
my ($self, $cmd, $args, $info) = @_;
|
my ($self, $cmd, $args, $info) = @_;
|
||||||
fail 'unexpected E argument' if defined $args->{E};
|
fail 'unexpected E argument' if defined $args->{E};
|
||||||
|
if (defined $args->{Z}) {
|
||||||
|
push @z_moves, $args->{Z};
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
my $layer_count = 20/0.4; # cube is 20mm tall
|
||||||
|
is scalar(@z_moves), 2*$layer_count, 'complete_objects generates the correct number of Z moves';
|
||||||
|
is_deeply [ @z_moves[0..($layer_count-1)] ], [ @z_moves[$layer_count..$#z_moves] ], 'complete_objects generates the correct Z moves';
|
||||||
}
|
}
|
||||||
|
|
||||||
__END__
|
__END__
|
||||||
|
Loading…
Reference in New Issue
Block a user