mirror of https://github.com/vitalif/Slic3r
master
parent
8290a006ed
commit
3d25b9030c
|
@ -953,6 +953,7 @@ sub write_gcode {
|
||||||
|
|
||||||
my $finished_objects = 0;
|
my $finished_objects = 0;
|
||||||
for my $obj_idx (@obj_idx) {
|
for my $obj_idx (@obj_idx) {
|
||||||
|
my $object = $self->objects->[$obj_idx];
|
||||||
for my $copy (@{ $self->objects->[$obj_idx]->_shifted_copies }) {
|
for my $copy (@{ $self->objects->[$obj_idx]->_shifted_copies }) {
|
||||||
# move to the origin position for the copy we're going to print.
|
# move to the origin position for the copy we're going to print.
|
||||||
# this happens before Z goes down to layer 0 again, so that
|
# this happens before Z goes down to layer 0 again, so that
|
||||||
|
@ -960,7 +961,7 @@ sub write_gcode {
|
||||||
if ($finished_objects > 0) {
|
if ($finished_objects > 0) {
|
||||||
$gcodegen->set_shift(map unscale $copy->[$_], X,Y);
|
$gcodegen->set_shift(map unscale $copy->[$_], X,Y);
|
||||||
print $fh $gcodegen->retract;
|
print $fh $gcodegen->retract;
|
||||||
print $fh $gcodegen->G0(Slic3r::Point->new(0,0), undef, 0, $gcodegen->config->travel_speed*60, 'move to origin position for next object');
|
print $fh $gcodegen->G0($object->_copies_shift->negative, undef, 0, $gcodegen->config->travel_speed*60, 'move to origin position for next object');
|
||||||
}
|
}
|
||||||
|
|
||||||
my $buffer = Slic3r::GCode::CoolingBuffer->new(
|
my $buffer = Slic3r::GCode::CoolingBuffer->new(
|
||||||
|
@ -968,7 +969,6 @@ sub write_gcode {
|
||||||
gcodegen => $gcodegen,
|
gcodegen => $gcodegen,
|
||||||
);
|
);
|
||||||
|
|
||||||
my $object = $self->objects->[$obj_idx];
|
|
||||||
my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers};
|
my @layers = sort { $a->print_z <=> $b->print_z } @{$object->layers}, @{$object->support_layers};
|
||||||
for my $layer (@layers) {
|
for my $layer (@layers) {
|
||||||
# if we are printing the bottom layer of an object, and we have already finished
|
# if we are printing the bottom layer of an object, and we have already finished
|
||||||
|
|
19
t/gcode.t
19
t/gcode.t
|
@ -1,4 +1,4 @@
|
||||||
use Test::More tests => 8;
|
use Test::More tests => 9;
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ BEGIN {
|
||||||
|
|
||||||
use List::Util qw(first);
|
use List::Util qw(first);
|
||||||
use Slic3r;
|
use Slic3r;
|
||||||
use Slic3r::Geometry qw(scale);
|
use Slic3r::Geometry qw(scale convex_hull);
|
||||||
use Slic3r::Test;
|
use Slic3r::Test;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,7 @@ use Slic3r::Test;
|
||||||
# - complete objects does not crash
|
# - complete objects does not crash
|
||||||
# - no hard-coded "E" are generated
|
# - no hard-coded "E" are generated
|
||||||
# - Z moves are correctly generated for both objects
|
# - Z moves are correctly generated for both objects
|
||||||
|
# - no travel moves go outside skirt
|
||||||
my $config = Slic3r::Config->new_from_defaults;
|
my $config = Slic3r::Config->new_from_defaults;
|
||||||
$config->set('gcode_comments', 1);
|
$config->set('gcode_comments', 1);
|
||||||
$config->set('complete_objects', 1);
|
$config->set('complete_objects', 1);
|
||||||
|
@ -56,16 +57,30 @@ use Slic3r::Test;
|
||||||
my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2);
|
my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2);
|
||||||
ok my $gcode = Slic3r::Test::gcode($print), "complete_objects";
|
ok my $gcode = Slic3r::Test::gcode($print), "complete_objects";
|
||||||
my @z_moves = ();
|
my @z_moves = ();
|
||||||
|
my @travel_moves = (); # array of scaled points
|
||||||
|
my @extrusions = (); # array of scaled points
|
||||||
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}) {
|
if (defined $args->{Z}) {
|
||||||
push @z_moves, $args->{Z};
|
push @z_moves, $args->{Z};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($info->{dist_XY}) {
|
||||||
|
if ($info->{extruding} || $args->{A}) {
|
||||||
|
push @extrusions, Slic3r::Point->new_scale($info->{new_X}, $info->{new_Y});
|
||||||
|
} else {
|
||||||
|
push @travel_moves, Slic3r::Point->new_scale($info->{new_X}, $info->{new_Y})
|
||||||
|
if @extrusions; # skip initial travel move to first skirt point
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
my $layer_count = 20/0.4; # cube is 20mm tall
|
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 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';
|
is_deeply [ @z_moves[0..($layer_count-1)] ], [ @z_moves[$layer_count..$#z_moves] ], 'complete_objects generates the correct Z moves';
|
||||||
|
|
||||||
|
my $convex_hull = convex_hull(\@extrusions);
|
||||||
|
ok !(defined first { !$convex_hull->contains_point($_) } @travel_moves), 'all travel moves happen within skirt';
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,6 +190,12 @@ Point::projection_onto(const Line &line) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Point
|
||||||
|
Point::negative() const
|
||||||
|
{
|
||||||
|
return Point(-this->x, -this->y);
|
||||||
|
}
|
||||||
|
|
||||||
Point
|
Point
|
||||||
operator+(const Point& point1, const Point& point2)
|
operator+(const Point& point1, const Point& point2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@ class Point
|
||||||
double ccw(const Line &line) const;
|
double ccw(const Line &line) const;
|
||||||
Point projection_onto(const MultiPoint &poly) const;
|
Point projection_onto(const MultiPoint &poly) const;
|
||||||
Point projection_onto(const Line &line) const;
|
Point projection_onto(const Line &line) const;
|
||||||
|
Point negative() const;
|
||||||
|
|
||||||
#ifdef SLIC3RXS
|
#ifdef SLIC3RXS
|
||||||
void from_SV(SV* point_sv);
|
void from_SV(SV* point_sv);
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*polyline)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*polyline)); %};
|
||||||
Clone<Point> projection_onto_line(Line* line)
|
Clone<Point> projection_onto_line(Line* line)
|
||||||
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
|
%code{% RETVAL = new Point(THIS->projection_onto(*line)); %};
|
||||||
|
Clone<Point> negative()
|
||||||
|
%code{% RETVAL = new Point(THIS->negative()); %};
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue