diff --git a/lib/Slic3r/GUI/Plater.pm b/lib/Slic3r/GUI/Plater.pm index 331aecaae6..be001cae7c 100644 --- a/lib/Slic3r/GUI/Plater.pm +++ b/lib/Slic3r/GUI/Plater.pm @@ -5,9 +5,9 @@ use utf8; use File::Basename qw(basename dirname); use List::Util qw(max sum first); +use Math::Clipper qw(offset JT_ROUND); use Math::ConvexHull::MonotoneChain qw(convex_hull); use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX); -use Slic3r::Geometry::Clipper qw(offset JT_ROUND); use threads::shared qw(shared_clone); use Wx qw(:bitmap :brush :button :cursor :dialog :filedialog :font :keycode :icon :id :listctrl :misc :panel :pen :sizer :toolbar :window); use Wx::Event qw(EVT_BUTTON EVT_COMMAND EVT_KEY_DOWN EVT_LIST_ITEM_ACTIVATED EVT_LIST_ITEM_DESELECTED EVT_LIST_ITEM_SELECTED EVT_MOUSE_EVENTS EVT_PAINT EVT_TOOL EVT_CHOICE); diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 68e3d7c0e7..bef2713da5 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -14,12 +14,13 @@ our $clipper = Math::Clipper->new; sub safety_offset { my ($polygons, $factor) = @_; - return Math::Clipper::offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2); + return Math::Clipper::int_offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2); } sub safety_offset_ex { - # offset polygons and then apply holes to the right contours - return @{ union_ex([ safety_offset(@_) ]) }; + my ($polygons, $factor) = @_; + return map Slic3r::ExPolygon->new($_), + @{Math::Clipper::ex_int_offset($polygons, $factor // (scale 1e-05), 100000, JT_MITER, 2)}; } sub offset { @@ -28,13 +29,18 @@ sub offset { $joinType //= JT_MITER; $miterLimit //= 3; - my $offsets = Math::Clipper::offset($polygons, $distance, $scale, $joinType, $miterLimit); + my $offsets = Math::Clipper::int_offset($polygons, $distance, $scale, $joinType, $miterLimit); return @$offsets; } sub offset_ex { - # offset polygons and then apply holes to the right contours - return @{ union_ex([ offset(@_) ]) }; + my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; + $scale ||= 100000; + $joinType //= JT_MITER; + $miterLimit //= 3; + + my $offsets = Math::Clipper::ex_int_offset($polygons, $distance, $scale, $joinType, $miterLimit); + return map Slic3r::ExPolygon->new($_), @$offsets; } sub diff_ex { @@ -96,13 +102,19 @@ sub xor_ex { ]; } +sub ex_int_offset2 { + my ($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit) = @_; + $scale ||= 100000; + $joinType //= JT_MITER; + $miterLimit //= 3; + + my $offsets = Math::Clipper::ex_int_offset2($polygons, $delta1, $delta2, $scale, $joinType, $miterLimit); + return map Slic3r::ExPolygon->new($_), @$offsets; +} + sub collapse_ex { my ($polygons, $width) = @_; - my @result = offset( - [ offset($polygons, -$width/2,) ], - +$width/2, - ); - return union_ex([@result]); + return ex_int_offset2($polygons, -$width/2, +$width/2); } sub simplify_polygon { diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index c13b32760e..e4d8ee4763 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -96,12 +96,9 @@ sub make_surfaces { # detect thin walls by offsetting slices by half extrusion inwards { my $width = $self->perimeter_flow->scaled_width; - my $outgrown = union_ex([ - Slic3r::Geometry::Clipper::offset( - [Slic3r::Geometry::Clipper::offset([ map @$_, map $_->expolygon, @{$self->slices} ], -$width)], - +$width, - ), - ]); + my $outgrown = [ + Slic3r::Geometry::Clipper::ex_int_offset2([ map @$_, map $_->expolygon, @{$self->slices} ], -$width, +$width), + ]; my $diff = diff_ex( [ map $_->p, @{$self->slices} ], [ map @$_, @$outgrown ], @@ -230,12 +227,7 @@ sub make_perimeters { # offsetting a polygon can result in one or many offset polygons my @new_offsets = (); foreach my $expolygon (@last_offsets) { - my @offsets = @{union_ex([ - Slic3r::Geometry::Clipper::offset( - [Slic3r::Geometry::Clipper::offset($expolygon, -1.5*$spacing)], - +0.5*$spacing, - ), - ])}; + my @offsets = Slic3r::Geometry::Clipper::ex_int_offset2($expolygon, -1.5*$spacing, +0.5*$spacing); push @new_offsets, @offsets; # where the above check collapses the expolygon, then there's no room for an inner loop