diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index fc8d35b8..205bed4d 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -7,7 +7,7 @@ our @ISA = qw(Exporter); our @EXPORT_OK = qw(safety_offset safety_offset_ex offset offset_ex collapse_ex diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND JT_SQUARE is_counter_clockwise union_pt offset2 offset2_ex traverse_pt - intersection union); + intersection union collapse); use Math::Clipper 1.22 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area); use Slic3r::Geometry qw(scale); @@ -31,7 +31,7 @@ sub offset { $miterLimit //= 3; my $offsets = Math::Clipper::int_offset($polygons, $distance, $scale, $joinType, $miterLimit); - return @$offsets; + return map Slic3r::Polygon->new(@$_), @$offsets; } sub offset2 { @@ -41,7 +41,7 @@ sub offset2 { $miterLimit //= 3; my $offsets = Math::Clipper::int_offset2($polygons, $distance1, $distance2, $scale, $joinType, $miterLimit); - return @$offsets; + return map Slic3r::Polygon->new(@$_), @$offsets; } sub offset_ex { @@ -159,6 +159,11 @@ sub collapse_ex { return [ offset2_ex($polygons, -$width/2, +$width/2) ]; } +sub collapse { + my ($polygons, $width) = @_; + return [ offset2($polygons, -$width/2, +$width/2) ]; +} + sub simplify_polygon { my ($polygon, $pft) = @_; return map Slic3r::Polygon->new(@$_), diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 2ca0e0d1..8b0c8600 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -5,7 +5,7 @@ use List::Util qw(min max sum first); use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(Z PI scale unscale deg2rad rad2deg scaled_epsilon chained_path_points); use Slic3r::Geometry::Clipper qw(diff diff_ex intersection intersection_ex union union_ex - offset offset_ex offset2); + offset offset_ex offset2 collapse); use Slic3r::Surface ':types'; has 'print' => (is => 'ro', weak_ref => 1, required => 1); @@ -912,6 +912,10 @@ sub generate_support_material { # ignore this contact area if it's too low next if $contact_z < $Slic3r::Config->first_layer_height; + # make sure nothing collapses, and even small areas get support + if (my $collapsed = collapse(\@contact, $flow->scaled_width)) { + push @contact, offset(diff(\@contact, $collapsed), $flow->scaled_width); + } $contact{$contact_z} = [ @contact ]; $overhang{$contact_z} = [ @overhang ]; }