From e29aca35539ee7a85eb02b95e22a07f0834ec5fc Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 20 Jul 2013 12:22:41 +0200 Subject: [PATCH] Reapply correct optimization for simplifiying fill_surfaces before performing the offset. #1325 --- lib/Slic3r/ExPolygon.pm | 12 +++++++++--- lib/Slic3r/Geometry/Clipper.pm | 6 ++++-- lib/Slic3r/Layer/Region.pm | 11 +++++------ lib/Slic3r/Polygon.pm | 2 ++ t/clean_polylines.t | 21 ++++++++++++++++++++- 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index c58af979..610751a6 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -145,15 +145,21 @@ sub clip_line { return Boost::Geometry::Utils::polygon_multi_linestring_intersection($self, [$line]); } -sub simplify { +sub simplify_as_polygons { my $self = shift; my ($tolerance) = @_; # it would be nice to have a multilinestring_simplify method in B::G::U - my @simplified = Slic3r::Geometry::Clipper::simplify_polygons( + return Slic3r::Geometry::Clipper::simplify_polygons( [ map Boost::Geometry::Utils::linestring_simplify($_, $tolerance), @$self ], ); - return @{ Slic3r::Geometry::Clipper::union_ex([ @simplified ]) }; +} + +sub simplify { + my $self = shift; + my ($tolerance) = @_; + + return @{ Slic3r::Geometry::Clipper::union_ex([ $self->simplify_as_polygons($tolerance) ]) }; } sub scale { diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index aa124ba8..35d13c87 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -150,12 +150,14 @@ sub collapse_ex { sub simplify_polygon { my ($polygon, $pft) = @_; - return @{ Math::Clipper::simplify_polygon($polygon, $pft // PFT_NONZERO) }; + return map Slic3r::Polygon->new(@$_), + @{ Math::Clipper::simplify_polygon($polygon, $pft // PFT_NONZERO) }; } sub simplify_polygons { my ($polygons, $pft) = @_; - return @{ Math::Clipper::simplify_polygons($polygons, $pft // PFT_NONZERO) }; + return map Slic3r::Polygon->new(@$_), + @{ Math::Clipper::simplify_polygons($polygons, $pft // PFT_NONZERO) }; } sub traverse_pt { diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 6d1d4745..4441215d 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -209,12 +209,11 @@ sub make_perimeters { # and then we offset back and forth by the infill spacing to only consider the # non-collapsing regions push @{ $self->fill_surfaces }, - map $_->simplify(&Slic3r::SCALED_RESOLUTION), - offset2_ex( - \@last, - -($perimeter_spacing/2 + $infill_spacing), - +$infill_spacing, - ); + offset2_ex( + [ map $_->simplify_as_polygons(&Slic3r::SCALED_RESOLUTION), @{union_ex(\@last)} ], + -($perimeter_spacing/2 + $infill_spacing), + +$infill_spacing, + ); } $self->_fill_gaps(\@gaps); diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index f743ac54..8b4fc745 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -72,6 +72,8 @@ sub grow { return $self->split_at_first_point->grow(@_); } +# NOTE that this will turn the polygon to ccw regardless of its +# original orientation sub simplify { my $self = shift; return Slic3r::Geometry::Clipper::simplify_polygon( $self->SUPER::simplify(@_) ); diff --git a/t/clean_polylines.t b/t/clean_polylines.t index 84acab55..6427021f 100644 --- a/t/clean_polylines.t +++ b/t/clean_polylines.t @@ -2,7 +2,7 @@ use Test::More; use strict; use warnings; -plan tests => 8; +plan tests => 10; BEGIN { use FindBin; @@ -84,6 +84,25 @@ use Slic3r; is_deeply \@simplified_ex, [ \@simplified ], 'simplified polygon equals simplified expolygon'; } +{ + my $square = Slic3r::Polygon->new( # ccw + [100, 100], + [200, 100], + [200, 200], + [100, 200], + ); + my $hole_in_square = Slic3r::Polygon->new( # cw + [140, 140], + [140, 160], + [160, 160], + [160, 140], + ); + my $expolygon = Slic3r::ExPolygon->new($square, $hole_in_square); + my @simplified = $hole_in_square->simplify; + is scalar(@simplified), 1, 'hole simplification returns one polygon'; + ok $simplified[0]->is_counter_clockwise, 'hole simplification turns cw polygon into ccw polygon'; +} + { my $circle = [ [3744.8,8045.8],[3788.1,8061.4],[3940.6,8116.3],[3984.8,8129.2],[4140.6,8174.4],[4185.5,8184.4],[4343.8,8219.9],