Browse Source

Rewrote Fill2.pm to C++, deleted Perl infills for good.
Removed dependency on Perl Math::PlanePath module.
Fixed compilation with Visual Studio and SLIC3R_DEBUG: Visual Studio older than 2015 does not support the prinf type specifier %zu. Use %Iu instead.
C++11 move semantics enabled.

bubnikv 8 years ago
parent
commit
95ede7c4b8

+ 0 - 1
Build.PL

@@ -15,7 +15,6 @@ my %prereqs = qw(
     File::Basename                  0
     File::Spec                      0
     Getopt::Long                    0
-    Math::PlanePath                 53
     Module::Build::WithXSpp         0.14
     Moo                             1.003001
     POSIX                           0

+ 1 - 3
lib/Slic3r.pm

@@ -56,8 +56,6 @@ use Slic3r::Config;
 use Slic3r::ExPolygon;
 use Slic3r::ExtrusionLoop;
 use Slic3r::ExtrusionPath;
-use Slic3r::Fill;
-use Slic3r::Fill2;
 use Slic3r::Flow;
 use Slic3r::Format::AMF;
 use Slic3r::Format::OBJ;
@@ -139,7 +137,7 @@ sub spawn_thread {
 # Otherwise run the task on the current thread.
 # Used for 
 #   Slic3r::Print::Object->layers->make_perimeters  : This is a pure C++ function.
-#   Slic3r::Print::Object->layers->make_fill        : This requires a rewrite of Fill.pm to C++.
+#   Slic3r::Print::Object->layers->make_fill        : This is a pure C++ function.
 #   Slic3r::Print::SupportMaterial::generate_toolpaths
 sub parallelize {
     my %params = @_;

+ 0 - 308
lib/Slic3r/Fill.pm

@@ -1,308 +0,0 @@
-package Slic3r::Fill;
-use Moo;
-
-use List::Util qw(max);
-use Slic3r::ExtrusionPath ':roles';
-use Slic3r::Fill::3DHoneycomb;
-use Slic3r::Fill::Base;
-use Slic3r::Fill::Concentric;
-use Slic3r::Fill::Honeycomb;
-use Slic3r::Fill::PlanePath;
-use Slic3r::Fill::Rectilinear;
-use Slic3r::Flow ':roles';
-use Slic3r::Geometry qw(X Y PI scale chained_path deg2rad);
-use Slic3r::Geometry::Clipper qw(union union_ex diff diff_ex intersection_ex offset offset2);
-use Slic3r::Surface ':types';
-
-
-has 'bounding_box' => (is => 'ro', required => 0);
-has 'fillers'   => (is => 'rw', default => sub { {} });
-
-our %FillTypes = (
-    archimedeanchords   => 'Slic3r::Fill::ArchimedeanChords',
-    rectilinear         => 'Slic3r::Fill::Rectilinear',
-    grid                => 'Slic3r::Fill::Grid',
-    flowsnake           => 'Slic3r::Fill::Flowsnake',
-    octagramspiral      => 'Slic3r::Fill::OctagramSpiral',
-    hilbertcurve        => 'Slic3r::Fill::HilbertCurve',
-    line                => 'Slic3r::Fill::Line',
-    concentric          => 'Slic3r::Fill::Concentric',
-    honeycomb           => 'Slic3r::Fill::Honeycomb',
-    '3dhoneycomb'       => 'Slic3r::Fill::3DHoneycomb',
-);
-
-sub filler {
-    my $self = shift;
-    my ($filler) = @_;
-    
-    if (!ref $self) {
-        return $FillTypes{$filler}->new;
-    }
-    
-    $self->fillers->{$filler} ||= $FillTypes{$filler}->new(
-        bounding_box => $self->bounding_box,
-    );
-    return $self->fillers->{$filler};
-}
-
-sub make_fill {
-    my $self = shift;
-    my ($layerm) = @_;
-    
-    Slic3r::debugf "Filling layer %d:\n", $layerm->layer->id;
-    
-    my $fill_density            = $layerm->region->config->fill_density;
-    my $infill_flow             = $layerm->flow(FLOW_ROLE_INFILL);
-    my $solid_infill_flow       = $layerm->flow(FLOW_ROLE_SOLID_INFILL);
-    my $top_solid_infill_flow   = $layerm->flow(FLOW_ROLE_TOP_SOLID_INFILL);
-    
-    my @surfaces = ();
-    
-    # merge adjacent surfaces
-    # in case of bridge surfaces, the ones with defined angle will be attached to the ones
-    # without any angle (shouldn't this logic be moved to process_external_surfaces()?)
-    {
-        my @surfaces_with_bridge_angle = grep { $_->bridge_angle >= 0 } @{$layerm->fill_surfaces};
-        
-        # group surfaces by distinct properties
-        my @groups = @{$layerm->fill_surfaces->group};
-        
-        # merge compatible groups (we can generate continuous infill for them)
-        {
-            # cache flow widths and patterns used for all solid groups
-            # (we'll use them for comparing compatible groups)
-            my @is_solid = my @fw = my @pattern = ();
-            for (my $i = 0; $i <= $#groups; $i++) {
-                # we can only merge solid non-bridge surfaces, so discard
-                # non-solid surfaces
-                if ($groups[$i][0]->is_solid && (!$groups[$i][0]->is_bridge || $layerm->layer->id == 0)) {
-                    $is_solid[$i] = 1;
-                    $fw[$i] = ($groups[$i][0]->surface_type == S_TYPE_TOP)
-                        ? $top_solid_infill_flow->width
-                        : $solid_infill_flow->width;
-                    $pattern[$i] = $groups[$i][0]->is_external
-                        ? $layerm->region->config->external_fill_pattern
-                        : 'rectilinear';
-                } else {
-                    $is_solid[$i]   = 0;
-                    $fw[$i]         = 0;
-                    $pattern[$i]    = 'none';
-                }
-            }
-            
-            # loop through solid groups
-            for (my $i = 0; $i <= $#groups; $i++) {
-                next if !$is_solid[$i];
-                
-                # find compatible groups and append them to this one
-                for (my $j = $i+1; $j <= $#groups; $j++) {
-                    next if !$is_solid[$j];
-                
-                    if ($fw[$i] == $fw[$j] && $pattern[$i] eq $pattern[$j]) {
-                        # groups are compatible, merge them
-                        push @{$groups[$i]}, @{$groups[$j]};
-                        splice @groups,     $j, 1;
-                        splice @is_solid,   $j, 1;
-                        splice @fw,         $j, 1;
-                        splice @pattern,    $j, 1;
-                    }
-                }
-            }
-        }
-        
-        # give priority to bridges
-        @groups = sort { ($a->[0]->bridge_angle >= 0) ? -1 : 0 } @groups;
-        
-        foreach my $group (@groups) {
-            my $union_p = union([ map $_->p, @$group ], 1);
-            
-            # subtract surfaces having a defined bridge_angle from any other
-            if (@surfaces_with_bridge_angle && $group->[0]->bridge_angle < 0) {
-                $union_p = diff(
-                    $union_p,
-                    [ map $_->p, @surfaces_with_bridge_angle ],
-                    1,
-                );
-            }
-            
-            # subtract any other surface already processed
-            my $union = diff_ex(
-                $union_p,
-                [ map $_->p, @surfaces ],
-                1,
-            );
-            
-            push @surfaces, map $group->[0]->clone(expolygon => $_), @$union;
-        }
-    }
-    
-    # we need to detect any narrow surfaces that might collapse
-    # when adding spacing below
-    # such narrow surfaces are often generated in sloping walls
-    # by bridge_over_infill() and combine_infill() as a result of the
-    # subtraction of the combinable area from the layer infill area,
-    # which leaves small areas near the perimeters
-    # we are going to grow such regions by overlapping them with the void (if any)
-    # TODO: detect and investigate whether there could be narrow regions without
-    # any void neighbors
-    {
-        my $distance_between_surfaces = max(
-            $infill_flow->scaled_spacing,
-            $solid_infill_flow->scaled_spacing,
-            $top_solid_infill_flow->scaled_spacing,
-        );
-        my $collapsed = diff(
-            [ map @{$_->expolygon}, @surfaces ],
-            offset2([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2, +$distance_between_surfaces/2),
-            1,
-        );
-        push @surfaces, map Slic3r::Surface->new(
-            expolygon       => $_,
-            surface_type    => S_TYPE_INTERNALSOLID,
-        ), @{intersection_ex(
-            offset($collapsed, $distance_between_surfaces),
-            [
-                (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces),
-                (@$collapsed),
-            ],
-            1,
-        )};
-    }
-    
-    if (0) {
-        require "Slic3r/SVG.pm";
-        Slic3r::SVG::output("fill_" . $layerm->print_z . ".svg",
-            expolygons      => [ map $_->expolygon, grep !$_->is_solid, @surfaces ],
-            red_expolygons  => [ map $_->expolygon, grep  $_->is_solid, @surfaces ],
-        );
-    }
-    
-    my @fills = ();
-    SURFACE: foreach my $surface (@surfaces) {
-        next if $surface->surface_type == S_TYPE_INTERNALVOID;
-        my $filler          = $layerm->region->config->fill_pattern;
-        my $density         = $fill_density;
-        my $role = ($surface->surface_type == S_TYPE_TOP) ? FLOW_ROLE_TOP_SOLID_INFILL
-            : $surface->is_solid ? FLOW_ROLE_SOLID_INFILL
-            : FLOW_ROLE_INFILL;
-        my $is_bridge       = $layerm->layer->id > 0 && $surface->is_bridge;
-        my $is_solid        = $surface->is_solid;
-        
-        if ($surface->is_solid) {
-            $density = 100;
-            $filler = 'rectilinear';
-            if ($surface->is_external && !$is_bridge) {
-                $filler = $layerm->region->config->external_fill_pattern;
-            }
-        } else {
-            next SURFACE unless $density > 0;
-        }
-        
-        # get filler object
-        my $f = $self->filler($filler);
-        
-        # calculate the actual flow we'll be using for this infill
-        my $h = $surface->thickness == -1 ? $layerm->layer->height : $surface->thickness;
-        my $flow = $layerm->region->flow(
-            $role,
-            $h,
-            $is_bridge || $f->use_bridge_flow,
-            $layerm->layer->id == 0,
-            -1,
-            $layerm->layer->object,
-        );
-        
-        # calculate flow spacing for infill pattern generation
-        my $using_internal_flow = 0;
-        if (!$is_solid && !$is_bridge) {
-            # it's internal infill, so we can calculate a generic flow spacing 
-            # for all layers, for avoiding the ugly effect of
-            # misaligned infill on first layer because of different extrusion width and
-            # layer height
-            my $internal_flow = $layerm->region->flow(
-                FLOW_ROLE_INFILL,
-                $layerm->layer->object->config->layer_height,  # TODO: handle infill_every_layers?
-                0,  # no bridge
-                0,  # no first layer
-                -1, # auto width
-                $layerm->layer->object,
-            );
-            $f->spacing($internal_flow->spacing);
-            $using_internal_flow = 1;
-#        } elsif ($surface->surface_type == S_TYPE_INTERNALBRIDGE) {
-#            # The internal bridging layer will be sparse.
-#            $f->spacing($flow->spacing * 2.);
-        } else {
-            $f->spacing($flow->spacing);
-        }
-        
-        my $old_spacing = $f->spacing;
-
-        $f->layer_id($layerm->layer->id);
-        $f->z($layerm->layer->print_z);
-        $f->angle(deg2rad($layerm->region->config->fill_angle));
-        $f->loop_clipping(scale($flow->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
-        
-        # apply half spacing using this flow's own spacing and generate infill
-        my @polylines = map $f->fill_surface(
-            $_,
-            density         => $density/100,
-            layer_height    => $h,
-#FIXME Vojtech disabled the automatic extrusion width adjustment as this feature quite often
-# generated extrusions with excessive widths.
-# The goal of the automatic line width adjustment was to fill in a region without a gap, but because
-# the filled regions are mostly not aligned with the fill direction, very likely 
-# the extrusion width adjustment causes more harm than good.
-            dont_adjust     => 1,
-        ), @{ $surface->offset(-scale($f->spacing)/2) };
-        
-        next unless @polylines;
-        
-        # calculate actual flow from spacing (which might have been adjusted by the infill
-        # pattern generator)
-        if ($using_internal_flow) {
-            # if we used the internal flow we're not doing a solid infill
-            # so we can safely ignore the slight variation that might have
-            # been applied to $f->flow_spacing
-        } else {
-            if (abs($old_spacing - $f->spacing) > 0.3 * $old_spacing) {
-                print "Infill: Extreme spacing adjustment, from: ", $old_spacing, " to: ", $f->spacing, "\n";
-            }
-            $flow = Slic3r::Flow->new_from_spacing(
-                spacing         => $f->spacing,
-                nozzle_diameter => $flow->nozzle_diameter,
-                layer_height    => $h,
-                bridge          => $is_bridge || $f->use_bridge_flow,
-            );
-        }
-        my $mm3_per_mm = $flow->mm3_per_mm;
-        
-        # save into layer
-        {
-            my $role = $is_bridge ? EXTR_ROLE_BRIDGE
-                : $is_solid ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
-                : EXTR_ROLE_FILL;
-            
-            push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;
-            $collection->no_sort($f->no_sort);
-            $collection->append(
-                map Slic3r::ExtrusionPath->new(
-                    polyline    => $_,
-                    role        => $role,
-                    mm3_per_mm  => $mm3_per_mm,
-                    width       => $flow->width,
-                    height      => $flow->height,
-                ), @polylines,
-            );
-        }
-    }
-    
-    # add thin fill regions
-    foreach my $thin_fill (@{$layerm->thin_fills}) {
-        push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill);
-    }
-    
-    return @fills;
-}
-
-1;

+ 0 - 230
lib/Slic3r/Fill/3DHoneycomb.pm

@@ -1,230 +0,0 @@
-package Slic3r::Fill::3DHoneycomb;
-use Moo;
-
-extends 'Slic3r::Fill::Base';
-
-use POSIX qw(ceil fmod);
-use Slic3r::Geometry qw(scale scaled_epsilon);
-use Slic3r::Geometry::Clipper qw(intersection_pl);
-
-# require bridge flow since most of this pattern hangs in air
-sub use_bridge_flow { 1 }
-
-sub fill_surface {
-    my ($self, $surface, %params) = @_;
-    
-    my $expolygon = $surface->expolygon;
-    my $bb = $expolygon->bounding_box;
-    my $size = $bb->size;
-    
-    my $distance = scale($self->spacing) / $params{density};
-    
-    # align bounding box to a multiple of our honeycomb grid module
-    # (a module is 2*$distance since one $distance half-module is 
-    # growing while the other $distance half-module is shrinking)
-    {
-        my $min = $bb->min_point;
-        $min->translate(
-            -($bb->x_min % (2*$distance)),
-            -($bb->y_min % (2*$distance)),
-        );
-        $bb->merge_point($min);
-    }
-    
-    # generate pattern
-    my @polylines = map Slic3r::Polyline->new(@$_),
-        makeGrid(
-            scale($self->z),
-            $distance,
-            ceil($size->x / $distance) + 1,
-            ceil($size->y / $distance) + 1,  #//
-            (($self->layer_id / $surface->thickness_layers) % 2) + 1,
-        );
-    
-    # move pattern in place
-    $_->translate($bb->x_min, $bb->y_min) for @polylines;
-    
-    # clip pattern to boundaries
-    @polylines = @{intersection_pl(\@polylines, \@$expolygon)};
-    
-    # connect lines
-    unless ($params{dont_connect} || !@polylines) {  # prevent calling leftmost_point() on empty collections
-        my ($expolygon_off) = @{$expolygon->offset_ex(scaled_epsilon)};
-        my $collection = Slic3r::Polyline::Collection->new(@polylines);
-        @polylines = ();
-        foreach my $polyline (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
-            # try to append this polyline to previous one if any
-            if (@polylines) {
-                my $line = Slic3r::Line->new($polylines[-1]->last_point, $polyline->first_point);
-                if ($line->length <= 1.5*$distance && $expolygon_off->contains_line($line)) {
-                    $polylines[-1]->append_polyline($polyline);
-                    next;
-                }
-            }
-            
-            # make a clone before $collection goes out of scope
-            push @polylines, $polyline->clone;
-        }
-    }
-    
-    # TODO: return ExtrusionLoop objects to get better chained paths
-    return @polylines;
-}
-
-
-=head1 DESCRIPTION
-
-Creates a contiguous sequence of points at a specified height that make
-up a horizontal slice of the edges of a space filling truncated
-octahedron tesselation. The octahedrons are oriented so that the
-square faces are in the horizontal plane with edges parallel to the X
-and Y axes.
-
-Credits: David Eccles (gringer).
-
-=head2 makeGrid(z, gridSize, gridWidth, gridHeight, curveType)
-
-Generate a set of curves (array of array of 2d points) that describe a
-horizontal slice of a truncated regular octahedron with a specified
-grid square size.
-
-=cut
-
-sub makeGrid {
-    my ($z, $gridSize, $gridWidth, $gridHeight, $curveType) = @_;
-    my $scaleFactor = $gridSize;
-    my $normalisedZ = $z / $scaleFactor;
-    my @points = makeNormalisedGrid($normalisedZ, $gridWidth, $gridHeight, $curveType);
-    foreach my $lineRef (@points) {
-        foreach my $pointRef (@$lineRef) {
-            $pointRef->[0] *= $scaleFactor;
-            $pointRef->[1] *= $scaleFactor;
-        }
-    }
-    return @points;
-}
-
-=head1 FUNCTIONS
-=cut
-
-=head2 colinearPoints(offset, gridLength)
-
-Generate an array of points that are in the same direction as the
-basic printing line (i.e. Y points for columns, X points for rows)
-
-Note: a negative offset only causes a change in the perpendicular
-direction
-
-=cut
-
-sub colinearPoints {
-    my ($offset, $baseLocation, $gridLength) = @_;
-    
-    my @points = ();
-    push @points, $baseLocation - abs($offset/2);
-    for (my $i = 0; $i < $gridLength; $i++) {
-        push @points, $baseLocation + $i + abs($offset/2);
-        push @points, $baseLocation + ($i+1) - abs($offset/2);
-    }
-    push @points, $baseLocation + $gridLength + abs($offset/2);
-    return @points;
-}
-
-=head2 colinearPoints(offset, baseLocation, gridLength)
-
-Generate an array of points for the dimension that is perpendicular to
-the basic printing line (i.e. X points for columns, Y points for rows)
-
-=cut
-
-sub perpendPoints {
-    my ($offset, $baseLocation, $gridLength) = @_;
-    
-    my @points = ();
-    my $side = 2*(($baseLocation) % 2) - 1;
-    push @points, $baseLocation - $offset/2 * $side;
-    for (my $i = 0; $i < $gridLength; $i++) {
-        $side = 2*(($i+$baseLocation) % 2) - 1;
-        push @points, $baseLocation + $offset/2 * $side;
-        push @points, $baseLocation + $offset/2 * $side;
-    }
-    push @points, $baseLocation - $offset/2 * $side;
-    
-    return @points;
-}
-
-=head2 trim(pointArrayRef, minX, minY, maxX, maxY)
-
-Trims an array of points to specified rectangular limits. Point
-components that are outside these limits are set to the limits.
-
-=cut
-
-sub trim {
-    my ($pointArrayRef, $minX, $minY, $maxX, $maxY) = @_;
-  
-    foreach (@$pointArrayRef) {
-        $_->[0] = ($_->[0] < $minX) ? $minX : (($_->[0] > $maxX) ? $maxX : $_->[0]);
-        $_->[1] = ($_->[1] < $minY) ? $minY : (($_->[1] > $maxY) ? $maxY : $_->[1]);
-    }
-}
-
-=head2 makeNormalisedGrid(z, gridWidth, gridHeight, curveType)
-
-Generate a set of curves (array of array of 2d points) that describe a
-horizontal slice of a truncated regular octahedron with edge length 1.
-
-curveType specifies which lines to print, 1 for vertical lines
-(columns), 2 for horizontal lines (rows), and 3 for both.
-
-=cut
-
-sub makeNormalisedGrid {
-    my ($z, $gridWidth, $gridHeight, $curveType) = @_;
-    
-    ## offset required to create a regular octagram
-    my $octagramGap = 0.5;
-    
-    # sawtooth wave function for range f($z) = [-$octagramGap .. $octagramGap]
-    my $a = sqrt(2);  # period
-    my $wave = abs(fmod($z, $a) - $a/2)/$a*4 - 1;
-    my $offset = $wave * $octagramGap;
-    
-    my @points = ();
-    if (($curveType & 1) != 0) {
-        for (my $x = 0; $x <= $gridWidth; $x++) {
-            my @xPoints = perpendPoints($offset, $x, $gridHeight);
-            my @yPoints = colinearPoints($offset, 0, $gridHeight);
-            # This is essentially @newPoints = zip(@xPoints, @yPoints)
-            my @newPoints = map [ $xPoints[$_], $yPoints[$_] ], 0..$#xPoints;
-            
-            # trim points to grid edges
-            #trim(\@newPoints, 0, 0, $gridWidth, $gridHeight);
-            
-            if ($x % 2 == 0){
-                push @points, [ @newPoints ];
-            } else {
-                push @points, [ reverse @newPoints ];
-            }
-        }
-    }
-    if (($curveType & 2) != 0) {
-        for (my $y = 0; $y <= $gridHeight; $y++) {
-            my @xPoints = colinearPoints($offset, 0, $gridWidth);
-            my @yPoints = perpendPoints($offset, $y, $gridWidth);
-            my @newPoints = map [ $xPoints[$_], $yPoints[$_] ], 0..$#xPoints;
-            
-            # trim points to grid edges
-            #trim(\@newPoints, 0, 0, $gridWidth, $gridHeight);
-            
-            if ($y % 2 == 0) {
-                push @points, [ @newPoints ];
-            } else {
-                push @points, [ reverse @newPoints ];
-            }
-        }
-    }
-    return @points;
-}
-
-1;

+ 0 - 101
lib/Slic3r/Fill/Base.pm

@@ -1,101 +0,0 @@
-package Slic3r::Fill::Base;
-use Moo;
-
-has 'layer_id'            => (is => 'rw');
-has 'z'                   => (is => 'rw'); # in unscaled coordinates
-has 'angle'               => (is => 'rw'); # in radians, ccw, 0 = East
-has 'spacing'             => (is => 'rw'); # in unscaled coordinates
-has 'loop_clipping'       => (is => 'rw', default => sub { 0 }); # in scaled coordinates
-has 'bounding_box'        => (is => 'ro', required => 0);  # Slic3r::Geometry::BoundingBox object
-
-sub set_spacing {
-    my ($self, $spacing) = @_;
-    $self->spacing($spacing);
-}
-
-sub set_angle {
-    my ($self, $angle) = @_;
-    $self->angle($angle);
-}
-
-sub adjust_solid_spacing {
-    my $self = shift;
-    my %params = @_;
-    
-    my $number_of_lines = int($params{width} / $params{distance}) + 1;
-    return $params{distance} if $number_of_lines <= 1;
-    
-    my $extra_space = $params{width} % $params{distance};
-    return $params{distance} + $extra_space / ($number_of_lines - 1);
-}
-
-sub no_sort { 0 }
-sub use_bridge_flow { 0 }
-
-
-package Slic3r::Fill::WithDirection;
-use Moo::Role;
-
-use Slic3r::Geometry qw(PI rad2deg);
-
-sub angles () { [0, PI/2] }
-
-sub infill_direction {
-    my $self = shift;
-    my ($surface) = @_;
-    
-    if (!defined $self->angle) {
-        warn "Using undefined infill angle";
-        $self->angle(0);
-    }
-    
-    # set infill angle
-    my (@rotate);
-    $rotate[0] = $self->angle;
-    $rotate[1] = $self->bounding_box
-        ? $self->bounding_box->center
-        : $surface->expolygon->bounding_box->center;
-    my $shift = $rotate[1]->clone;
-    
-    if (defined $self->layer_id) {
-        # alternate fill direction
-        my $layer_num = $self->layer_id / $surface->thickness_layers;
-        my $angle = $self->angles->[$layer_num % @{$self->angles}];
-        $rotate[0] = $self->angle + $angle if $angle;
-    }
-        
-    # use bridge angle
-    if ($surface->bridge_angle >= 0) {
-        Slic3r::debugf "Filling bridge with angle %d\n", rad2deg($surface->bridge_angle);
-        $rotate[0] = $surface->bridge_angle;
-    }
-    
-    $rotate[0] += PI/2;
-    $shift->rotate(@rotate);
-    return [\@rotate, $shift];
-}
-
-# this method accepts any object that implements rotate() and translate()
-sub rotate_points {
-    my $self = shift;
-    my ($expolygon, $rotate_vector) = @_;
-    
-    # rotate points
-    my ($rotate, $shift) = @$rotate_vector;
-    $rotate = [ -$rotate->[0], $rotate->[1] ];
-    $expolygon->rotate(@$rotate);
-    $expolygon->translate(@$shift);
-}
-
-sub rotate_points_back {
-    my $self = shift;
-    my ($paths, $rotate_vector) = @_;
-    
-    my ($rotate, $shift) = @$rotate_vector;
-    $shift = [ map -$_, @$shift ];
-    
-    $_->translate(@$shift) for @$paths;
-    $_->rotate(@$rotate) for @$paths;
-}
-
-1;

+ 0 - 57
lib/Slic3r/Fill/Concentric.pm

@@ -1,57 +0,0 @@
-package Slic3r::Fill::Concentric;
-use Moo;
-
-extends 'Slic3r::Fill::Base';
-
-use Slic3r::Geometry qw(scale unscale X);
-use Slic3r::Geometry::Clipper qw(offset offset2 union_pt_chained);
-
-sub no_sort { 1 }
-
-sub fill_surface {
-    my $self = shift;
-    my ($surface, %params) = @_;
-    
-    # no rotation is supported for this infill pattern
-    
-    my $expolygon = $surface->expolygon;
-    my $bounding_box = $expolygon->bounding_box;
-    
-    my $min_spacing = scale($self->spacing);
-    my $distance = $min_spacing / $params{density};
-    
-    if ($params{density} == 1 && !$params{dont_adjust}) {
-        $distance = $self->adjust_solid_spacing(
-            width       => $bounding_box->size->[X],
-            distance    => $distance,
-        );
-        $self->spacing(unscale $distance);
-    }
-    
-    my @loops = my @last = map $_->clone, @$expolygon;
-    while (@last) {
-        push @loops, @last = @{offset2(\@last, -($distance + 0.5*$min_spacing), +0.5*$min_spacing)};
-    }
-    
-    # generate paths from the outermost to the innermost, to avoid 
-    # adhesion problems of the first central tiny loops
-    @loops = map Slic3r::Polygon->new(@$_),
-        reverse @{union_pt_chained(\@loops)};
-    
-    # split paths using a nearest neighbor search
-    my @paths = ();
-    my $last_pos = Slic3r::Point->new(0,0);
-    foreach my $loop (@loops) {
-        push @paths, $loop->split_at_index($last_pos->nearest_point_index(\@$loop));
-        $last_pos = $paths[-1]->last_point;
-    }
-    
-    # clip the paths to prevent the extruder from getting exactly on the first point of the loop
-    $_->clip_end($self->loop_clipping) for @paths;
-    @paths = grep $_->is_valid, @paths;  # remove empty paths (too short, thus eaten by clipping)
-    
-    # TODO: return ExtrusionLoop objects to get better chained paths
-    return @paths;
-}
-
-1;

+ 0 - 129
lib/Slic3r/Fill/Honeycomb.pm

@@ -1,129 +0,0 @@
-package Slic3r::Fill::Honeycomb;
-use Moo;
-
-extends 'Slic3r::Fill::Base';
-with qw(Slic3r::Fill::WithDirection);
-
-has 'cache'         => (is => 'rw', default => sub {{}});
-
-use Slic3r::Geometry qw(PI X Y MIN MAX scale scaled_epsilon);
-use Slic3r::Geometry::Clipper qw(intersection intersection_pl);
-
-sub angles () { [0, PI/3, PI/3*2] }
-
-sub fill_surface {
-    my $self = shift;
-    my ($surface, %params) = @_;
-    
-    my $rotate_vector = $self->infill_direction($surface);
-    
-    # cache hexagons math
-    my $cache_id = sprintf "d%s_s%s", $params{density}, $self->spacing;
-    my $m;
-    if (!($m = $self->cache->{$cache_id})) {
-        $m = $self->cache->{$cache_id} = {};
-        my $min_spacing = scale($self->spacing);
-        $m->{distance} = $min_spacing / $params{density};
-        $m->{hex_side} = $m->{distance} / (sqrt(3)/2);
-        $m->{hex_width} = $m->{distance} * 2;  # $m->{hex_width} == $m->{hex_side} * sqrt(3);
-        my $hex_height = $m->{hex_side} * 2;
-        $m->{pattern_height} = $hex_height + $m->{hex_side};
-        $m->{y_short} = $m->{distance} * sqrt(3)/3;
-        $m->{x_offset} = $min_spacing / 2;
-        $m->{y_offset} = $m->{x_offset} * sqrt(3)/3;
-        $m->{hex_center} = Slic3r::Point->new($m->{hex_width}/2, $m->{hex_side});
-    }
-    
-    my @polygons = ();
-    {
-        # adjust actual bounding box to the nearest multiple of our hex pattern
-        # and align it so that it matches across layers
-        
-        my $bounding_box = $surface->expolygon->bounding_box;
-        {
-            # rotate bounding box according to infill direction
-            my $bb_polygon = $bounding_box->polygon;
-            $bb_polygon->rotate($rotate_vector->[0][0], $m->{hex_center});
-            $bounding_box = $bb_polygon->bounding_box;
-            
-            # extend bounding box so that our pattern will be aligned with other layers
-            # $bounding_box->[X1] and [Y1] represent the displacement between new bounding box offset and old one
-            $bounding_box->merge_point(Slic3r::Point->new(
-                $bounding_box->x_min - ($bounding_box->x_min % $m->{hex_width}),
-                $bounding_box->y_min - ($bounding_box->y_min % $m->{pattern_height}),
-            ));
-        }
-        
-        my $x = $bounding_box->x_min;
-        while ($x <= $bounding_box->x_max) {
-            my $p = [];
-            
-            my @x = ($x + $m->{x_offset}, $x + $m->{distance} - $m->{x_offset});
-            for (1..2) {
-                @$p = reverse @$p; # turn first half upside down
-                my @p = ();
-                for (my $y = $bounding_box->y_min; $y <= $bounding_box->y_max; $y += $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side}) {
-                    push @$p,
-                        [ $x[1], $y + $m->{y_offset} ],
-                        [ $x[0], $y + $m->{y_short} - $m->{y_offset} ],
-                        [ $x[0], $y + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ],
-                        [ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} - $m->{y_offset} ],
-                        [ $x[1], $y + $m->{y_short} + $m->{hex_side} + $m->{y_short} + $m->{hex_side} + $m->{y_offset} ];
-                }
-                @x = map $_ + $m->{distance}, reverse @x; # draw symmetrical pattern
-                $x += $m->{distance};
-            }
-            
-            push @polygons, Slic3r::Polygon->new(@$p);
-        }
-        
-        $_->rotate(-$rotate_vector->[0][0], $m->{hex_center}) for @polygons;
-    }
-    
-    my @paths;
-    if ($params{complete} || 1) {
-        # we were requested to complete each loop;
-        # in this case we don't try to make more continuous paths
-        @paths = map $_->split_at_first_point,
-            @{intersection([ $surface->p ], \@polygons)};
-        
-    } else {
-        # consider polygons as polylines without re-appending the initial point:
-        # this cuts the last segment on purpose, so that the jump to the next 
-        # path is more straight
-        @paths = @{intersection_pl(
-            [ map Slic3r::Polyline->new(@$_), @polygons ],
-            [ @{$surface->expolygon} ],
-        )};
-        
-        # connect paths
-        if (@paths) {  # prevent calling leftmost_point() on empty collections
-            my $collection = Slic3r::Polyline::Collection->new(@paths);
-            @paths = ();
-            foreach my $path (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
-                if (@paths) {
-                    # distance between first point of this path and last point of last path
-                    my $distance = $paths[-1]->last_point->distance_to($path->first_point);
-                    
-                    if ($distance <= $m->{hex_width}) {
-                        $paths[-1]->append_polyline($path);
-                        next;
-                    }
-                }
-                
-                # make a clone before $collection goes out of scope
-                push @paths, $path->clone;
-            }
-        }
-        
-        # clip paths again to prevent connection segments from crossing the expolygon boundaries
-        @paths = @{intersection_pl(
-            \@paths,
-            [ map @$_, @{$surface->expolygon->offset_ex(scaled_epsilon)} ],
-        )};
-    }
-    
-    return @paths;
-}
-
-1;

+ 0 - 118
lib/Slic3r/Fill/PlanePath.pm

@@ -1,118 +0,0 @@
-package Slic3r::Fill::PlanePath;
-use Moo;
-
-extends 'Slic3r::Fill::Base';
-with qw(Slic3r::Fill::WithDirection);
-
-use Slic3r::Geometry qw(scale X1 Y1 X2 Y2);
-use Slic3r::Geometry::Clipper qw(intersection_pl);
-
-sub angles () { [0] }
-sub multiplier () { 1 }
-
-sub process_polyline {}
-
-sub fill_surface {
-    my $self = shift;
-    my ($surface, %params) = @_;
-    
-    # rotate polygons
-    my $expolygon = $surface->expolygon->clone;
-    my $rotate_vector = $self->infill_direction($surface);
-    $self->rotate_points($expolygon, $rotate_vector);
-    
-    my $distance_between_lines = scale($self->spacing) / $params{density} * $self->multiplier;
-    
-    # align infill across layers using the object's bounding box
-    my $bb_polygon = $self->bounding_box->polygon;
-    $self->rotate_points($bb_polygon, $rotate_vector);
-    my $bounding_box = $bb_polygon->bounding_box;
-    
-    (ref $self) =~ /::([^:]+)$/;
-    my $path = "Math::PlanePath::$1"->new;
-    
-    my $translate = Slic3r::Point->new(0,0);  # vector
-    if ($path->x_negative || $path->y_negative) {
-        # if the curve extends on both positive and negative coordinate space,
-        # center our expolygon around origin
-        $translate = $bounding_box->center->negative;
-    } else {
-        # if the curve does not extend in negative coordinate space,
-        # move expolygon entirely in positive coordinate space
-        $translate = $bounding_box->min_point->negative;
-    }
-    $expolygon->translate(@$translate);
-    $bounding_box->translate(@$translate);
-    
-    my ($n_lo, $n_hi) = $path->rect_to_n_range(
-        map { $_ / $distance_between_lines }
-            @{$bounding_box->min_point},
-            @{$bounding_box->max_point},
-    );
-    
-    my $polyline = Slic3r::Polyline->new(
-        map [ map { $_ * $distance_between_lines } $path->n_to_xy($_) ], ($n_lo..$n_hi)
-    );
-    return {} if @$polyline <= 1;
-    
-    $self->process_polyline($polyline, $bounding_box);
-    
-    my @paths = @{intersection_pl([$polyline], \@$expolygon)};
-    
-    if (0) {
-        require "Slic3r/SVG.pm";
-        Slic3r::SVG::output("fill.svg",
-            no_arrows       => 1,
-            polygons        => \@$expolygon,
-            green_polygons  => [ $bounding_box->polygon ],
-            polylines       => [ $polyline ],
-            red_polylines   => \@paths,
-        );
-    }
-    
-    # paths must be repositioned and rotated back
-    $_->translate(@{$translate->negative}) for @paths;
-    $self->rotate_points_back(\@paths, $rotate_vector);
-    
-    return @paths;
-}
-
-
-package Slic3r::Fill::ArchimedeanChords;
-use Moo;
-extends 'Slic3r::Fill::PlanePath';
-use Math::PlanePath::ArchimedeanChords;
-
-
-package Slic3r::Fill::Flowsnake;
-use Moo;
-extends 'Slic3r::Fill::PlanePath';
-use Math::PlanePath::Flowsnake;
-use Slic3r::Geometry qw(X);
-
-# Sorry, this fill is currently broken.
-
-sub process_polyline {
-    my $self = shift;
-    my ($polyline, $bounding_box) = @_;
-    
-    $_->[X] += $bounding_box->center->[X] for @$polyline;
-}
-
-
-package Slic3r::Fill::HilbertCurve;
-use Moo;
-extends 'Slic3r::Fill::PlanePath';
-use Math::PlanePath::HilbertCurve;
-
-
-package Slic3r::Fill::OctagramSpiral;
-use Moo;
-extends 'Slic3r::Fill::PlanePath';
-use Math::PlanePath::OctagramSpiral;
-
-sub multiplier () { sqrt(2) }
-
-
-
-1;

+ 0 - 172
lib/Slic3r/Fill/Rectilinear.pm

@@ -1,172 +0,0 @@
-package Slic3r::Fill::Rectilinear;
-use Moo;
-
-extends 'Slic3r::Fill::Base';
-with qw(Slic3r::Fill::WithDirection);
-
-has '_min_spacing'          => (is => 'rw');
-has '_line_spacing'         => (is => 'rw');
-has '_diagonal_distance'    => (is => 'rw');
-has '_line_oscillation'     => (is => 'rw');
-
-use Slic3r::Geometry qw(scale unscale scaled_epsilon);
-use Slic3r::Geometry::Clipper qw(intersection_pl);
-
-sub horizontal_lines { 0 }
-
-sub fill_surface {
-    my $self = shift;
-    my ($surface, %params) = @_;
-    
-    # rotate polygons so that we can work with vertical lines here
-    my $expolygon = $surface->expolygon->clone;
-    my $rotate_vector = $self->infill_direction($surface);
-    $self->rotate_points($expolygon, $rotate_vector);
-    
-    $self->_min_spacing(scale $self->spacing);
-    $self->_line_spacing($self->_min_spacing / $params{density});
-    $self->_diagonal_distance($self->_line_spacing * 2);
-    $self->_line_oscillation($self->_line_spacing - $self->_min_spacing);  # only for Line infill
-    my $bounding_box = $expolygon->bounding_box;
-    
-    # define flow spacing according to requested density
-    if ($params{density} == 1 && !$params{dont_adjust}) {
-        my $old_spacing = $self->spacing;
-        $self->_line_spacing($self->adjust_solid_spacing(
-            width       => $bounding_box->size->x,
-            distance    => $self->_line_spacing,
-        ));
-        $self->spacing(unscale $self->_line_spacing);
-        if (abs($old_spacing - $self->spacing) > 0.3 * $old_spacing) {
-            print "Infill2: Extreme spacing adjustment, from: ", $old_spacing, " to: ", $self->spacing, "\n";
-        }
-    } else {
-        # extend bounding box so that our pattern will be aligned with other layers
-        $bounding_box->merge_point(Slic3r::Point->new(
-            $bounding_box->x_min - ($bounding_box->x_min % $self->_line_spacing),
-            $bounding_box->y_min - ($bounding_box->y_min % $self->_line_spacing),
-        ));
-    }
-    
-    # generate the basic pattern
-    my $x_max = $bounding_box->x_max + scaled_epsilon;
-    my @lines  = ();
-    for (my $x = $bounding_box->x_min; $x <= $x_max; $x += $self->_line_spacing) {
-        push @lines, $self->_line($#lines, $x, $bounding_box->y_min, $bounding_box->y_max);
-    }
-    if ($self->horizontal_lines) {
-        my $y_max = $bounding_box->y_max + scaled_epsilon;
-        for (my $y = $bounding_box->y_min; $y <= $y_max; $y += $self->_line_spacing) {
-            push @lines, Slic3r::Polyline->new(
-                [$bounding_box->x_min, $y],
-                [$bounding_box->x_max, $y],
-            );
-        }
-    }
-    
-    # clip paths against a slightly larger expolygon, so that the first and last paths
-    # are kept even if the expolygon has vertical sides
-    # the minimum offset for preventing edge lines from being clipped is scaled_epsilon;
-    # however we use a larger offset to support expolygons with slightly skewed sides and 
-    # not perfectly straight
-    my @polylines = @{intersection_pl(\@lines, $expolygon->offset(+scale 0.02))};
-    
-    my $extra = $self->_min_spacing * &Slic3r::INFILL_OVERLAP_OVER_SPACING;
-    foreach my $polyline (@polylines) {
-        my ($first_point, $last_point) = @$polyline[0,-1];
-        if ($first_point->y > $last_point->y) { #>
-            ($first_point, $last_point) = ($last_point, $first_point);
-        }
-        $first_point->set_y($first_point->y - $extra);  #--
-        $last_point->set_y($last_point->y + $extra);    #++
-    }
-    
-    # connect lines
-    unless ($params{dont_connect} || !@polylines) {  # prevent calling leftmost_point() on empty collections
-        # offset the expolygon by max(min_spacing/2, extra)
-        my ($expolygon_off) = @{$expolygon->offset_ex($self->_min_spacing/2)};
-        my $collection = Slic3r::Polyline::Collection->new(@polylines);
-        @polylines = ();
-        
-        foreach my $polyline (@{$collection->chained_path_from($collection->leftmost_point, 0)}) {
-            if (@polylines) {
-                my $first_point = $polyline->first_point;
-                my $last_point = $polylines[-1]->last_point;
-                my @distance = map abs($first_point->$_ - $last_point->$_), qw(x y);
-                
-                # TODO: we should also check that both points are on a fill_boundary to avoid 
-                # connecting paths on the boundaries of internal regions
-                if ($self->_can_connect(@distance) && $expolygon_off->contains_line(Slic3r::Line->new($last_point, $first_point))) {
-                    $polylines[-1]->append_polyline($polyline);
-                    next;
-                }
-            }
-            
-            # make a clone before $collection goes out of scope
-            push @polylines, $polyline->clone;
-        }
-    }
-    
-    # paths must be rotated back
-    $self->rotate_points_back(\@polylines, $rotate_vector);
-    
-    return @polylines;
-}
-
-sub _line {
-    my ($self, $i, $x, $y_min, $y_max) = @_;
-    
-    return Slic3r::Polyline->new(
-        [$x, $y_min],
-        [$x, $y_max],
-    );
-}
-
-sub _can_connect {
-    my ($self, $dist_X, $dist_Y) = @_;
-    
-    return $dist_X <= $self->_diagonal_distance
-        && $dist_Y <= $self->_diagonal_distance;
-}
-
-
-package Slic3r::Fill::Line;
-use Moo;
-extends 'Slic3r::Fill::Rectilinear';
-
-use Slic3r::Geometry qw(scaled_epsilon);
-
-sub _line {
-    my ($self, $i, $x, $y_min, $y_max) = @_;
-    
-    if ($i % 2) {
-        return Slic3r::Polyline->new(
-            [$x - $self->_line_oscillation, $y_min],
-            [$x + $self->_line_oscillation, $y_max],
-        );
-    } else {
-        return Slic3r::Polyline->new(
-            [$x, $y_min],
-            [$x, $y_max],
-        );
-    }
-}
-
-sub _can_connect {
-    my ($self, $dist_X, $dist_Y) = @_;
-    
-    my $TOLERANCE = 10 * scaled_epsilon;
-    return ($dist_X >= ($self->_line_spacing - $self->_line_oscillation) - $TOLERANCE)
-        && ($dist_X <= ($self->_line_spacing + $self->_line_oscillation) + $TOLERANCE)
-        && $dist_Y <= $self->_diagonal_distance;
-}
-
-
-package Slic3r::Fill::Grid;
-use Moo;
-extends 'Slic3r::Fill::Rectilinear';
-
-sub angles () { [0] }
-sub horizontal_lines { 1 }
-
-1;

+ 0 - 294
lib/Slic3r/Fill2.pm

@@ -1,294 +0,0 @@
-# This is derived from Fill.pm
-# and it uses the C++ fillers.
-package Slic3r::Fill2;
-use Moo;
-
-use List::Util qw(max);
-use Slic3r::ExtrusionPath ':roles';
-
-use Slic3r::Flow ':roles';
-use Slic3r::Geometry qw(X Y PI scale chained_path deg2rad);
-use Slic3r::Geometry::Clipper qw(union union_ex diff diff_ex intersection_ex offset offset2);
-use Slic3r::Surface ':types';
-
-has 'bounding_box' => (is => 'ro', required => 0);
-has 'fillers'   => (is => 'rw', default => sub { {} });
-
-sub filler {
-    my $self = shift;
-    my ($filler) = @_;
-    
-    if (!ref $self) {
-       return Slic3r::Filler->new_from_type($filler);
-    }
-
-    #print "Filler: ", $filler, "\n";
-    $self->fillers->{$filler} ||= Slic3r::Filler->new_from_type($filler);
-    $self->fillers->{$filler}->set_bounding_box($self->bounding_box);
-    return $self->fillers->{$filler};
-}
-
-
-# Generate infills for Slic3r::Layer::Region.
-# The Slic3r::Layer::Region at this point of time may contain
-# surfaces of various types (internal/bridge/top/bottom/solid).
-# The infills are generated on the groups of surfaces with a compatible type. 
-# Returns an array of Slic3r::ExtrusionPath::Collection objects containing the infills generaed now
-# and the thin fills generated by generate_perimeters().
-sub make_fill {
-    my $self = shift;
-    # of type - C++: LayerRegion, Perl: Slic3r::Layer::Region
-    my ($layerm) = @_;
-    
-    Slic3r::debugf "Filling layer %d:\n", $layerm->layer->id;
-    
-    my $fill_density            = $layerm->region->config->fill_density;
-    my $infill_flow             = $layerm->flow(FLOW_ROLE_INFILL);
-    my $solid_infill_flow       = $layerm->flow(FLOW_ROLE_SOLID_INFILL);
-    my $top_solid_infill_flow   = $layerm->flow(FLOW_ROLE_TOP_SOLID_INFILL);
-    
-    # Surfaces are of the type Slic3r::Surface
-    my @surfaces = ();
-    
-    # merge adjacent surfaces
-    # in case of bridge surfaces, the ones with defined angle will be attached to the ones
-    # without any angle (shouldn't this logic be moved to process_external_surfaces()?)
-    {
-        my @surfaces_with_bridge_angle = grep { $_->bridge_angle >= 0 } @{$layerm->fill_surfaces};
-        
-        # group surfaces by distinct properties
-        # group is of type Slic3r::SurfaceCollection
-        my @groups = @{$layerm->fill_surfaces->group};
-        
-        # merge compatible groups (we can generate continuous infill for them)
-        {
-            # cache flow widths and patterns used for all solid groups
-            # (we'll use them for comparing compatible groups)
-            my @is_solid = my @fw = my @pattern = ();
-            for (my $i = 0; $i <= $#groups; $i++) {
-                # we can only merge solid non-bridge surfaces, so discard
-                # non-solid surfaces
-                if ($groups[$i][0]->is_solid && (!$groups[$i][0]->is_bridge || $layerm->layer->id == 0)) {
-                    $is_solid[$i] = 1;
-                    $fw[$i] = ($groups[$i][0]->surface_type == S_TYPE_TOP)
-                        ? $top_solid_infill_flow->width
-                        : $solid_infill_flow->width;
-                    $pattern[$i] = $groups[$i][0]->is_external
-                        ? $layerm->region->config->external_fill_pattern
-                        : 'rectilinear';
-                } else {
-                    $is_solid[$i]   = 0;
-                    $fw[$i]         = 0;
-                    $pattern[$i]    = 'none';
-                }
-            }
-            
-            # loop through solid groups
-            for (my $i = 0; $i <= $#groups; $i++) {
-                next if !$is_solid[$i];
-                
-                # find compatible groups and append them to this one
-                for (my $j = $i+1; $j <= $#groups; $j++) {
-                    next if !$is_solid[$j];
-                
-                    if ($fw[$i] == $fw[$j] && $pattern[$i] eq $pattern[$j]) {
-                        # groups are compatible, merge them
-                        push @{$groups[$i]}, @{$groups[$j]};
-                        splice @groups,     $j, 1;
-                        splice @is_solid,   $j, 1;
-                        splice @fw,         $j, 1;
-                        splice @pattern,    $j, 1;
-                    }
-                }
-            }
-        }
-        
-        # give priority to bridges
-        @groups = sort { ($a->[0]->bridge_angle >= 0) ? -1 : 0 } @groups;
-        
-        foreach my $group (@groups) {
-            # Make a union of polygons defining the infiill regions of a group, use a safety offset.
-            my $union_p = union([ map $_->p, @$group ], 1);
-            
-            # Subtract surfaces having a defined bridge_angle from any other, use a safety offset.
-            if (@surfaces_with_bridge_angle && $group->[0]->bridge_angle < 0) {
-                $union_p = diff(
-                    $union_p,
-                    [ map $_->p, @surfaces_with_bridge_angle ],
-                    1,
-                );
-            }
-            
-            # subtract any other surface already processed
-            #FIXME Vojtech: Because the bridge surfaces came first, they are subtracted twice!
-            my $union = diff_ex(
-                $union_p,
-                [ map $_->p, @surfaces ],
-                1,
-            );
-            
-            push @surfaces, map $group->[0]->clone(expolygon => $_), @$union;
-        }
-    }
-    
-    # we need to detect any narrow surfaces that might collapse
-    # when adding spacing below
-    # such narrow surfaces are often generated in sloping walls
-    # by bridge_over_infill() and combine_infill() as a result of the
-    # subtraction of the combinable area from the layer infill area,
-    # which leaves small areas near the perimeters
-    # we are going to grow such regions by overlapping them with the void (if any)
-    # TODO: detect and investigate whether there could be narrow regions without
-    # any void neighbors
-    {
-        my $distance_between_surfaces = max(
-            $infill_flow->scaled_spacing,
-            $solid_infill_flow->scaled_spacing,
-            $top_solid_infill_flow->scaled_spacing,
-        );
-        my $collapsed = diff(
-            [ map @{$_->expolygon}, @surfaces ],
-            offset2([ map @{$_->expolygon}, @surfaces ], -$distance_between_surfaces/2, +$distance_between_surfaces/2),
-            1,
-        );
-        push @surfaces, map Slic3r::Surface->new(
-            expolygon       => $_,
-            surface_type    => S_TYPE_INTERNALSOLID,
-        ), @{intersection_ex(
-            offset($collapsed, $distance_between_surfaces),
-            [
-                (map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNALVOID, @surfaces),
-                (@$collapsed),
-            ],
-            1,
-        )};
-    }
-    
-    if (0) {
-        require "Slic3r/SVG.pm";
-        Slic3r::SVG::output("fill_" . $layerm->print_z . ".svg",
-            expolygons      => [ map $_->expolygon, grep !$_->is_solid, @surfaces ],
-            red_expolygons  => [ map $_->expolygon, grep  $_->is_solid, @surfaces ],
-        );
-    }
-    
-    # Fills are of perl type Slic3r::ExtrusionPath::Collection, c++ type ExtrusionEntityCollection
-    my @fills = ();
-    SURFACE: foreach my $surface (@surfaces) {
-        next if $surface->surface_type == S_TYPE_INTERNALVOID;
-        my $filler          = $layerm->region->config->fill_pattern;
-        my $density         = $fill_density;
-        my $role = ($surface->surface_type == S_TYPE_TOP) ? FLOW_ROLE_TOP_SOLID_INFILL
-            : $surface->is_solid ? FLOW_ROLE_SOLID_INFILL
-            : FLOW_ROLE_INFILL;
-        my $is_bridge       = $layerm->layer->id > 0 && $surface->is_bridge;
-        my $is_solid        = $surface->is_solid;
-        
-        if ($surface->is_solid) {
-            $density = 100;
-            $filler = 'rectilinear';
-            if ($surface->is_external && !$is_bridge) {
-                $filler = $layerm->region->config->external_fill_pattern;
-            }
-        } else {
-            next SURFACE unless $density > 0;
-        }
-        
-        # get filler object
-        my $f = $self->filler($filler);
-        
-        # calculate the actual flow we'll be using for this infill
-        my $h = $surface->thickness == -1 ? $layerm->layer->height : $surface->thickness;
-        my $flow = $layerm->region->flow(
-            $role,
-            $h,
-            $is_bridge || $f->use_bridge_flow,
-            $layerm->layer->id == 0,
-            -1,
-            $layerm->layer->object,
-        );
-        
-        # calculate flow spacing for infill pattern generation
-        my $using_internal_flow = 0;
-        if (!$is_solid && !$is_bridge) {
-            # it's internal infill, so we can calculate a generic flow spacing 
-            # for all layers, for avoiding the ugly effect of
-            # misaligned infill on first layer because of different extrusion width and
-            # layer height
-            my $internal_flow = $layerm->region->flow(
-                FLOW_ROLE_INFILL,
-                $layerm->layer->object->config->layer_height,  # TODO: handle infill_every_layers?
-                0,  # no bridge
-                0,  # no first layer
-                -1, # auto width
-                $layerm->layer->object,
-            );
-            $f->set_spacing($internal_flow->spacing);
-            $using_internal_flow = 1;
-        } else {
-            $f->set_spacing($flow->spacing);
-        }
-        
-        $f->set_layer_id($layerm->layer->id);
-        $f->set_z($layerm->layer->print_z);
-        $f->set_angle(deg2rad($layerm->region->config->fill_angle));
-        $f->set_loop_clipping(scale($flow->nozzle_diameter) * &Slic3r::LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER);
-        
-        # apply half spacing using this flow's own spacing and generate infill
-        my @polylines = $f->fill_surface(
-            $surface,
-            density         => $density/100,
-            layer_height    => $h,
-        );
-        next unless @polylines;
-
-        
-        # calculate actual flow from spacing (which might have been adjusted by the infill
-        # pattern generator)
-        if ($using_internal_flow) {
-            # if we used the internal flow we're not doing a solid infill
-            # so we can safely ignore the slight variation that might have
-            # been applied to $f->flow_spacing
-        } else {
-            $flow = Slic3r::Flow->new_from_spacing(
-                spacing         => $f->spacing,
-                nozzle_diameter => $flow->nozzle_diameter,
-                layer_height    => $h,
-                bridge          => $is_bridge || $f->use_bridge_flow,
-            );
-        }
-
-        # save into layer
-        {
-            my $role = $is_bridge ? EXTR_ROLE_BRIDGE
-                : $is_solid ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL)
-                : EXTR_ROLE_FILL;
-            
-            push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new;
-            # Only concentric fills are not sorted.
-            $collection->no_sort($f->no_sort);
-            $collection->append(
-                map Slic3r::ExtrusionPath->new(
-                    polyline    => $_,
-                    role        => $role,
-                    mm3_per_mm  => $flow->mm3_per_mm,
-                    width       => $flow->width,
-                    height      => $flow->height,
-                ), map @$_, @polylines,
-            );
-        }
-    }
-    
-    # add thin fill regions
-    # thin_fills are of C++ Slic3r::ExtrusionEntityCollection, perl type Slic3r::ExtrusionPath::Collection
-    # Unpacks the collection, creates multiple collections per path.
-    # The path type could be ExtrusionPath, ExtrusionLoop or ExtrusionEntityCollection.
-    # Why the paths are unpacked?
-    foreach my $thin_fill (@{$layerm->thin_fills}) {
-        push @fills, Slic3r::ExtrusionPath::Collection->new($thin_fill);
-    }
-    
-    return @fills;
-}
-
-1;

Some files were not shown because too many files changed in this diff