From a1e4bda670cab107f7c0bc80dc82a623c2e81a02 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 7 Jul 2013 15:17:09 +0200 Subject: [PATCH] Have Clipper.pm only return ExPolygon::XS objects --- lib/Slic3r/ExPolygon.pm | 5 ++++- lib/Slic3r/Fill/Honeycomb.pm | 4 ++-- lib/Slic3r/Fill/Rectilinear.pm | 4 ++-- lib/Slic3r/GCode.pm | 4 ++-- lib/Slic3r/Geometry/Clipper.pm | 16 +++++++++------- lib/Slic3r/Polyline.pm | 2 +- lib/Slic3r/Surface.pm | 2 +- xs/xsp/ExPolygon.xsp | 1 + 8 files changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 85a31faef..803bf20dc 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -32,6 +32,9 @@ sub clone { Storable::dclone($_[0]) } +# no-op for legacy with ::XS +sub arrayref { $_[0] } + sub threadsafe_clone { my $self = shift; return (ref $self)->new(map $_->threadsafe_clone, @$self); @@ -142,7 +145,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, [$line]); + return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self->arrayref, [$line]); } sub simplify { diff --git a/lib/Slic3r/Fill/Honeycomb.pm b/lib/Slic3r/Fill/Honeycomb.pm index fa25f5a67..714f82a59 100644 --- a/lib/Slic3r/Fill/Honeycomb.pm +++ b/lib/Slic3r/Fill/Honeycomb.pm @@ -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, + $surface->expolygon->arrayref, \@polygons, ) }; @@ -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( - [ $surface->expolygon->offset_ex(scaled_epsilon) ], + [ map $_->arrayref, $surface->expolygon->offset_ex(scaled_epsilon) ], [ @paths ], ) } if @paths; # this temporary check is a workaround for the multilinestring bug in B::G::U } diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index 08bbee21f..b78b2a306 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -17,7 +17,7 @@ sub fill_surface { $self->rotate_points($expolygon, $rotate_vector); my ($expolygon_off) = $expolygon->offset_ex(scale $params{flow_spacing}/2); - return {} if !$expolygon_off; # skip some very small polygons (which shouldn't arrive here) + return {} if !defined $expolygon_off; # skip some very small polygons (which shouldn't arrive here) my $flow_spacing = $params{flow_spacing}; my $min_spacing = scale $params{flow_spacing}; @@ -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], # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object + +($expolygon->offset_ex(scaled_epsilon))[0]->arrayref, # TODO: we should use all the resulting expolygons and clip the linestrings to a multipolygon object [ @{ $self->cache->{$cache_id} } ], ) }; diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index d4e498a9f..1f4edde1d 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -98,7 +98,7 @@ sub change_layer { $self->layer($layer); $self->_layer_overhangs( $layer->id > 0 - ? [ map $_->expolygon, grep $_->surface_type == S_TYPE_BOTTOM, map @{$_->slices}, @{$layer->regions} ] + ? [ map $_->expolygon->arrayref, grep $_->surface_type == S_TYPE_BOTTOM, map @{$_->slices}, @{$layer->regions} ] : [] ); if ($self->config->avoid_crossing_perimeters) { @@ -348,7 +348,7 @@ sub travel_to { $travel->translate(-$self->shift_x, -$self->shift_y); if ($travel->length < scale $self->extruder->retract_before_travel - || ($self->config->only_retract_when_crossing_perimeters && first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->upper_layer_slices}) + || ($self->config->only_retract_when_crossing_perimeters && defined first { $_->encloses_line($travel, scaled_epsilon) } @{$self->layer->upper_layer_slices}) || ($role == EXTR_ROLE_SUPPORTMATERIAL && $self->layer->support_islands_enclose_line($travel)) ) { $self->straight_once(0); diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index aa124ba87..142acbd0e 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -20,7 +20,7 @@ sub safety_offset { sub safety_offset_ex { my ($polygons, $factor) = @_; - return map Slic3r::ExPolygon->new($_), + return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @{Math::Clipper::ex_int_offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2)}; } @@ -30,6 +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); return @$offsets; } @@ -50,8 +51,9 @@ 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); - return map Slic3r::ExPolygon->new($_), @$offsets; + return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @$offsets; } sub offset2_ex { @@ -61,7 +63,7 @@ sub offset2_ex { $miterLimit //= 3; my $offsets = Math::Clipper::ex_int_offset2($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit); - return map Slic3r::ExPolygon->new($_), @$offsets; + return map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @$offsets; } sub diff_ex { @@ -71,7 +73,7 @@ sub diff_ex { $clipper->add_subject_polygons($subject); $clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip); return [ - map Slic3r::ExPolygon->new($_), + map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @{ $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO) }, ]; } @@ -94,7 +96,7 @@ sub union_ex { $clipper->clear; $clipper->add_subject_polygons($safety_offset ? safety_offset($polygons) : $polygons); return [ - map Slic3r::ExPolygon->new($_), + map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @{ $clipper->ex_execute(CT_UNION, $jointype, $jointype) }, ]; } @@ -114,7 +116,7 @@ sub intersection_ex { $clipper->add_subject_polygons($subject); $clipper->add_clip_polygons($safety_offset ? safety_offset($clip) : $clip); return [ - map Slic3r::ExPolygon->new($_), + map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @{ $clipper->ex_execute(CT_INTERSECTION, $jointype, $jointype) }, ]; } @@ -138,7 +140,7 @@ sub xor_ex { $clipper->add_subject_polygons($subject); $clipper->add_clip_polygons($clip); return [ - map Slic3r::ExPolygon->new($_), + map Slic3r::ExPolygon::XS->new($_->{outer}, @{$_->{holes}}), @{ $clipper->ex_execute(CT_XOR, $jointype, $jointype) }, ]; } diff --git a/lib/Slic3r/Polyline.pm b/lib/Slic3r/Polyline.pm index fd4bd571f..d63451a08 100644 --- a/lib/Slic3r/Polyline.pm +++ b/lib/Slic3r/Polyline.pm @@ -115,7 +115,7 @@ sub clip_with_expolygon { my $self = shift; my ($expolygon) = @_; - my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon, [$self]); + my $result = Boost::Geometry::Utils::polygon_multi_linestring_intersection($expolygon->arrayref, [$self]); bless $_, 'Slic3r::Polyline' for @$result; bless $_, 'Slic3r::Point' for map @$_, @$result; return @$result; diff --git a/lib/Slic3r/Surface.pm b/lib/Slic3r/Surface.pm index 06c887de3..7db4cfd27 100644 --- a/lib/Slic3r/Surface.pm +++ b/lib/Slic3r/Surface.pm @@ -40,7 +40,7 @@ sub clone { return (ref $self)->new( (map { $_ => $self->$_ } qw(surface_type thickness thickness_layers bridge_angle)), - expolygon => ($p{expolygon} ? delete $p{expolygon} : $self->expolygon->clone), + expolygon => (defined $p{expolygon} ? delete $p{expolygon} : $self->expolygon->clone), %p, ); } diff --git a/xs/xsp/ExPolygon.xsp b/xs/xsp/ExPolygon.xsp index 4da73c55f..e4281046e 100644 --- a/xs/xsp/ExPolygon.xsp +++ b/xs/xsp/ExPolygon.xsp @@ -6,6 +6,7 @@ %} %name{Slic3r::ExPolygon::XS} class ExPolygon { + %name{_clone} ExPolygon(ExPolygon& self); %{ ExPolygon*