Use XS Point everywhere

This commit is contained in:
Alessandro Ranellucci 2013-07-15 20:31:43 +02:00
parent d0701cdcd4
commit 9af2a1c007
37 changed files with 238 additions and 303 deletions

View file

@ -34,6 +34,7 @@ sub clone {
# no-op for legacy with ::XS
sub arrayref { $_[0] }
sub arrayref_pp { [ map $_->arrayref_pp, @{$_[0]} ] }
sub contour {
my $self = shift;
@ -107,7 +108,7 @@ sub noncollapsing_offset_ex {
sub encloses_point {
my $self = shift;
my ($point) = @_;
return Boost::Geometry::Utils::point_covered_by_polygon($point, $self);
return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, $self->arrayref_pp);
}
# A version of encloses_point for use when hole borders do not matter.
@ -116,7 +117,7 @@ sub encloses_point {
sub encloses_point_quick {
my $self = shift;
my ($point) = @_;
return Boost::Geometry::Utils::point_within_polygon($point, $self->arrayref);
return Boost::Geometry::Utils::point_within_polygon($point->arrayref, $self->arrayref);
}
sub encloses_line {
@ -140,7 +141,7 @@ sub clip_line {
my $self = shift;
my ($line) = @_; # line must be a Slic3r::Line object
return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self->arrayref, [$line]);
return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self->arrayref_pp, [$line->arrayref_pp]);
}
sub simplify {
@ -149,7 +150,7 @@ sub simplify {
# it would be nice to have a multilinestring_simplify method in B::G::U
my @simplified = Slic3r::Geometry::Clipper::simplify_polygons(
[ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @$self ],
[ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @{$self->arrayref_pp} ],
);
return @{ Slic3r::Geometry::Clipper::union_ex([ @simplified ]) };
}

View file

@ -207,7 +207,7 @@ sub detect_arcs {
my $rotation_angle = PI/2 * ($orientation eq 'ccw' ? -1 : 1);
my $ray1 = Slic3r::Line->new($s1_mid, rotate_points($rotation_angle, $s1_mid, $points[$i+1]));
my $last_ray = Slic3r::Line->new($last_mid, rotate_points($rotation_angle, $last_mid, $points[$last_j]));
$arc_center = $ray1->intersection($last_ray, 0) or next POINT;
$arc_center = $ray1->intersection($last_ray, 0) // next POINT;
}
my $arc = Slic3r::ExtrusionPath::Arc->new(

View file

@ -90,7 +90,7 @@ sub fill_surface {
# path is more straight
@paths = map Slic3r::Polyline->new(@$_),
@{ Boost::Geometry::Utils::polygon_multi_linestring_intersection(
$surface->expolygon->arrayref,
$surface->expolygon->arrayref_pp,
\@polygons,
) };

View file

@ -66,7 +66,7 @@ sub fill_surface {
# clip paths against a slightly offsetted expolygon, so that the first and last paths
# are kept even if the expolygon has vertical sides
my @paths = @{ Boost::Geometry::Utils::polygon_multi_linestring_intersection(
+($expolygon->offset_ex(scaled_epsilon))[0]->arrayref, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object
+($expolygon->offset_ex(scaled_epsilon))[0]->arrayref_pp, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object
[ @{ $self->cache->{$cache_id} } ],
) };
@ -92,7 +92,7 @@ sub fill_surface {
# TODO: we should also check that both points are on a fill_boundary to avoid
# connecting paths on the boundaries of internal regions
if ($can_connect->(@distance, $paths[-1][-1], $path->[0])
if ($can_connect->(@distance)
&& $expolygon_off->encloses_line(Slic3r::Line->new($paths[-1][-1], $path->[0]), $tolerance)) {
push @{$paths[-1]}, @$path;
next;

View file

@ -242,7 +242,7 @@ sub extrude_loop {
my $first_segment = Slic3r::Line->new(@{$extrusion_path->polyline}[0,1]);
my $distance = min(scale $extrusion_path->flow_spacing, $first_segment->length);
my $point = Slic3r::Geometry::point_along_segment(@$first_segment, $distance);
bless $point, 'Slic3r::Point';
$point = Slic3r::Point->new(@$point);
$point->rotate($angle, $extrusion_path->polyline->[0]);
# generate the travel move
@ -558,7 +558,7 @@ sub _G0_G1 {
my ($gcode, $point, $z, $e, $comment) = @_;
my $dec = $self->dec;
if ($point) {
if (defined $point) {
$gcode .= sprintf " X%.${dec}f Y%.${dec}f",
($point->x * &Slic3r::SCALING_FACTOR) + $self->shift_x - $self->extruder->extruder_offset->[X],
($point->y * &Slic3r::SCALING_FACTOR) + $self->shift_y - $self->extruder->extruder_offset->[Y]; #**

View file

@ -891,7 +891,7 @@ sub repaint {
# if sequential printing is enabled and we have more than one object
if ($parent->{config}->complete_objects && (map @{$_->instances}, @{$parent->{objects}}) > 1) {
my $convex_hull = Slic3r::Polygon->new(@{convex_hull([ map @{$_->contour}, @{$parent->{object_previews}->[-1][2]} ])});
my $convex_hull = Slic3r::Polygon->new(@{convex_hull([ map @{$_->contour->arrayref_pp}, @{$parent->{object_previews}->[-1][2]} ])});
my ($clearance) = @{offset([$convex_hull], $parent->{config}->extruder_clearance_radius / 2 * $parent->{scaling_factor}, 100, JT_ROUND)};
$dc->SetPen($parent->{clearance_pen});
$dc->SetBrush($parent->{transparent_brush});
@ -1198,7 +1198,7 @@ sub _apply_transform {
# the order of these transformations MUST be the same everywhere, including
# in Slic3r::Print->add_model()
my $result = $entity->clone;
$result->rotate(deg2rad($self->rotate), Slic3r::Point::XS->new(@{$self->bounding_box->center_2D}));
$result->rotate(deg2rad($self->rotate), $self->bounding_box->center_2D);
$result->scale($self->scale);
return $result;
}

View file

@ -504,7 +504,7 @@ sub polygon_points_visibility {
my $our_line = [ $p1, $p2 ];
foreach my $line (polygon_lines($polygon)) {
my $intersection = line_intersection($our_line, $line, 1) or next;
my $intersection = line_intersection($our_line, $line, 1) // next;
next if grep points_coincide($intersection, $_), $p1, $p2;
return 0;
}

View file

@ -15,13 +15,13 @@ our $clipper = Math::Clipper->new;
sub safety_offset {
my ($polygons, $factor) = @_;
return Math::Clipper::int_offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2);
return Math::Clipper::int_offset(_convert($polygons), $factor // (scale 1e-05), 100000, JT_MITER, 2);
}
sub safety_offset_ex {
my ($polygons, $factor) = @_;
return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}),
@{Math::Clipper::ex_int_offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2)};
@{Math::Clipper::ex_int_offset(_convert($polygons), $factor // (scale 1e-05), 100000, JT_MITER, 2)};
}
sub offset {
@ -30,8 +30,7 @@ sub offset {
$joinType //= JT_MITER;
$miterLimit //= 3;
$polygons = $polygons->arrayref if ref $polygons eq 'Slic3r::ExPolygon::XS';
my $offsets = Math::Clipper::int_offset($polygons, $distance, $scale, $joinType, $miterLimit);
my $offsets = Math::Clipper::int_offset(_convert($polygons), $distance, $scale, $joinType, $miterLimit);
return @$offsets;
}
@ -41,7 +40,7 @@ sub offset2 {
$joinType //= JT_MITER;
$miterLimit //= 3;
my $offsets = Math::Clipper::int_offset2($polygons, $distance1, $distance2, $scale, $joinType, $miterLimit);
my $offsets = Math::Clipper::int_offset2(_convert($polygons), $distance1, $distance2, $scale, $joinType, $miterLimit);
return @$offsets;
}
@ -51,8 +50,7 @@ sub offset_ex {
$joinType //= JT_MITER;
$miterLimit //= 3;
$polygons = $polygons->arrayref if ref $polygons eq 'Slic3r::ExPolygon::XS';
my $offsets = Math::Clipper::ex_int_offset($polygons, $distance, $scale, $joinType, $miterLimit);
my $offsets = Math::Clipper::ex_int_offset(_convert($polygons), $distance, $scale, $joinType, $miterLimit);
return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @$offsets;
}
@ -62,7 +60,7 @@ sub offset2_ex {
$joinType //= JT_MITER;
$miterLimit //= 3;
my $offsets = Math::Clipper::ex_int_offset2($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit);
my $offsets = Math::Clipper::ex_int_offset2(_convert($polygons), $delta1, $delta2, $scale, $joinType, $miterLimit);
return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @$offsets;
}
@ -70,8 +68,8 @@ sub diff_ex {
my ($subject, $clip, $safety_offset) = @_;
$clipper->clear;
$clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip);
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons($safety_offset ? safety_offset(_convert($clip)) : _convert($clip));
return [
map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO) },
@ -82,8 +80,8 @@ sub diff {
my ($subject, $clip, $safety_offset) = @_;
$clipper->clear;
$clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip);
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons($safety_offset ? safety_offset(_convert($clip)) : _convert($clip));
return [
map Slic3r::Polygon->new(@$_),
@{ $clipper->execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO) },
@ -95,7 +93,7 @@ sub union_ex {
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$polygons = $polygons->arrayref if ref $polygons eq 'Slic3r::ExPolygon::XS';
$clipper->add_subject_polygons($safety_offset ? safety_offset($polygons) : $polygons);
$clipper->add_subject_polygons($safety_offset ? safety_offset(_convert($polygons)) : _convert($polygons));
return [
map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_UNION, $jointype, $jointype) },
@ -106,7 +104,7 @@ sub union_pt {
my ($polygons, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons($safety_offset ? safety_offset($polygons) : $polygons);
$clipper->add_subject_polygons($safety_offset ? safety_offset(_convert($polygons)) : _convert($polygons));
return $clipper->pt_execute(CT_UNION, $jointype, $jointype);
}
@ -114,8 +112,8 @@ sub intersection_ex {
my ($subject, $clip, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip);
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons($safety_offset ? safety_offset(_convert($clip)) : _convert($clip));
return [
map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_INTERSECTION, $jointype, $jointype) },
@ -126,8 +124,8 @@ sub intersection {
my ($subject, $clip, $jointype, $safety_offset) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip);
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons($safety_offset ? safety_offset(_convert($clip)) : _convert($clip));
return [
map Slic3r::Polygon->new(@$_),
@{ $clipper->execute(CT_INTERSECTION, $jointype, $jointype) },
@ -138,8 +136,8 @@ sub xor_ex {
my ($subject, $clip, $jointype) = @_;
$jointype = PFT_NONZERO unless defined $jointype;
$clipper->clear;
$clipper->add_subject_polygons($subject);
$clipper->add_clip_polygons($clip);
$clipper->add_subject_polygons(_convert($subject));
$clipper->add_clip_polygons(_convert($clip));
return [
map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}),
@{ $clipper->ex_execute(CT_XOR, $jointype, $jointype) },
@ -153,12 +151,12 @@ sub collapse_ex {
sub simplify_polygon {
my ($polygon, $pft) = @_;
return @{ Math::Clipper::simplify_polygon($polygon, $pft // PFT_NONZERO) };
return @{ Math::Clipper::simplify_polygon(_convert([$polygon])->[0], $pft // PFT_NONZERO) };
}
sub simplify_polygons {
my ($polygons, $pft) = @_;
return @{ Math::Clipper::simplify_polygons($polygons, $pft // PFT_NONZERO) };
return @{ Math::Clipper::simplify_polygons(_convert($polygons), $pft // PFT_NONZERO) };
}
sub traverse_pt {
@ -179,4 +177,11 @@ sub traverse_pt {
return @polygons;
}
sub _convert {
my $polygons = shift;
$polygons = $polygons->arrayref_pp if ref $polygons eq 'Slic3r::ExPolygon::XS';
$polygons = [ map $_->arrayref_pp, @$polygons ] if @$polygons && ref $polygons->[0] eq 'Slic3r::Polygon';
return $polygons;
}
1;

View file

@ -2,67 +2,10 @@ package Slic3r::Point;
use strict;
use warnings;
use Storable qw();
sub new {
my $class = shift;
my $self;
if (@_ == 2) {
$self = [@_];
} elsif ((ref $_[0]) =~ 'ARRAY' || (ref $_[0]) =~ /Slic3r::Point/) {
$self = [@{$_[0]}];
} elsif ($_[0]->isa(__PACKAGE__)) {
return $_[0];
} else {
die "Invalid arguments for ${class}->new";
}
bless $self, $class;
return $self;
}
sub clone {
return Slic3r::Point::XS->new(@{$_[0]});
}
sub threadsafe_clone {
my $self = shift;
return (ref $self)->new(@$self);
}
sub coincides_with {
my $self = shift;
my ($point) = @_;
return Slic3r::Geometry::points_coincide($self, $point);
}
sub distance_to {
my $self = shift;
my ($point) = @_;
return Slic3r::Geometry::distance_between_points($self, $point);
}
sub scale {
my $self = shift;
my ($factor) = @_;
$_ *= $factor for @$self;
$self;
}
sub rotate {
my $self = shift;
my ($angle, $center) = @_;
@$self = @{ +(Slic3r::Geometry::rotate_points($angle, $center, $self))[0] };
$self;
}
sub translate {
my $self = shift;
my ($x, $y) = @_;
@$self = @{ +(Slic3r::Geometry::move_points([$x, $y], $self))[0] };
$self;
}
sub x { $_[0]->[0] }
sub y { $_[0]->[1] }
1;

View file

@ -10,8 +10,6 @@ use Slic3r::Geometry qw(polygon_lines polygon_remove_parallel_continuous_edges
PI X1 X2 Y1 Y2 epsilon);
use Slic3r::Geometry::Clipper qw(JT_MITER);
sub arrayref { $_[0] }
sub lines {
my $self = shift;
return polygon_lines($self);
@ -24,7 +22,7 @@ sub wkt {
sub is_counter_clockwise {
my $self = shift;
return Slic3r::Geometry::Clipper::is_counter_clockwise($self->arrayref);
return Slic3r::Geometry::Clipper::is_counter_clockwise($self->arrayref_pp);
}
sub make_counter_clockwise {
@ -49,24 +47,22 @@ sub merge_continuous_lines {
my $self = shift;
polygon_remove_parallel_continuous_edges($self);
bless $_, 'Slic3r::Point' for @$self;
}
sub remove_acute_vertices {
my $self = shift;
polygon_remove_acute_vertices($self);
bless $_, 'Slic3r::Point' for @$self;
}
sub encloses_point {
my $self = shift;
my ($point) = @_;
return Boost::Geometry::Utils::point_covered_by_polygon($point, [$self]);
return Boost::Geometry::Utils::point_covered_by_polygon($point->arrayref, [$self->arrayref_pp]);
}
sub area {
my $self = shift;
return Slic3r::Geometry::Clipper::area($self);
return Slic3r::Geometry::Clipper::area($self->arrayref_pp);
}
sub grow {

View file

@ -12,19 +12,25 @@ use Storable qw();
sub new {
my $class = shift;
my $self = [ @_ ];
my $self = [ map { ref($_) eq 'Slic3r::Point' ? $_ : Slic3r::Point->new(@$_) } @_ ];
bless $self, $class;
bless $_, 'Slic3r::Point' for @$self;
$self;
}
sub arrayref { $_[0] }
sub arrayref_pp {
my $self = shift;
if (ref($self->[0]) eq 'Slic3r::Point') {
return [ map $_->arrayref, @$self ];
} else {
return $self;
}
}
sub clone {
Storable::dclone($_[0])
}
# compability with ::XS
sub arrayref { $_[0] }
sub serialize {
my $self = shift;
return pack 'l*', map @$_, @$self;
@ -62,7 +68,7 @@ sub simplify {
my $self = shift;
my $tolerance = shift || 10;
my $simplified = Boost::Geometry::Utils::linestring_simplify($self->arrayref, $tolerance);
my $simplified = Boost::Geometry::Utils::linestring_simplify($self->arrayref_pp, $tolerance);
return (ref $self)->new(@$simplified);
}
@ -73,7 +79,7 @@ sub reverse {
sub length {
my $self = shift;
return Boost::Geometry::Utils::linestring_length($self->arrayref);
return Boost::Geometry::Utils::linestring_length($self->arrayref_pp);
}
sub grow {
@ -113,9 +119,8 @@ sub clip_with_expolygon {
my $self = shift;
my ($expolygon) = @_;
my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon->arrayref, [$self->arrayref]);
my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon->arrayref_pp, [$self->arrayref_pp]);
bless $_, 'Slic3r::Polyline' for @$result;
bless $_, 'Slic3r::Point' for map @$_, @$result;
return @$result;
}
@ -138,29 +143,21 @@ sub align_to_origin {
sub rotate {
my $self = shift;
my ($angle, $center) = @_;
@$self = Slic3r::Geometry::rotate_points($angle, $center, @$self);
bless $_, 'Slic3r::Point' for @$self;
$_->rotate($angle, $center) for @$self;
return $self;
}
sub translate {
my $self = shift;
my ($x, $y) = @_;
@$self = Slic3r::Geometry::move_points([$x, $y], @$self);
bless $_, 'Slic3r::Point' for @$self;
$_->translate($x, $y) for @$self;
return $self;
}
sub scale {
my $self = shift;
my ($factor) = @_;
# transform point coordinates
if ($factor != 1) {
foreach my $point (@$self) {
$point->[$_] *= $factor for X,Y;
}
}
$_->scale($factor) for @$self;
return $self;
}

View file

@ -594,7 +594,7 @@ sub make_skirt {
return if @points < 3; # at least three points required for a convex hull
# find out convex hull
my $convex_hull = convex_hull(\@points);
my $convex_hull = convex_hull([ map $_->arrayref, @points ]);
my @extruded_length = (); # for each extruder
@ -763,7 +763,7 @@ sub write_gcode {
my @islands = ();
foreach my $obj_idx (0 .. $#{$self->objects}) {
my $convex_hull = convex_hull([
map @{$_->contour}, map @{$_->slices}, @{$self->objects->[$obj_idx]->layers},
map @{$_->contour->arrayref_pp}, map @{$_->slices}, @{$self->objects->[$obj_idx]->layers},
]);
# discard layers only containing thin walls (offset would fail on an empty polygon)
if (@$convex_hull) {