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