From 5efa409c7c208e0151a2910eba9e66aafe659daf Mon Sep 17 00:00:00 2001
From: Alessandro Ranellucci <aar@cpan.org>
Date: Mon, 13 May 2013 13:07:22 +0200
Subject: [PATCH] Move gap fill to its own method

---
 lib/Slic3r/Layer/Region.pm | 162 +++++++++++++++++++------------------
 1 file changed, 84 insertions(+), 78 deletions(-)

diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm
index 19a30d87f..ee0b42265 100644
--- a/lib/Slic3r/Layer/Region.pm
+++ b/lib/Slic3r/Layer/Region.pm
@@ -247,86 +247,10 @@ sub make_perimeters {
                         +$infill_spacing,
                     );
         }
-        
-        # fill gaps
-        if ($Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0 && @gaps) {
-            my $filler = $self->layer->object->print->fill_maker->filler('rectilinear');
-            $filler->layer_id($self->layer->id);
-            
-            # we should probably use this code to handle thin walls and remove that logic from
-            # make_surfaces(), but we need to enable dynamic extrusion width before as we can't
-            # use zigzag for thin walls.
-            # in the mean time we subtract thin walls from the detected gaps so that we don't
-            # reprocess them, causing overlapping thin walls and zigzag.
-            @gaps = @{diff_ex(
-                [ map @$_, @gaps ],
-                [ map $_->grow($self->perimeter_flow->scaled_width), @{$self->{thin_walls}} ],
-                1,
-            )};
-            
-            my $w = $self->perimeter_flow->width;
-            my @widths = (1.5 * $w, $w, 0.4 * $w);  # worth trying 0.2 too?
-            foreach my $width (@widths) {
-                my $flow = $self->perimeter_flow->clone(width => $width);
-                
-                # extract the gaps having this width
-                my @this_width = map $_->offset_ex(+0.5*$flow->scaled_width),
-                    map $_->noncollapsing_offset_ex(-0.5*$flow->scaled_width),
-                    @gaps;
-                
-                if (0) {  # remember to re-enable t/dynamic.t
-                    # fill gaps using dynamic extrusion width, by treating them like thin polygons,
-                    # thus generating the skeleton and using it to fill them
-                    my %path_args = (
-                        role            => EXTR_ROLE_SOLIDFILL,
-                        flow_spacing    => $flow->spacing,
-                    );
-                    push @{ $self->thin_fills }, map {
-                        $_->isa('Slic3r::Polygon')
-                            ? (map $_->pack, Slic3r::ExtrusionLoop->new(polygon => $_, %path_args)->split_at_first_point)  # we should keep these as loops
-                            : Slic3r::ExtrusionPath->pack(polyline => $_, %path_args),
-                    } map $_->medial_axis($flow->scaled_width), @this_width;
-                
-                    Slic3r::debugf "  %d gaps filled with extrusion width = %s\n", scalar @this_width, $width
-                        if @{ $self->thin_fills };
-                    
-                } else {
-                    # fill gaps using zigzag infill
-                    
-                    # since this is infill, we have to offset by half-extrusion width inwards
-                    my @infill = map $_->offset_ex(-0.5*$flow->scaled_width), @this_width;
-                    
-                    foreach my $expolygon (@infill) {
-                        my @paths = $filler->fill_surface(
-                            Slic3r::Surface->new(expolygon => $expolygon),
-                            density         => 1,
-                            flow_spacing    => $flow->spacing,
-                        );
-                        my $params = shift @paths;
-                        
-                        push @{ $self->thin_fills },
-                            map {
-                                $_->polyline->simplify($flow->scaled_width / 3);
-                                $_->pack;
-                            }
-                            map Slic3r::ExtrusionPath->new(
-                                polyline        => Slic3r::Polyline->new(@$_),
-                                role            => EXTR_ROLE_GAPFILL,
-                                height          => $self->height,
-                                flow_spacing    => $params->{flow_spacing},
-                            ), @paths;
-                    }
-                }
-                
-                # check what's left
-                @gaps = @{diff_ex(
-                    [ map @$_, @gaps ],
-                    [ map @$_, @this_width ],
-                )};
-            }
-        }
     }
     
+    $self->_fill_gaps(\@gaps);
+    
     # TODO: can these be removed?
     @contours   = grep $_->is_printable($self->perimeter_flow->scaled_width), @contours;
     @holes      = grep $_->is_printable($self->perimeter_flow->scaled_width), @holes;
@@ -395,6 +319,88 @@ sub make_perimeters {
     ])->chained_path;
 }
 
+sub _fill_gaps {
+    my $self = shift;
+    my ($gaps) = @_;
+    
+    return unless $Slic3r::Config->gap_fill_speed > 0 && $Slic3r::Config->fill_density > 0 && @$gaps;
+    
+    my $filler = $self->layer->object->print->fill_maker->filler('rectilinear');
+    $filler->layer_id($self->layer->id);
+    
+    # we should probably use this code to handle thin walls and remove that logic from
+    # make_surfaces(), but we need to enable dynamic extrusion width before as we can't
+    # use zigzag for thin walls.
+    # in the mean time we subtract thin walls from the detected gaps so that we don't
+    # reprocess them, causing overlapping thin walls and zigzag.
+    @$gaps = @{diff_ex(
+        [ map @$_, @$gaps ],
+        [ map $_->grow($self->perimeter_flow->scaled_width), @{$self->{thin_walls}} ],
+        1,
+    )};
+    
+    my $w = $self->perimeter_flow->width;
+    my @widths = (1.5 * $w, $w, 0.4 * $w);  # worth trying 0.2 too?
+    foreach my $width (@widths) {
+        my $flow = $self->perimeter_flow->clone(width => $width);
+        
+        # extract the gaps having this width
+        my @this_width = map $_->offset_ex(+0.5*$flow->scaled_width),
+            map $_->noncollapsing_offset_ex(-0.5*$flow->scaled_width),
+            @$gaps;
+        
+        if (0) {  # remember to re-enable t/dynamic.t
+            # fill gaps using dynamic extrusion width, by treating them like thin polygons,
+            # thus generating the skeleton and using it to fill them
+            my %path_args = (
+                role            => EXTR_ROLE_SOLIDFILL,
+                flow_spacing    => $flow->spacing,
+            );
+            push @{ $self->thin_fills }, map {
+                $_->isa('Slic3r::Polygon')
+                    ? (map $_->pack, Slic3r::ExtrusionLoop->new(polygon => $_, %path_args)->split_at_first_point)  # we should keep these as loops
+                    : Slic3r::ExtrusionPath->pack(polyline => $_, %path_args),
+            } map $_->medial_axis($flow->scaled_width), @this_width;
+        
+            Slic3r::debugf "  %d gaps filled with extrusion width = %s\n", scalar @this_width, $width
+                if @{ $self->thin_fills };
+            
+        } else {
+            # fill gaps using zigzag infill
+            
+            # since this is infill, we have to offset by half-extrusion width inwards
+            my @infill = map $_->offset_ex(-0.5*$flow->scaled_width), @this_width;
+            
+            foreach my $expolygon (@infill) {
+                my @paths = $filler->fill_surface(
+                    Slic3r::Surface->new(expolygon => $expolygon),
+                    density         => 1,
+                    flow_spacing    => $flow->spacing,
+                );
+                my $params = shift @paths;
+                
+                push @{ $self->thin_fills },
+                    map {
+                        $_->polyline->simplify($flow->scaled_width / 3);
+                        $_->pack;
+                    }
+                    map Slic3r::ExtrusionPath->new(
+                        polyline        => Slic3r::Polyline->new(@$_),
+                        role            => EXTR_ROLE_GAPFILL,
+                        height          => $self->height,
+                        flow_spacing    => $params->{flow_spacing},
+                    ), @paths;
+            }
+        }
+        
+        # check what's left
+        @$gaps = @{diff_ex(
+            [ map @$_, @$gaps ],
+            [ map @$_, @this_width ],
+        )};
+    }
+}
+
 sub prepare_fill_surfaces {
     my $self = shift;