From dc0f70678984c483cfd61e5eb4c85e648aeb7fa8 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 14 Mar 2013 14:27:08 +0100 Subject: [PATCH] Bugfix: simplification of support areas could lead to complex polygons with bad orientation, thus causing wrong pattern clipping. #1032 --- lib/Slic3r/ExPolygon.pm | 8 ++++++++ lib/Slic3r/Geometry/Clipper.pm | 11 ++++++++++- lib/Slic3r/Print/Object.pm | 5 ++++- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 770db9a8..202258ac 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -5,6 +5,7 @@ use warnings; # an ExPolygon is a polygon with holes use Boost::Geometry::Utils; +use List::Util qw(first); use Math::Geometry::Voronoi; use Slic3r::Geometry qw(X Y A B point_in_polygon same_line line_length epsilon); use Slic3r::Geometry::Clipper qw(union_ex JT_MITER); @@ -54,6 +55,13 @@ sub clipper_expolygon { }; } +sub is_valid { + my $self = shift; + return (!first { !$_->is_valid } @$self) + && $self->contour->is_counter_clockwise + && (!first { $_->is_counter_clockwise } $self->holes); +} + sub boost_polygon { my $self = shift; return Boost::Geometry::Utils::polygon(@$self); diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index 292e88f2..6b259e0b 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -4,7 +4,7 @@ use warnings; require Exporter; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(safety_offset offset offset_ex +our @EXPORT_OK = qw(safety_offset 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); @@ -83,4 +83,13 @@ sub xor_ex { ]; } +sub collapse_ex { + my ($polygons, $width) = @_; + my @result = offset( + [ offset($polygons, -$width/2,) ], + +$width/2, + ); + return union_ex([@result]); +} + 1; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 6008e02e..947daee5 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -4,7 +4,7 @@ use Moo; use List::Util qw(min sum first); use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(Z PI scale unscale deg2rad rad2deg scaled_epsilon); -use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex offset); +use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex offset collapse_ex); use Slic3r::Surface ':types'; has 'print' => (is => 'ro', weak_ref => 1, required => 1); @@ -774,6 +774,7 @@ sub generate_support_material { [ map @$_, @{ $upper_layers_overhangs[-1] || [] } ], [ map @$_, @current_layer_offsetted_slices ], ); + $layers_contact_areas{$i} = collapse_ex([ map @$_, @{$layers_contact_areas{$i}} ], $flow->scaled_width); $_->simplify($flow->scaled_spacing) for @{$layers_contact_areas{$i}}; # to define interface regions of this layer we consider the overhangs of all the upper layers @@ -785,6 +786,7 @@ sub generate_support_material { (map @$_, @{ $layers_contact_areas{$i} }), ], ); + $layers_interfaces{$i} = collapse_ex([ map @$_, @{$layers_interfaces{$i}} ], $flow->scaled_width); $_->simplify($flow->scaled_spacing) for @{$layers_interfaces{$i}}; # generate support material in current layer (for upper layers) @@ -804,6 +806,7 @@ sub generate_support_material { (map @$_, @{ $layers_interfaces{$i} }), ], ); + $layers{$i} = collapse_ex([ map @$_, @{$layers{$i}} ], $flow->scaled_width); $_->simplify($flow->scaled_spacing) for @{$layers{$i}}; # get layer overhangs and put them into queue for adding support inside lower layers;