Просмотр исходного кода

Port offset_ex() and offset2_ex() to XS

Alessandro Ranellucci 11 лет назад
Родитель
Сommit
898007fc36

+ 4 - 4
lib/Slic3r/ExPolygon.pm

@@ -51,12 +51,12 @@ sub offset {
 
 sub offset_ex {
     my $self = shift;
-    return Slic3r::Geometry::Clipper::offset_ex($self, @_);
+    return Slic3r::Geometry::Clipper::offset_ex(\@$self, @_);
 }
 
 sub safety_offset {
     my $self = shift;
-    return Slic3r::Geometry::Clipper::safety_offset_ex($self, @_);
+    return Slic3r::Geometry::Clipper::safety_offset_ex(\@$self, @_);
 }
 
 sub noncollapsing_offset_ex {
@@ -69,7 +69,7 @@ sub noncollapsing_offset_ex {
 sub encloses_point {
     my $self = shift;
     my ($point) = @_;
-    return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, $self->pp);
+    return Boost::Geometry::Utils::point_covered_by_polygon($point->pp, $self->pp);
 }
 
 # A version of encloses_point for use when hole borders do not matter.
@@ -78,7 +78,7 @@ sub encloses_point {
 sub encloses_point_quick {
     my $self = shift;
     my ($point) = @_;
-    return Boost::Geometry::Utils::point_within_polygon($point->arrayref, $self->arrayref);
+    return Boost::Geometry::Utils::point_within_polygon($point->pp, $self->pp);
 }
 
 sub encloses_line {

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

@@ -115,7 +115,7 @@ sub fill_surface {
         # clip paths again to prevent connection segments from crossing the expolygon boundaries
         @paths = map Slic3r::Polyline->new(@$_),
             @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection(
-                [ map $_->pp, $surface->expolygon->offset_ex(scaled_epsilon) ],
+                [ map $_->pp, @{$surface->expolygon->offset_ex(scaled_epsilon)} ],
                 [ map $_->pp, @paths ],
             ) } if @paths;  # this temporary check is a workaround for the multilinestring bug in B::G::U
     }

+ 2 - 2
lib/Slic3r/Fill/Rectilinear.pm

@@ -16,7 +16,7 @@ sub fill_surface {
     my $rotate_vector = $self->infill_direction($surface);
     $self->rotate_points($expolygon, $rotate_vector);
     
-    my ($expolygon_off) = $expolygon->offset_ex(scale $params{flow_spacing}/2);
+    my $expolygon_off = $expolygon->offset_ex(scale $params{flow_spacing}/2)->[0];
     return {} if !defined $expolygon_off;  # skip some very small polygons (which shouldn't arrive here)
     
     my $flow_spacing = $params{flow_spacing};
@@ -67,7 +67,7 @@ sub fill_surface {
     # are kept even if the expolygon has vertical sides
     my @polylines = map Slic3r::Polyline->new(@$_),
         @{ Boost::Geometry::Utils::multi_polygon_multi_linestring_intersection(
-            [ map $_->pp, $expolygon->offset_ex(scaled_epsilon) ],
+            [ map $_->pp, @{ $expolygon->offset_ex(scaled_epsilon) } ],
             [ map $_->pp, @{ $self->cache->{$cache_id} } ],
         ) };
     

+ 1 - 1
lib/Slic3r/GCode/MotionPlanner.pm

@@ -49,7 +49,7 @@ sub BUILD {
         # so that no motion along external perimeters happens
         $self->_inner->[$i] = $self->no_internal
             ? []
-            : [ $self->islands->[$i]->offset_ex(-$self->_inner_margin) ];
+            : $self->islands->[$i]->offset_ex(-$self->_inner_margin);
         
         # offset the island outwards to make the boundaries for external movements
         $self->_outer->[$i] = [ offset([ $self->islands->[$i]->contour], $self->_outer_margin) ];

+ 1 - 21
lib/Slic3r/Geometry/Clipper.pm

@@ -45,26 +45,6 @@ sub offset2 {
     return @$offsets;
 }
 
-sub offset_ex {
-    my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_;
-    $scale      ||= 100000;
-    $joinType   //= JT_MITER;
-    $miterLimit //= 3;
-    
-    my $offsets = Math::Clipper::ex_int_offset(_convert($polygons), $distance, $scale, $joinType, $miterLimit);
-    return map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), @$offsets;
-}
-
-sub offset2_ex {
-    my ($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit) = @_;
-    $scale      ||= 100000;
-    $joinType   //= JT_MITER;
-    $miterLimit //= 3;
-    
-    my $offsets = Math::Clipper::ex_int_offset2(_convert($polygons), $delta1, $delta2, $scale, $joinType, $miterLimit);
-    return map Slic3r::ExPolygon->new($_->{outer}, @{$_->{holes}}), @$offsets;
-}
-
 sub diff_ex {
     my ($subject, $clip, $safety_offset) = @_;
     
@@ -147,7 +127,7 @@ sub xor_ex {
 
 sub collapse_ex {
     my ($polygons, $width) = @_;
-    return [ offset2_ex($polygons, -$width/2, +$width/2) ];
+    return offset2_ex($polygons, -$width/2, +$width/2);
 }
 
 sub simplify_polygon {

+ 9 - 9
lib/Slic3r/Layer/Region.pm

@@ -5,7 +5,7 @@ use List::Util qw(sum first);
 use Slic3r::ExtrusionPath ':roles';
 use Slic3r::Geometry qw(PI A B scale chained_path_items points_coincide);
 use Slic3r::Geometry::Clipper qw(safety_offset union_ex diff_ex intersection_ex 
-    offset offset2 offset2_ex PFT_EVENODD union_pt traverse_pt diff intersection);
+    offset offset2 offset_ex offset2_ex PFT_EVENODD union_pt traverse_pt diff intersection);
 use Slic3r::Surface ':types';
 
 has 'layer' => (
@@ -141,7 +141,7 @@ sub _merge_loops {
             $expolygons = diff_ex([ map @$_, @$expolygons ], [$loop]);
         }
     }
-    $expolygons = [ map $_->offset_ex(-$safety_offset), @$expolygons ];
+    $expolygons = offset_ex([ map @$_, @$expolygons ], -$safety_offset);
     
     Slic3r::debugf "  %d surface(s) having %d holes detected from %d polylines\n",
         scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops);
@@ -180,7 +180,7 @@ sub make_perimeters {
                 ? $perimeter_spacing / 2
                 : $perimeter_spacing;
             
-            my @offsets = offset2_ex(\@last, -1.5*$spacing,  +0.5*$spacing);
+            my @offsets = @{offset2_ex(\@last, -1.5*$spacing,  +0.5*$spacing)};
             my @contours_offsets    = map $_->contour, @offsets;
             my @holes_offsets       = map $_->holes, @offsets;
             @offsets = (@contours_offsets, @holes_offsets);     # turn @offsets from ExPolygons to Polygons
@@ -209,11 +209,11 @@ sub make_perimeters {
         # non-collapsing regions
         # use a bogus surface_type
         $self->fill_surfaces->append(
-            map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_TOP), offset2_ex(
+            map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_TOP), @{offset2_ex(
                 [ map $_->simplify(&Slic3r::SCALED_RESOLUTION), @last ],
                 -($perimeter_spacing/2 + $infill_spacing),
                 +$infill_spacing,
-            )
+            )}
         );
     }
     
@@ -322,8 +322,8 @@ sub _fill_gaps {
         my $flow = $self->perimeter_flow->clone(width => $width);
         
         # extract the gaps having this width
-        my @this_width = map $_->offset_ex(+0.5*$flow->scaled_width),
-            map $_->noncollapsing_offset_ex(-0.5*$flow->scaled_width),
+        my @this_width = map @{$_->offset_ex(+0.5*$flow->scaled_width)},
+            map @{$_->noncollapsing_offset_ex(-0.5*$flow->scaled_width)},
             @$gaps;
         
         if (0) {  # remember to re-enable t/dynamic.t
@@ -346,7 +346,7 @@ sub _fill_gaps {
             # fill gaps using zigzag infill
             
             # since this is infill, we have to offset by half-extrusion width inwards
-            my @infill = map $_->offset_ex(-0.5*$flow->scaled_width), @this_width;
+            my @infill = map @{$_->offset_ex(-0.5*$flow->scaled_width)}, @this_width;
             
             foreach my $expolygon (@infill) {
                 my @paths = $filler->fill_surface(
@@ -520,7 +520,7 @@ sub _detect_bridges {
             }
         } elsif (@edges) {
             # inset the bridge expolygon; we'll use this one to clip our test lines
-            my $inset = [ $surface->expolygon->offset_ex($self->infill_flow->scaled_width) ];
+            my $inset = $surface->expolygon->offset_ex($self->infill_flow->scaled_width);
             
             # detect anchors as intersection between our bridge expolygon and the lower slices
             my $anchors = intersection_ex(

+ 3 - 3
lib/Slic3r/Print.pm

@@ -766,9 +766,9 @@ sub write_gcode {
             ]);
             # discard layers only containing thin walls (offset would fail on an empty polygon)
             if (@$convex_hull) {
-                my @island = Slic3r::ExPolygon->new($convex_hull)
-                    ->translate(scale $shift[X], scale $shift[Y])
-                    ->offset_ex(scale $distance_from_objects, 1, JT_SQUARE);
+                my $expolygon = Slic3r::ExPolygon->new($convex_hull);
+                $expolygon->translate(scale $shift[X], scale $shift[Y]);
+                my @island = @{$expolygon->offset_ex(scale $distance_from_objects, 1, JT_SQUARE)};
                 foreach my $copy (@{ $self->objects->[$obj_idx]->copies }) {
                     push @islands, map $_->clone->translate(@$copy), @island;
                 }

+ 5 - 5
lib/Slic3r/Print/Object.pm

@@ -488,9 +488,9 @@ sub clip_fill_surfaces {
                 my $overhang_width = $layerm->overhang_width;
                 # we want to support any solid surface, not just tops
                 # (internal solids might have been generated)
-                push @overhangs, map $_->offset_ex($additional_margin), @{intersection_ex(
+                push @overhangs, map @{$_->offset_ex($additional_margin)}, @{intersection_ex(
                     [ map @{$_->expolygon}, grep $_->surface_type != S_TYPE_INTERNAL, @{$layerm->fill_surfaces} ],
-                    [ map @$_, map $_->offset_ex(-$overhang_width), @{$lower_layer->slices} ],
+                    [ map @$_, map @{$_->offset_ex(-$overhang_width)}, @{$lower_layer->slices} ],
                 )};
             }
         }
@@ -825,7 +825,7 @@ sub generate_support_material {
             my $layer = $self->layers->[$i];
             my $lower_layer = $i > 0 ? $self->layers->[$i-1] : undef;
             
-            my @current_layer_offsetted_slices = map $_->offset_ex($distance_from_object), @{$layer->slices};
+            my @current_layer_offsetted_slices = map @{$_->offset_ex($distance_from_object)}, @{$layer->slices};
             
             # $upper_layers_overhangs[-1] contains the overhangs of the upper layer, regardless of any interface layers
             # $upper_layers_overhangs[0] contains the overhangs of the first upper layer above the interface layers
@@ -884,7 +884,7 @@ sub generate_support_material {
                         ? scale $lower_layer->height * ((cos $threshold_rad) / (sin $threshold_rad))
                         : $self->layers->[1]->regions->[0]->overhang_width;
                 
-                @overhangs = map $_->offset_ex(+$distance), @{diff_ex(
+                @overhangs = map @{$_->offset_ex(+$distance)}, @{diff_ex(
                     [ map @$_, @{$layer->slices} ],
                     [ map @$_, @{$lower_layer->slices} ],
                     1,
@@ -906,7 +906,7 @@ sub generate_support_material {
     my $support_interface_patterns = [];
     {
         # 0.5 ensures the paths don't get clipped externally when applying them to layers
-        my @areas = map $_->offset_ex(- 0.5 * $flow->scaled_width),
+        my @areas = map @{$_->offset_ex(- 0.5 * $flow->scaled_width)},
             @{union_ex([ map $_->contour, map @$_, values %layers, values %layers_interfaces, values %layers_contact_areas ])};
         
         my $pattern = $Slic3r::Config->support_material_pattern;

+ 1 - 1
lib/Slic3r/Surface.pm

@@ -35,7 +35,7 @@ sub group {
 
 sub offset {
     my $self = shift;
-    return map $self->clone(expolygon => $_), $self->expolygon->offset_ex(@_);
+    return map $self->clone(expolygon => $_), @{$self->expolygon->offset_ex(@_)};
 }
 
 sub simplify {

+ 1 - 1
t/dynamic.t

@@ -22,7 +22,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ }
         scale_points [0,0], [10,0], [10,10], [0,10],
     ]);
     
-    my @offsets = $square->noncollapsing_offset_ex(- scale 5);
+    my @offsets = @{$square->noncollapsing_offset_ex(- scale 5)};
     is scalar @offsets, 1, 'non-collapsing offset';
 }
 

Некоторые файлы не были показаны из-за большого количества измененных файлов