diff --git a/lib/Slic3r/Layer/BridgeDetector.pm b/lib/Slic3r/Layer/BridgeDetector.pm index 80ca67417..8620326c2 100644 --- a/lib/Slic3r/Layer/BridgeDetector.pm +++ b/lib/Slic3r/Layer/BridgeDetector.pm @@ -157,7 +157,7 @@ sub coverage { my ($self, $angle) = @_; if (!defined $angle) { - return [] if !defined($angle = $self->detect_angle); + return [] if !defined($angle = $self->angle); } # Clone our expolygon and rotate it so that we work with vertical lines. @@ -181,6 +181,9 @@ sub coverage { my @polylines = map $_->as_polyline, @{$trapezoid->lines}; my @supported = @{intersection_pl(\@polylines, [map @$_, @$anchors])}; + # not nice, we need a more robust non-numeric check + @supported = grep $_->length >= $self->extrusion_width, @supported; + if (@supported >= 2) { push @covered, $trapezoid; } diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 1cdce8ce9..a150ac809 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -30,6 +30,9 @@ has 'thin_fills' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collect # collection of surfaces for infill generation has 'fill_surfaces' => (is => 'rw', default => sub { Slic3r::Surface::Collection->new }); +# collection of expolygons representing the bridged areas (thus not needing support material) +has 'bridged' => (is => 'rw', default => sub { Slic3r::ExPolygon::Collection->new }); + # ordered collection of extrusion paths/loops to build all perimeters has 'perimeters' => (is => 'rw', default => sub { Slic3r::ExtrusionPath::Collection->new }); @@ -412,6 +415,10 @@ sub process_external_surfaces { ); Slic3r::debugf "Processing bridge at layer %d:\n", $self->id; $angle = $bridge_detector->detect_angle; + + if (defined $angle && $self->object->config->support_material) { + $self->bridged->append(@{ $bridge_detector->coverage($angle) }); + } } push @bottom, map $surface->clone(expolygon => $_, bridge_angle => $angle), @$grown; diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 724ecc923..db27d67fd 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -159,8 +159,13 @@ sub contact_area { # outside the lower slice boundary, thus no overhang } - # TODO: this is the place to remove bridged areas - + # remove bridged areas + $diff = diff( + $diff, + [ map @$_, @{$layerm->bridged} ], + 1, + ); + next if !@$diff; push @overhang, @$diff; # NOTE: this is not the full overhang as it misses the outermost half of the perimeter width! diff --git a/t/bridges.t b/t/bridges.t index daddd7f6b..3ebb9866f 100644 --- a/t/bridges.t +++ b/t/bridges.t @@ -1,4 +1,4 @@ -use Test::More tests => 12; +use Test::More tests => 14; use strict; use warnings; @@ -67,6 +67,20 @@ use Slic3r::Test; ok check_angle($lower, $bridge, 135), 'correct bridge angle for C-shaped overhang'; } +{ + my $bridge = Slic3r::ExPolygon->new( + Slic3r::Polygon->new_scale([10,10],[20,10],[20,20], [10,20]), + ); + my $lower = [ + Slic3r::ExPolygon->new( + Slic3r::Polygon->new_scale([10,10],[10,20],[20,20],[20,30],[0,30],[0,10]), + ), + ]; + $_->translate(scale 20, scale 20) for $bridge, @$lower; # avoid negative coordinates for easier SVG preview + + ok check_angle($lower, $bridge, 45, undef, $bridge->area/2), 'correct bridge angle for L-shaped overhang'; +} + sub check_angle { my ($lower, $bridge, $expected, $tolerance, $expected_coverage) = @_;