From a8981b8b359eedc2294404f72aa9b70182d62d97 Mon Sep 17 00:00:00 2001
From: Alessandro Ranellucci <aar@cpan.org>
Date: Sat, 15 Jun 2013 12:10:57 +0200
Subject: [PATCH] Bugfix: infill was clipped badly. Includes regression test.
 #1245

---
 MANIFEST            |  1 +
 lib/Slic3r/Print.pm | 12 ++++++++----
 lib/Slic3r/Test.pm  |  9 ++++++---
 t/print.t           | 20 ++++++++++++++++++++
 4 files changed, 35 insertions(+), 7 deletions(-)
 create mode 100644 t/print.t

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__