Browse Source

Exclude support from bridged areas

Alessandro Ranellucci 11 years ago
parent
commit
148c773319

+ 4 - 1
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;
         }

+ 7 - 0
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;

+ 7 - 2
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!
             

+ 15 - 1
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) = @_;