Browse Source

Return objects by reference instead of always cloning

Alessandro Ranellucci 11 years ago
parent
commit
c0789506e4

+ 2 - 1
lib/Slic3r/Fill.pm

@@ -180,9 +180,10 @@ sub make_fill {
         # save into layer
         push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;
         $collection->no_sort($params->{no_sort});
+        
         $collection->append(
             map Slic3r::ExtrusionPath->new(
-                polyline => Slic3r::Polyline->new(@$_),
+                polyline => $_,
                 role => ($surface->surface_type == S_TYPE_INTERNALBRIDGE
                     ? EXTR_ROLE_INTERNALBRIDGE
                     : $is_bridge

+ 3 - 1
lib/Slic3r/Fill/Honeycomb.pm

@@ -108,7 +108,9 @@ sub fill_surface {
                         next;
                     }
                 }
-                push @paths, $path;
+                
+                # make a clone before $collection goes out of scope
+                push @paths, $path->clone;
             }
         }
         

+ 3 - 1
lib/Slic3r/Fill/Rectilinear.pm

@@ -91,7 +91,9 @@ sub fill_surface {
                     next;
                 }
             }
-            push @polylines, $polyline;
+            
+            # make a clone before $collection goes out of scope
+            push @polylines, $polyline->clone;
         }
     }
     

+ 5 - 3
lib/Slic3r/Layer/Region.pm

@@ -252,7 +252,7 @@ sub make_perimeters {
         # use a nearest neighbor search to order these children
         # TODO: supply second argument to chained_path_items() too?
         my @nodes = @{Slic3r::Geometry::chained_path_items(
-            [ map [ Slic3r::Point->new(@{$_->{outer} ? $_->{outer}[0] : $_->{hole}[0]}), $_ ], @$polynodes ],
+            [ map [ ($_->{outer} // $_->{hole})->first_point->clone, $_ ], @$polynodes ],
         )};
         
         my @loops = ();
@@ -262,7 +262,9 @@ sub make_perimeters {
             # return ccw contours and cw holes
             # GCode.pm will convert all of them to ccw, but it needs to know
             # what the holes are in order to compute the correct inwards move
-            my $polygon = Slic3r::Polygon->new(defined $polynode->{outer} ? @{$polynode->{outer}} : reverse @{$polynode->{hole}});
+            
+            my $polygon = ($polynode->{outer} // $polynode->{hole})->clone;
+            $polygon->reverse if defined $polynode->{hole};
             $polygon->reverse if !$is_contour;
             
             my $role = EXTR_ROLE_PERIMETER;
@@ -302,7 +304,7 @@ sub make_perimeters {
     # add thin walls as perimeters
     push @{ $self->perimeters }, @{Slic3r::ExtrusionPath::Collection->new(
         map Slic3r::ExtrusionPath->new(
-                polyline        => ($_->isa('Slic3r::Polygon') ? $_->split_at_first_point : $_),
+                polyline        => ($_->isa('Slic3r::Polygon') ? $_->split_at_first_point : $_->clone),
                 role            => EXTR_ROLE_EXTERNAL_PERIMETER,
                 flow_spacing    => $self->perimeter_flow->spacing,
         ), @{ $self->thin_walls }

+ 10 - 0
xs/lib/Slic3r/XS.pm

@@ -12,11 +12,21 @@ use overload
     '@{}' => sub { $_[0]->arrayref },
     'fallback' => 1;
 
+package Slic3r::Line::Ref;
+our @ISA = 'Slic3r::Line';
+
+sub DESTROY {}
+
 package Slic3r::Point;
 use overload
     '@{}' => sub { $_[0]->arrayref },
     'fallback' => 1;
 
+package Slic3r::Point::Ref;
+our @ISA = 'Slic3r::Point';
+
+sub DESTROY {}
+
 package Slic3r::ExPolygon;
 use overload
     '@{}' => sub { $_[0]->arrayref },

+ 2 - 2
xs/src/ClipperUtils.cpp

@@ -339,9 +339,9 @@ polynode2perl(const ClipperLib::PolyNode& node)
     Slic3r::Polygon p;
     ClipperPolygon_to_Slic3rPolygon(node.Contour, p);
     if (node.IsHole()) {
-        (void)hv_stores( hv, "hole", p.to_SV() );
+        (void)hv_stores( hv, "hole", p.to_SV_clone_ref() );
     } else {
-        (void)hv_stores( hv, "outer", p.to_SV() );
+        (void)hv_stores( hv, "outer", p.to_SV_clone_ref() );
     }
     (void)hv_stores( hv, "children", polynode_children_2_perl(node) );
     return (SV*)newRV_noinc((SV*)hv);

+ 9 - 5
xs/src/ExPolygon.cpp

@@ -57,19 +57,23 @@ ExPolygon::to_SV() {
     av_extend(av, num_holes);  // -1 +1
     
     SV* sv = newSV(0);
-    sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->contour) );
-    av_store(av, 0, sv);
+    av_store(av, 0, this->contour.to_SV_ref());
     
     for (unsigned int i = 0; i < num_holes; i++) {
-        sv = newSV(0);
-        sv_setref_pv( sv, "Slic3r::Polygon", new Polygon(this->holes[i]) );
-        av_store(av, i+1, sv);
+        av_store(av, i+1, this->holes[i].to_SV_ref());
     }
     return newRV_noinc((SV*)av);
 }
 
 SV*
 ExPolygon::to_SV_ref() {
+    SV* sv = newSV(0);
+    sv_setref_pv( sv, "Slic3r::ExPolygon::Ref", this );
+    return sv;
+}
+
+SV*
+ExPolygon::to_SV_clone_ref() {
     SV* sv = newSV(0);
     sv_setref_pv( sv, "Slic3r::ExPolygon", new ExPolygon(*this) );
     return sv;

+ 1 - 0
xs/src/ExPolygon.hpp

@@ -15,6 +15,7 @@ class ExPolygon
     void from_SV_check(SV* poly_sv);
     SV* to_SV();
     SV* to_SV_ref();
+    SV* to_SV_clone_ref();
     SV* to_SV_pureperl();
     void scale(double factor);
     void translate(double x, double y);

+ 9 - 2
xs/src/Line.cpp

@@ -66,11 +66,11 @@ Line::to_SV() {
     av_extend(av, 1);
     
     SV* sv = newSV(0);
-    sv_setref_pv( sv, "Slic3r::Point", new Point(this->a) );
+    sv_setref_pv( sv, "Slic3r::Point::Ref", &(this->a) );
     av_store(av, 0, sv);
     
     sv = newSV(0);
-    sv_setref_pv( sv, "Slic3r::Point", new Point(this->b) );
+    sv_setref_pv( sv, "Slic3r::Point::Ref", &(this->b) );
     av_store(av, 1, sv);
     
     return newRV_noinc((SV*)av);
@@ -78,6 +78,13 @@ Line::to_SV() {
 
 SV*
 Line::to_SV_ref() {
+    SV* sv = newSV(0);
+    sv_setref_pv( sv, "Slic3r::Line::Ref", this );
+    return sv;
+}
+
+SV*
+Line::to_SV_clone_ref() {
     SV* sv = newSV(0);
     sv_setref_pv( sv, "Slic3r::Line", new Line(*this) );
     return sv;

+ 1 - 0
xs/src/Line.hpp

@@ -17,6 +17,7 @@ class Line
     void from_SV_check(SV* line_sv);
     SV* to_SV();
     SV* to_SV_ref();
+    SV* to_SV_clone_ref();
     SV* to_SV_pureperl();
     void scale(double factor);
     void translate(double x, double y);

Some files were not shown because too many files changed in this diff