diff --git a/MANIFEST b/MANIFEST index b2fe05eda..86390ed37 100644 --- a/MANIFEST +++ b/MANIFEST @@ -76,6 +76,7 @@ t/geometry.t t/layers.t t/loops.t t/polyclip.t +t/print.t t/retraction.t t/serialize.t t/shells.t diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 638ce8d3a..956de6992 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -106,6 +106,7 @@ sub add_model { $model->split_meshes if $Slic3r::Config->avoid_crossing_perimeters && !$Slic3r::Config->complete_objects; foreach my $object (@{ $model->objects }) { + # we align object to origin before applying transformations my @align = $object->align_to_origin; # extract meshes by material @@ -135,8 +136,11 @@ sub add_model { $mesh->scale(1 / &Slic3r::SCALING_FACTOR); } - # calculate transformed size - my $size = [ Slic3r::Geometry::size_3D([ map @{$_->used_vertices}, grep $_, @meshes ]) ]; + # we also align object after transformations so that we only work with positive coordinates + # and the assumption that bounding_box === size works + my $bb = Slic3r::Geometry::BoundingBox->new_from_points_3D([ map @{$_->used_vertices}, grep $_, @meshes ]); + my @align2 = map -$bb->extents->[$_][MIN], (X,Y,Z); + $_->move(@align2) for grep $_, @meshes; # initialize print object push @{$self->objects}, Slic3r::Print::Object->new( @@ -144,10 +148,10 @@ sub add_model { meshes => [ @meshes ], copies => [ $object->instances - ? (map [ scale($_->offset->[X] - $align[X]), scale($_->offset->[Y] - $align[Y]) ], @{$object->instances}) + ? (map [ scale($_->offset->[X] - $align[X]) - $align2[X], scale($_->offset->[Y] - $align[Y]) - $align2[Y] ], @{$object->instances}) : [0,0], ], - size => $size, + size => $bb->size, # transformed size input_file => $object->input_file, layer_height_ranges => $object->layer_height_ranges, ); diff --git a/lib/Slic3r/Test.pm b/lib/Slic3r/Test.pm index 46443cc6a..319214997 100644 --- a/lib/Slic3r/Test.pm +++ b/lib/Slic3r/Test.pm @@ -16,7 +16,7 @@ my %cuboids = ( ); sub model { - my ($model_name) = @_; + my ($model_name, %params) = @_; my ($vertices, $facets); if ($cuboids{$model_name}) { @@ -32,7 +32,10 @@ sub model { my $model = Slic3r::Model->new; my $object = $model->add_object(vertices => $vertices); $object->add_volume(facets => $facets); - $object->add_instance(offset => [0,0]); + $object->add_instance( + offset => [0,0], + rotation => $params{rotation}, + ); return $model; } @@ -46,7 +49,7 @@ sub init_print { my $print = Slic3r::Print->new(config => $config); $model_name = [$model_name] if ref($model_name) ne 'ARRAY'; - $print->add_model(model($_)) for @$model_name; + $print->add_model(model($_, %params)) for @$model_name; $print->validate; return $print; diff --git a/t/print.t b/t/print.t new file mode 100644 index 000000000..485ad12bb --- /dev/null +++ b/t/print.t @@ -0,0 +1,20 @@ +use Test::More tests => 1; +use strict; +use warnings; + +BEGIN { + use FindBin; + use lib "$FindBin::Bin/../lib"; +} + +use List::Util qw(first); +use Slic3r; +use Slic3r::Test; + +{ + my $print = Slic3r::Test::init_print('20mm_cube', rotation => 45); + ok !(first { $_ < 0 } map @$_, map @{$_->used_vertices}, grep $_, map @{$_->meshes}, @{$print->objects}), + "object is still in positive coordinate space even after rotation"; +} + +__END__