From 896641cb7e66f99bf652025bd84edd6c92978c78 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 25 Aug 2012 20:04:29 +0200 Subject: [PATCH] Fixed regression causing some bridges not to be detected correctly. #629 --- lib/Slic3r/ExPolygon.pm | 21 ++++++--------------- lib/Slic3r/Geometry/Clipper.pm | 19 +++++++++++++++++-- lib/Slic3r/Layer.pm | 19 ++++++++++++++++++- lib/Slic3r/Polygon.pm | 8 +------- lib/Slic3r/Print.pm | 2 +- 5 files changed, 43 insertions(+), 26 deletions(-) diff --git a/lib/Slic3r/ExPolygon.pm b/lib/Slic3r/ExPolygon.pm index 5f9d23577b..e5f96d381f 100644 --- a/lib/Slic3r/ExPolygon.pm +++ b/lib/Slic3r/ExPolygon.pm @@ -61,13 +61,12 @@ sub boost_polygon { sub offset { my $self = shift; - my ($distance, $scale, $joinType, $miterLimit) = @_; - $scale ||= &Slic3r::SCALING_FACTOR * 1000000; - $joinType = JT_MITER if !defined $joinType; - $miterLimit ||= 2; - - my $offsets = Math::Clipper::offset($self, $distance, $scale, $joinType, $miterLimit); - return @$offsets; + return Slic3r::Geometry::Clipper::offset($self, @_); +} + +sub offset_ex { + my $self = shift; + return Slic3r::Geometry::Clipper::offset_ex($self, @_); } sub safety_offset { @@ -83,14 +82,6 @@ sub safety_offset { ); } -sub offset_ex { - my $self = shift; - my @offsets = $self->offset(@_); - - # apply holes to the right contours - return @{ union_ex(\@offsets) }; -} - sub encloses_point { my $self = shift; my ($point) = @_; diff --git a/lib/Slic3r/Geometry/Clipper.pm b/lib/Slic3r/Geometry/Clipper.pm index a76048fc4e..84c57dcf6a 100644 --- a/lib/Slic3r/Geometry/Clipper.pm +++ b/lib/Slic3r/Geometry/Clipper.pm @@ -4,11 +4,11 @@ use warnings; require Exporter; our @ISA = qw(Exporter); -our @EXPORT_OK = qw(explode_expolygon explode_expolygons safety_offset offset +our @EXPORT_OK = qw(explode_expolygon explode_expolygons safety_offset offset offset_ex diff_ex diff union_ex intersection_ex xor_ex PFT_EVENODD JT_MITER JT_ROUND JT_SQUARE is_counter_clockwise); -use Math::Clipper 1.09 ':all'; +use Math::Clipper 1.09 qw(:cliptypes :polyfilltypes :jointypes is_counter_clockwise area); use Slic3r::Geometry qw(scale); our $clipper = Math::Clipper->new; @@ -27,6 +27,21 @@ sub safety_offset { return Math::Clipper::offset($polygons, $factor || (scale 1e-05), 100, JT_MITER, 2); } +sub offset { + my ($polygons, $distance, $scale, $joinType, $miterLimit) = @_; + $scale ||= &Slic3r::SCALING_FACTOR * 1000000; + $joinType = JT_MITER if !defined $joinType; + $miterLimit ||= 2; + + my $offsets = Math::Clipper::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(@_) ]) }; +} + sub diff_ex { my ($subject, $clip, $safety_offset) = @_; diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index fc33cf4209..cb47fa4848 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -358,13 +358,30 @@ sub prepare_fill_surfaces { if ($Slic3r::Config->fill_density == 0) { @surfaces = grep $_->surface_type != S_TYPE_INTERNAL, @surfaces; } + + # remove unprintable regions (they would slow down the infill process and also cause + # some weird failures during bridge neighbor detection) + { + my $distance = scale $self->infill_flow->spacing / 2; + @surfaces = map { + my $surface = $_; + + # offset inwards + my @offsets = $surface->expolygon->offset_ex(-$distance); + @offsets = @{union_ex(Math::Clipper::offset([ map @$_, @offsets ], $distance, 100, JT_MITER))}; + map Slic3r::Surface->new( + expolygon => $_, + surface_type => $surface->surface_type, + ), @offsets; + } @surfaces; + } # turn too small internal regions into solid regions { my $min_area = scale scale $Slic3r::Config->solid_infill_below_area; # scaling an area requires two calls! my @small = grep $_->surface_type == S_TYPE_INTERNAL && $_->expolygon->contour->area <= $min_area, @surfaces; $_->surface_type(S_TYPE_INTERNALSOLID) for @small; - Slic3r::debugf "identified %d small surfaces at layer %d\n", scalar(@small), $self->id if @small > 0; + Slic3r::debugf "identified %d small solid surfaces at layer %d\n", scalar(@small), $self->id if @small > 0; } $self->fill_surfaces([@surfaces]); diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index fa7ee712d8..ba09dcc2d5 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -71,13 +71,7 @@ sub safety_offset { sub offset { my $self = shift; - my ($distance, $scale, $joinType, $miterLimit) = @_; - $scale ||= &Slic3r::SCALING_FACTOR * 1000000; - $joinType = JT_MITER if !defined $joinType; - $miterLimit ||= 2; - - my $offsets = Math::Clipper::offset([$self], $distance, $scale, $joinType, $miterLimit); - return map Slic3r::Polygon->new($_), @$offsets; + return map Slic3r::Polygon->new($_), Slic3r::Geometry::Clipper::offset([$self], @_); } # this method subdivides the polygon segments to that no one of them diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index c5aec01a70..487a5c312c 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -497,7 +497,7 @@ sub make_skirt { my @skirt = (); for (my $i = $Slic3r::Config->skirts; $i > 0; $i--) { my $distance = scale ($Slic3r::Config->skirt_distance + ($flow->spacing * $i)); - my $outline = offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND); + my $outline = Math::Clipper::offset([$convex_hull], $distance, &Slic3r::SCALING_FACTOR * 100, JT_ROUND); push @skirt, Slic3r::ExtrusionLoop->pack( polygon => Slic3r::Polygon->new(@{$outline->[0]}), role => EXTR_ROLE_SKIRT,