Refactor/clean up. Merge remove_small_surfaces() into prepare_fill_surfaces(), rename infill_every_layers() to combine_infill(), remove $layer->fill_boundaries, initialize layer properties explicitely for clarity.
This commit is contained in:
parent
a5d683a9b9
commit
1d04e15b63
3 changed files with 47 additions and 74 deletions
|
@ -25,60 +25,36 @@ has 'infill_flow' => (is => 'lazy');
|
|||
|
||||
# collection of spare segments generated by slicing the original geometry;
|
||||
# these need to be merged in continuos (closed) polylines
|
||||
has 'lines' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[ArrayRef]',
|
||||
default => sub { [] },
|
||||
);
|
||||
has 'lines' => (is => 'rw', default => sub { [] });
|
||||
|
||||
# collection of surfaces generated by slicing the original geometry
|
||||
has 'slices' => (is => 'ro', default => sub { [] });
|
||||
has 'slices' => (is => 'rw');
|
||||
|
||||
# collection of polygons or polylines representing thin walls contained
|
||||
# in the original geometry
|
||||
has 'thin_walls' => (is => 'ro', default => sub { [] });
|
||||
|
||||
# collection of expolygons generated by offsetting the innermost perimeter(s)
|
||||
# they represent boundaries of areas to fill
|
||||
has 'fill_boundaries' => (is => 'ro', default => sub { [] });
|
||||
has 'thin_walls' => (is => 'rw');
|
||||
|
||||
# collection of polygons or polylines representing thin infill regions that
|
||||
# need to be filled with a medial axis
|
||||
has 'thin_fills' => (is => 'ro', default => sub { [] });
|
||||
has 'thin_fills' => (is => 'rw');
|
||||
|
||||
# collection of surfaces generated by clipping the slices to the fill boundaries
|
||||
has 'surfaces' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[Slic3r::Surface]',
|
||||
default => sub { [] },
|
||||
);
|
||||
# collection of expolygons generated by offsetting the innermost perimeter(s)
|
||||
# they represent boundaries of areas to fill, typed (top/bottom/internal)
|
||||
has 'surfaces' => (is => 'rw');
|
||||
|
||||
# collection of surfaces for infill
|
||||
has 'fill_surfaces' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[Slic3r::Surface]',
|
||||
default => sub { [] },
|
||||
);
|
||||
# collection of surfaces for infill generation. the difference between surfaces
|
||||
# fill_surfaces is that this one honors fill_density == 0 and turns small internal
|
||||
# surfaces into solid ones
|
||||
has 'fill_surfaces' => (is => 'rw');
|
||||
|
||||
# ordered collection of extrusion paths to build all perimeters
|
||||
has 'perimeters' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[Slic3r::ExtrusionLoop]',
|
||||
default => sub { [] },
|
||||
);
|
||||
# ordered collection of extrusion paths/loops to build all perimeters
|
||||
has 'perimeters' => (is => 'rw');
|
||||
|
||||
# ordered collection of extrusion paths to fill surfaces for support material
|
||||
has 'support_fills' => (
|
||||
is => 'rw',
|
||||
#isa => 'Slic3r::ExtrusionPath::Collection',
|
||||
);
|
||||
has 'support_fills' => (is => 'rw');
|
||||
|
||||
# ordered collection of extrusion paths to fill surfaces
|
||||
has 'fills' => (
|
||||
is => 'rw',
|
||||
#isa => 'ArrayRef[Slic3r::ExtrusionPath::Collection]',
|
||||
default => sub { [] },
|
||||
);
|
||||
has 'fills' => (is => 'rw');
|
||||
|
||||
# Z used for slicing
|
||||
sub _build_slice_z {
|
||||
|
@ -123,14 +99,6 @@ sub _build_infill_flow {
|
|||
: $Slic3r::infill_flow;
|
||||
}
|
||||
|
||||
sub add_line {
|
||||
my $self = shift;
|
||||
my ($line) = @_;
|
||||
|
||||
push @{ $self->lines }, $line;
|
||||
return $line;
|
||||
}
|
||||
|
||||
# build polylines from lines
|
||||
sub make_surfaces {
|
||||
my $self = shift;
|
||||
|
@ -144,9 +112,10 @@ sub make_surfaces {
|
|||
Slic3r::debugf " %d surface(s) having %d holes detected from %d polylines\n",
|
||||
scalar(@$expolygons), scalar(map $_->holes, @$expolygons), scalar(@$loops);
|
||||
|
||||
push @{$self->slices},
|
||||
$self->slices([
|
||||
map Slic3r::Surface->new(expolygon => $_, surface_type => S_TYPE_INTERNAL),
|
||||
@$expolygons;
|
||||
@$expolygons
|
||||
]);
|
||||
}
|
||||
|
||||
# the contours must be offsetted by half extrusion width inwards
|
||||
|
@ -170,13 +139,12 @@ sub make_surfaces {
|
|||
1,
|
||||
);
|
||||
|
||||
$self->thin_walls([]);
|
||||
if (@$diff) {
|
||||
my $area_threshold = scale($self->perimeters_flow->spacing) ** 2;
|
||||
@$diff = grep $_->area > ($area_threshold), @$diff;
|
||||
|
||||
push @{$self->thin_walls},
|
||||
map $_->medial_axis(scale $self->perimeters_flow->width),
|
||||
@$diff;
|
||||
@{$self->thin_walls} = map $_->medial_axis(scale $self->perimeters_flow->width), @$diff;
|
||||
|
||||
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
|
||||
}
|
||||
|
@ -216,6 +184,10 @@ sub make_perimeters {
|
|||
map [ $_->contour->[0], $_ ], @{$self->slices},
|
||||
])};
|
||||
|
||||
$self->perimeters([]);
|
||||
$self->surfaces([]);
|
||||
$self->thin_fills([]);
|
||||
|
||||
# for each island:
|
||||
foreach my $surface (@surfaces) {
|
||||
my @last_offsets = ($surface->expolygon);
|
||||
|
@ -276,7 +248,7 @@ sub make_perimeters {
|
|||
{
|
||||
my @fill_boundaries = map $_->offset_ex(-$distance), @last_offsets;
|
||||
$_->simplify(scale $Slic3r::resolution) for @fill_boundaries;
|
||||
push @{ $self->fill_boundaries }, @fill_boundaries;
|
||||
push @{ $self->surfaces }, @fill_boundaries;
|
||||
|
||||
# detect the small gaps that we need to treat like thin polygons,
|
||||
# thus generating the skeleton and using it to fill them
|
||||
|
@ -336,13 +308,13 @@ sub make_perimeters {
|
|||
}
|
||||
|
||||
# do holes, then contours starting from innermost one
|
||||
$self->add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef)
|
||||
$self->_add_perimeter($holes[$_], $is_external{$_} ? EXTR_ROLE_EXTERNAL_PERIMETER : undef)
|
||||
for reverse 0 .. $#holes;
|
||||
for my $depth (reverse 0 .. $#$island) {
|
||||
my $role = $depth == $#$island ? EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER
|
||||
: $depth == 0 ? EXTR_ROLE_EXTERNAL_PERIMETER
|
||||
: EXTR_ROLE_PERIMETER;
|
||||
$self->add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]};
|
||||
$self->_add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,7 +335,7 @@ sub make_perimeters {
|
|||
}
|
||||
}
|
||||
|
||||
sub add_perimeter {
|
||||
sub _add_perimeter {
|
||||
my $self = shift;
|
||||
my ($polygon, $role) = @_;
|
||||
|
||||
|
@ -381,6 +353,7 @@ sub prepare_fill_surfaces {
|
|||
my @surfaces = @{$self->surfaces};
|
||||
|
||||
# if no solid layers are requested, turn top/bottom surfaces to internal
|
||||
# note that this modifies $self->surfaces in place
|
||||
if ($Slic3r::solid_layers == 0) {
|
||||
$_->surface_type(S_TYPE_INTERNAL) for grep $_->surface_type != S_TYPE_INTERNAL, @surfaces;
|
||||
}
|
||||
|
@ -414,6 +387,7 @@ sub prepare_fill_surfaces {
|
|||
# (those that are too tight for extrusion)
|
||||
{
|
||||
my $distance = scale $self->infill_flow->spacing / 2;
|
||||
my @fill_surfaces = ();
|
||||
|
||||
foreach my $surface (@surfaces) {
|
||||
# offset inwards
|
||||
|
@ -423,25 +397,26 @@ sub prepare_fill_surfaces {
|
|||
@offsets = map $_->offset_ex($distance), @offsets;
|
||||
@offsets = @{ union_ex([ map @$_, @offsets ], undef, 1) };
|
||||
|
||||
push @{$self->fill_surfaces}, map Slic3r::Surface->new(
|
||||
push @fill_surfaces, map Slic3r::Surface->new(
|
||||
expolygon => $_,
|
||||
surface_type => $surface->surface_type), @offsets;
|
||||
}
|
||||
|
||||
Slic3r::debugf "identified %d small surfaces at layer %d\n",
|
||||
(@surfaces - @{$self->fill_surfaces}), $self->id
|
||||
if @{$self->fill_surfaces} != @surfaces;
|
||||
(@surfaces - @fill_surfaces), $self->id
|
||||
if @fill_surfaces != @surfaces;
|
||||
|
||||
# the difference between @surfaces and $self->fill_surfaces
|
||||
# is what's too small; we add it back as solid infill
|
||||
if ($Slic3r::fill_density > 0) {
|
||||
my $diff = diff_ex(
|
||||
[ map $_->p, @surfaces ],
|
||||
[ map $_->p, @{$self->fill_surfaces} ],
|
||||
[ map $_->p, @fill_surfaces ],
|
||||
);
|
||||
push @{$self->fill_surfaces}, map Slic3r::Surface->new(
|
||||
push @surfaces, map Slic3r::Surface->new(
|
||||
expolygon => $_,
|
||||
surface_type => S_TYPE_INTERNALSOLID), @$diff;
|
||||
surface_type => S_TYPE_INTERNALSOLID
|
||||
), @$diff;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,11 +252,11 @@ sub export_gcode {
|
|||
$_->discover_horizontal_shells for @{$self->objects};
|
||||
|
||||
# free memory
|
||||
@{$_->surfaces} = () for map @{$_->layers}, @{$self->objects};
|
||||
$_->surfaces(undef) for map @{$_->layers}, @{$self->objects};
|
||||
|
||||
# combine fill surfaces to honor the "infill every N layers" option
|
||||
$status_cb->(70, "Combining infill");
|
||||
$_->infill_every_layers for @{$self->objects};
|
||||
$_->combine_infill for @{$self->objects};
|
||||
|
||||
# this will generate extrusion paths for each layer
|
||||
$status_cb->(80, "Infilling layers");
|
||||
|
@ -284,13 +284,13 @@ sub export_gcode {
|
|||
my $fills = shift;
|
||||
foreach my $obj_idx (keys %$fills) {
|
||||
foreach my $layer_id (keys %{$fills->{$obj_idx}}) {
|
||||
@{$self->objects->[$obj_idx]->layers->[$layer_id]->fills} = @{$fills->{$obj_idx}{$layer_id}};
|
||||
$self->objects->[$obj_idx]->layers->[$layer_id]->fills($fills->{$obj_idx}{$layer_id});
|
||||
}
|
||||
}
|
||||
},
|
||||
no_threads_cb => sub {
|
||||
foreach my $layer (map @{$_->layers}, @{$self->objects}) {
|
||||
@{$layer->fills} = $fill_maker->make_fill($layer);
|
||||
$layer->fills([ $fill_maker->make_fill($layer) ]);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -303,7 +303,7 @@ sub export_gcode {
|
|||
}
|
||||
|
||||
# free memory (note that support material needs fill_surfaces)
|
||||
@{$_->fill_surfaces} = () for map @{$_->layers}, @{$self->objects};
|
||||
$_->fill_surfaces(undef) for map @{$_->layers}, @{$self->objects};
|
||||
|
||||
# make skirt
|
||||
$status_cb->(88, "Generating skirt");
|
||||
|
|
|
@ -48,7 +48,7 @@ sub slice {
|
|||
my $lines = shift;
|
||||
foreach my $layer_id (keys %$lines) {
|
||||
my $layer = $self->layer($layer_id);
|
||||
$layer->add_line($_) for @{ $lines->{$layer_id} };
|
||||
push @{$layer->lines}, @{$lines->{$layer_id}};
|
||||
}
|
||||
};
|
||||
Slic3r::parallelize(
|
||||
|
@ -84,7 +84,7 @@ sub slice {
|
|||
|
||||
# remove last layer if empty
|
||||
# (we might have created it because of the $max_layer = ... + 1 code below)
|
||||
pop @{$self->layers} if !@{$self->layers->[-1]->surfaces} && !@{$self->layers->[-1]->lines};
|
||||
pop @{$self->layers} if !@{$self->layers->[-1]->lines};
|
||||
|
||||
foreach my $layer (@{ $self->layers }) {
|
||||
Slic3r::debugf "Making surfaces for layer %d (slice z = %f):\n",
|
||||
|
@ -291,19 +291,17 @@ sub detect_surfaces_type {
|
|||
|
||||
# clip surfaces to the fill boundaries
|
||||
foreach my $layer (@{$self->layers}) {
|
||||
my $fill_boundaries = [ map @$_, @{$layer->surfaces} ];
|
||||
@{$layer->surfaces} = ();
|
||||
foreach my $surface (@{$layer->slices}) {
|
||||
my $intersection = intersection_ex(
|
||||
[ $surface->p ],
|
||||
[ map @$_, @{$layer->fill_boundaries} ],
|
||||
$fill_boundaries,
|
||||
);
|
||||
push @{$layer->surfaces}, map Slic3r::Surface->new
|
||||
(expolygon => $_, surface_type => $surface->surface_type),
|
||||
@$intersection;
|
||||
}
|
||||
|
||||
# free memory
|
||||
@{$layer->fill_boundaries} = ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,7 +392,7 @@ sub discover_horizontal_shells {
|
|||
}
|
||||
|
||||
# combine fill surfaces across layers
|
||||
sub infill_every_layers {
|
||||
sub combine_infill {
|
||||
my $self = shift;
|
||||
return unless $Slic3r::infill_every_layers > 1 && $Slic3r::fill_density > 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue