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

This commit is contained in:
Alessandro Ranellucci 2013-11-21 16:21:42 +01:00
parent a225a8b2ef
commit 5f81292f3f
22 changed files with 81 additions and 76 deletions

View file

@ -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]];
}

View file

@ -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)}) {

View file

@ -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 = ();

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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(@_);

View file

@ -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;

View file

@ -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 }