diff --git a/lib/Slic3r/Geometry.pm b/lib/Slic3r/Geometry.pm index d53193677..132fd013e 100644 --- a/lib/Slic3r/Geometry.pm +++ b/lib/Slic3r/Geometry.pm @@ -596,7 +596,6 @@ sub polygon_remove_parallel_continuous_edges { sub polyline_remove_acute_vertices { my ($points, $isPolygon) = @_; - for (my $i = $isPolygon ? -1 : 1; $i < $#$points; $i++) { my $angle = angle3points($points->[$i], $points->[$i-1], $points->[$i+1]); if ($angle < 0.01 || $angle >= 2*PI - 0.01) { diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm new file mode 100644 index 000000000..93cd42b5c --- /dev/null +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -0,0 +1,32 @@ +package Slic3r::Geometry::Clipper; +use strict; +use warnings; + +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT_OK = qw(diff_ex diff union_ex); + +use Math::Clipper ':all'; +our $clipper = Math::Clipper->new; + +sub diff_ex { + my ($subject, $clip) = @_; + + $clipper->clear; + $clipper->add_subject_polygons($subject); + $clipper->add_clip_polygons($clip); + return $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO); +} + +sub diff { + return [ map { $_->{outer}, $_->{holes} } diff_ex(@_) ]; +} + +sub union_ex { + my ($polygons) = @_; + $clipper->clear; + $clipper->add_subject_polygons($polygons); + return $clipper->ex_execute(CT_UNION, PFT_NONZERO, PFT_NONZERO); +} + +1; diff --git a/lib/Slic3r/Polyline/Closed.pm b/lib/Slic3r/Polyline/Closed.pm index 986d915fb..ee62523fd 100644 --- a/lib/Slic3r/Polyline/Closed.pm +++ b/lib/Slic3r/Polyline/Closed.pm @@ -35,4 +35,9 @@ sub is_printable { return @$offsets ? 1 : 0; } +sub is_valid { + my $self = shift; + return @{$self->points} >= 3; +} + 1; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 7de587c73..2cf9fd9c6 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -134,8 +134,13 @@ sub detect_surfaces_type { if ($lower_layer) { @bottom = $surface_difference->($layer->surfaces, $lower_layer->surfaces, 'bottom'); + $_->contour->merge_continuous_lines for @bottom; + + # merge_continuous_lines could return polylines with less than 3 points (thus invalid) + # actually, this shouldn't happen so it deserves further investigation + @bottom = grep $_->contour->is_valid, @bottom; + for (@bottom) { - $_->contour->merge_continuous_lines; $_->contour->remove_acute_vertices; # okay, this is an Ugly Hack(tm) to avoid floating point math problems