Browse Source

Ported encloses_point() to XS and renamed to contains_point()

Alessandro Ranellucci 11 years ago
parent
commit
5f81292f3f

+ 7 - 27
lib/Slic3r/ExPolygon.pm

@@ -39,36 +39,11 @@ sub noncollapsing_offset_ex {
     return $self->offset_ex($distance + 1, @params);
 }
 
-sub encloses_point {
-    my $self = shift;
-    my ($point) = @_;
-    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.
-# Useful because point_on_segment is probably slower (this was true
-# before the switch to Boost.Geometry, not sure about now)
-sub encloses_point_quick {
-    my $self = shift;
-    my ($point) = @_;
-    return Boost::Geometry::Utils::point_within_polygon($point->pp, $self->pp);
-}
-
 sub bounding_box {
     my $self = shift;
     return $self->contour->bounding_box;
 }
 
-sub clip_line {
-    my $self = shift;
-    my ($line) = @_;  # line must be a Slic3r::Line object
-    
-    return [
-        map Slic3r::Line->new(@$_),
-            @{Slic3r::Geometry::Clipper::intersection_pl([ $line->as_polyline ], \@$self)}
-    ];
-}
-
 sub simplify_as_polygons {
     my $self = shift;
     my ($tolerance) = @_;
@@ -192,8 +167,13 @@ sub _medial_axis_voronoi {
         # ignore lines going to infinite
         next if $edge->[1] == -1 || $edge->[2] == -1;
         
-        next if !$self->encloses_point_quick(Slic3r::Point->new(@{$vertices->[$edge->[1]]}))
-             || !$self->encloses_point_quick(Slic3r::Point->new(@{$vertices->[$edge->[2]]}));
+        my $line = Slic3r::Line->new($vertices->[$edge->[1]], $vertices->[$edge->[2]]);
+        next if !$self->contains_line($line);
+        
+        # contains_point() could be faster, but we need an implementation that
+        # reliably considers points on boundary
+        #next if !$self->contains_point(Slic3r::Point->new(@{$vertices->[$edge->[1]]}))
+        #     || !$self->contains_point(Slic3r::Point->new(@{$vertices->[$edge->[2]]}));
         
         push @skeleton_lines, [$edge->[1], $edge->[2]];
     }

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

@@ -94,7 +94,7 @@ sub fill_surface {
         )};
         
         # connect paths
-        {
+        if (@paths) {  # prevent calling leftmost_point() on empty collections
             my $collection = Slic3r::Polyline::Collection->new(@paths);
             @paths = ();
             foreach my $path (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {

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

@@ -61,7 +61,7 @@ sub fill_surface {
     my @polylines = @{intersection_pl(\@vertical_lines, $expolygon->offset($line_spacing*0.05))};
     
     # connect lines
-    unless ($params{dont_connect}) {
+    unless ($params{dont_connect} || !@polylines) {  # prevent calling leftmost_point() on empty collections
         my ($expolygon_off) = @{$expolygon->offset_ex(scale $params{flow_spacing}/2)};
         my $collection = Slic3r::Polyline::Collection->new(@polylines);
         @polylines = ();

+ 2 - 2
lib/Slic3r/GCode/Layer.pm

@@ -139,7 +139,7 @@ sub process_layer {
                     for 1 .. (@{$layer->slices} || 1);  # make sure we have at least one island hash to avoid failure of the -1 subscript below
                 PERIMETER: foreach my $perimeter (@{$layerm->perimeters}) {
                     for my $i (0 .. $#{$layer->slices}-1) {
-                        if ($layer->slices->[$i]->contour->encloses_point($perimeter->first_point)) {
+                        if ($layer->slices->[$i]->contour->contains_point($perimeter->first_point)) {
                             push @{ $islands[$i]{perimeters} }, $perimeter;
                             next PERIMETER;
                         }
@@ -148,7 +148,7 @@ sub process_layer {
                 }
                 FILL: foreach my $fill (@{$layerm->fills}) {
                     for my $i (0 .. $#{$layer->slices}-1) {
-                        if ($layer->slices->[$i]->contour->encloses_point($fill->first_point)) {
+                        if ($layer->slices->[$i]->contour->contains_point($fill->first_point)) {
                             push @{ $islands[$i]{fills} }, $fill;
                             next FILL;
                         }

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

@@ -192,13 +192,13 @@ sub find_node {
     
     # if we're inside a hole, move to a point on hole;
     {
-        my $polygon = first { $_->encloses_point($point) } (map @{$_->holes}, map @$_, @{$self->_inner});
+        my $polygon = first { $_->contains_point($point) } (map @{$_->holes}, map @$_, @{$self->_inner});
         return $point->nearest_point([ @$polygon ]) if $polygon;
     }
     
     # if we're inside an expolygon move to a point on contour or holes
     {
-        my $expolygon = first { $_->encloses_point_quick($point) } (map @$_, @{$self->_inner});
+        my $expolygon = first { $_->contains_point($point) } (map @$_, @{$self->_inner});
         return $point->nearest_point([ map @$_, @$expolygon ]) if $expolygon;
     }
     
@@ -206,11 +206,11 @@ sub find_node {
         my $outer_polygon_idx;
         if (!$self->no_internal) {
             # look for an outer expolygon whose contour contains our point
-            $outer_polygon_idx = first { first { $_->contour->encloses_point($point) } @{$self->_contours_ex->[$_]} }
+            $outer_polygon_idx = first { first { $_->contour->contains_point($point) } @{$self->_contours_ex->[$_]} }
                 0 .. $#{ $self->_contours_ex };
         } else {
             # # look for an outer expolygon containing our point
-            $outer_polygon_idx = first { first { $_->encloses_point($point) } @{$self->_outer->[$_]} }
+            $outer_polygon_idx = first { first { $_->contains_point($point) } @{$self->_outer->[$_]} }
                 0 .. $#{ $self->_outer };
         }
         my $candidates = defined $outer_polygon_idx

+ 2 - 2
lib/Slic3r/GUI/Plater.pm

@@ -1024,7 +1024,7 @@ sub mouse_event {
         $parent->selection_changed(0);
         for my $preview (@{$parent->{object_previews}}) {
             my ($obj_idx, $instance_idx, $thumbnail) = @$preview;
-            if (defined first { $_->contour->encloses_point($pos) } @$thumbnail) {
+            if (defined first { $_->contour->contains_point($pos) } @$thumbnail) {
                 $parent->{selected_objects} = [ [$obj_idx, $instance_idx] ];
                 $parent->{list}->Select($obj_idx, 1);
                 $parent->selection_changed(1);
@@ -1053,7 +1053,7 @@ sub mouse_event {
     } elsif ($event->Moving) {
         my $cursor = wxSTANDARD_CURSOR;
         for my $preview (@{$parent->{object_previews}}) {
-            if (defined first { $_->contour->encloses_point($pos) } @{ $preview->[2] }) {
+            if (defined first { $_->contour->contains_point($pos) } @{ $preview->[2] }) {
                 $cursor = Wx::Cursor->new(wxCURSOR_HAND);
                 last;
             }

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

@@ -114,7 +114,7 @@ sub _merge_loops {
     # supply everything to offset_ex() instead of performing several union/diff calls.
     
     # we sort by area assuming that the outermost loops have larger area;
-    # the previous sorting method, based on $b->encloses_point($a->[0]), failed to nest
+    # the previous sorting method, based on $b->contains_point($a->[0]), failed to nest
     # loops correctly in some edge cases when original model had overlapping facets
     my @abs_area = map abs($_), my @area = map $_->area, @$loops;
     my @sorted = sort { $abs_area[$b] <=> $abs_area[$a] } 0..$#$loops;  # outer first
@@ -568,10 +568,12 @@ sub _detect_bridge_direction {
             my @clipped_lines = map Slic3r::Line->new(@$_), @{ intersection_pl(\@lines, [ map @$_, @$inset ]) };
             
             # remove any line not having both endpoints within anchors
+            # NOTE: these calls to contains_point() probably need to check whether the point 
+            # is on the anchor boundaries too
             @clipped_lines = grep {
                 my $line = $_;
-                !(first { $_->encloses_point_quick($line->a) } @$anchors)
-                    && !(first { $_->encloses_point_quick($line->b) } @$anchors);
+                !(first { $_->contains_point($line->a) } @$anchors)
+                    && !(first { $_->contains_point($line->b) } @$anchors);
             } @clipped_lines;
             
             # sum length of bridged lines

+ 0 - 6
lib/Slic3r/Polygon.pm

@@ -27,12 +27,6 @@ sub remove_acute_vertices {
     polygon_remove_acute_vertices($self);
 }
 
-sub encloses_point {
-    my $self = shift;
-    my ($point) = @_;
-    return Boost::Geometry::Utils::point_covered_by_polygon($point->pp, [$self->pp]);
-}
-
 sub grow {
     my $self = shift;
     return $self->split_at_first_point->grow(@_);

+ 1 - 1
lib/Slic3r/Print.pm

@@ -527,7 +527,7 @@ EOF
             my $layer = $self->objects->[$obj_idx]->layers->[$layer_id] or next;
             
             # sort slices so that the outermost ones come first
-            my @slices = sort { $a->contour->encloses_point($b->contour->[0]) ? 0 : 1 } @{$layer->slices};
+            my @slices = sort { $a->contour->contains_point($b->contour->first_point) ? 0 : 1 } @{$layer->slices};
             foreach my $copy (@{$self->objects->[$obj_idx]->copies}) {
                 foreach my $slice (@slices) {
                     my $expolygon = $slice->clone;

+ 1 - 1
lib/Slic3r/Surface.pm

@@ -8,7 +8,7 @@ our @EXPORT_OK   = qw(S_TYPE_TOP S_TYPE_BOTTOM S_TYPE_INTERNAL S_TYPE_INTERNALSO
 our %EXPORT_TAGS = (types => \@EXPORT_OK);
 
 # delegate handles
-sub encloses_point  { $_[0]->expolygon->encloses_point }
+sub contains_point  { $_[0]->expolygon->contains_point }
 sub lines           { $_[0]->expolygon->lines }
 sub contour         { $_[0]->expolygon->contour }
 sub holes           { $_[0]->expolygon->holes }

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