diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 9cf2409aa..e5fb2eb1e 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -9,6 +9,11 @@ use Slic3r::Geometry qw(epsilon scale unscale scaled_epsilon points_coincide PI use Slic3r::Geometry::Clipper qw(union_ex offset_ex); use Slic3r::Surface ':types'; +# Origin of print coordinates expressed in unscaled G-code coordinates. +# This affects the input arguments supplied to the extrude*() and travel_to() +# methods. +has 'origin' => (is => 'rw', default => sub { Slic3r::Pointf->new }); + has 'config' => (is => 'ro', default => sub { Slic3r::Config::Full->new }); has '_writer' => (is => 'ro', default => sub { Slic3r::GCode::Writer->new }, handles => [qw(set_fan set_temperature set_bed_temperature @@ -50,19 +55,18 @@ sub set_extruders { $self->enable_wipe(defined first { $self->config->get_at('wipe', $_) } @$extruder_ids); } -sub set_shift { - my ($self, @shift) = @_; +sub set_origin { + my ($self, $pointf) = @_; - # if shift increases (goes towards right), last_pos decreases because it goes towards left + # if origin increases (goes towards right), last_pos decreases because it goes towards left my @translate = ( - scale ($self->shift_x - $shift[X]), - scale ($self->shift_y - $shift[Y]), + scale ($self->origin->x - $pointf->x), + scale ($self->origin->y - $pointf->y), #- ); $self->last_pos->translate(@translate); $self->wipe_path->translate(@translate) if $self->wipe_path; - $self->shift_x($shift[X]); - $self->shift_y($shift[Y]); + $self->origin($pointf); } sub change_layer { @@ -291,8 +295,8 @@ sub _extrude_path { { my $extruder_offset = $self->config->get_at('extruder_offset', $self->_writer->extruder->id); $gcode .= $path->gcode($self->_writer->extruder, $e_per_mm, $F, - $self->shift_x - $extruder_offset->x, - $self->shift_y - $extruder_offset->y, #,, + $self->origin->x - $extruder_offset->x, + $self->origin->y - $extruder_offset->y, #- $self->_writer->_extrusion_axis, $self->config->gcode_comments ? " ; $description" : ""); @@ -321,7 +325,7 @@ sub travel_to { # move travel back to original layer coordinates for the island check. # note that we're only considering the current object's islands, while we should # build a more complete configuration space - $travel->translate(-$self->shift_x, -$self->shift_y); + $travel->translate(scale -$self->origin->x, scale -$self->origin->y); #;; # skip retraction if the travel move is contained in an island in the current layer # *and* in an island in the upper layer (so that the ooze will not be visible) @@ -344,13 +348,13 @@ sub travel_to { # represent $point in G-code coordinates $point = $point->clone; - my @shift = ($self->shift_x, $self->shift_y); - $point->translate(map scale $_, @shift); + my $origin = $self->origin; + $point->translate(map scale $_, @$origin); # calculate path (external_mp uses G-code coordinates so we temporary need a null shift) - $self->set_shift(0,0); + $self->set_origin(Slic3r::Pointf->new(0,0)); $gcode .= $self->_plan($self->external_mp, $point, $comment); - $self->set_shift(@shift); + $self->set_origin($origin); } else { $gcode .= $self->_plan($self->layer_mp, $point, $comment); } @@ -466,8 +470,8 @@ sub point_to_gcode { my $extruder_offset = $self->config->get_at('extruder_offset', $self->_writer->extruder->id); return Slic3r::Pointf->new( - ($point->x * &Slic3r::SCALING_FACTOR) + $self->shift_x - $extruder_offset->x, - ($point->y * &Slic3r::SCALING_FACTOR) + $self->shift_y - $extruder_offset->y, #** + ($point->x * &Slic3r::SCALING_FACTOR) + $self->origin->x - $extruder_offset->x, + ($point->y * &Slic3r::SCALING_FACTOR) + $self->origin->y - $extruder_offset->y, #** ); } diff --git a/lib/Slic3r/GCode/Layer.pm b/lib/Slic3r/GCode/Layer.pm index d4519f8f2..0859b7d8c 100644 --- a/lib/Slic3r/GCode/Layer.pm +++ b/lib/Slic3r/GCode/Layer.pm @@ -6,7 +6,7 @@ use Slic3r::Geometry qw(X Y unscale); has 'print' => (is => 'ro', required => 1, handles => [qw(config)]); has 'gcodegen' => (is => 'ro', required => 1, handles => [qw(extruders)]); -has 'shift' => (is => 'ro', default => sub { [0,0] }); +has 'origin' => (is => 'ro', default => sub { Slic3r::Pointf->new(0,0) }); has 'spiralvase' => (is => 'lazy'); has 'vibration_limit' => (is => 'lazy'); @@ -82,7 +82,7 @@ sub process_layer { # extrude skirt if (((values %{$self->skirt_done}) < $self->print->config->skirt_height || $self->print->config->skirt_height == -1) && !$self->skirt_done->{$layer->print_z}) { - $self->gcodegen->set_shift(@{$self->shift}); + $self->gcodegen->set_origin($self->origin); my @extruder_ids = map { $_->id } @{$self->extruders}; $gcode .= $self->gcodegen->set_extruder($extruder_ids[0]); # skip skirt if we have a large brim @@ -106,7 +106,7 @@ sub process_layer { # extrude brim if (!$self->brim_done) { $gcode .= $self->gcodegen->set_extruder($self->print->objects->[0]->config->support_material_extruder-1); - $self->gcodegen->set_shift(@{$self->shift}); + $self->gcodegen->set_origin($self->origin); $gcode .= $self->gcodegen->extrude_loop($_, 'brim', $object->config->support_material_speed) for @{$self->print->brim}; $self->brim_done(1); @@ -117,7 +117,7 @@ sub process_layer { $self->gcodegen->new_object(1) if ($self->_last_obj_copy // '') ne "$copy"; $self->_last_obj_copy("$copy"); - $self->gcodegen->set_shift(map $self->shift->[$_] + unscale $copy->[$_], X,Y); + $self->gcodegen->set_origin(Slic3r::Pointf->new(map $self->origin->[$_] + unscale $copy->[$_], X,Y)); # extrude support material before other things because it might use a lower Z # and also because we avoid travelling on other things when printing it diff --git a/lib/Slic3r/GCode/OozePrevention.pm b/lib/Slic3r/GCode/OozePrevention.pm index 2616387a2..6f25dd596 100644 --- a/lib/Slic3r/GCode/OozePrevention.pm +++ b/lib/Slic3r/GCode/OozePrevention.pm @@ -13,9 +13,9 @@ sub pre_toolchange { # 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); + $last_pos->translate(scale +$gcodegen->origin->x, scale +$gcodegen->origin->y); #)) my $standby_point = $last_pos->nearest_point($self->standby_points); - $standby_point->translate(scale -$gcodegen->shift_x, scale -$gcodegen->shift_y); + $standby_point->translate(scale -$gcodegen->origin->x, scale -$gcodegen->origin->y); #)) $gcode .= $gcodegen->travel_to($standby_point); } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 1ac7f5f79..b4510220a 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -873,7 +873,7 @@ sub write_gcode { # this happens before Z goes down to layer 0 again, so that # no collision happens hopefully. if ($finished_objects > 0) { - $gcodegen->set_shift(map unscale $copy->[$_], X,Y); + $gcodegen->set_origin(Slic3r::Pointf->new(map unscale $copy->[$_], X,Y)); print $fh $gcodegen->retract; print $fh $gcodegen->travel_to( $object->_copies_shift->negative, diff --git a/t/gcode.t b/t/gcode.t index b4cd7aa9f..f82bc72ac 100644 --- a/t/gcode.t +++ b/t/gcode.t @@ -17,7 +17,7 @@ use Slic3r::Test; layer_count => 1, extruders => [], ); - $gcodegen->set_shift(10, 10); + $gcodegen->set_origin(Slic3r::Pointf->new(10, 10)); is_deeply $gcodegen->last_pos->arrayref, [scale -10, scale -10], 'last_pos is shifted correctly'; }