Perimeters refactoring complete
This commit is contained in:
parent
67b24efd49
commit
ca549cd2fe
@ -146,7 +146,7 @@ sub simplify_polygons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub traverse_pt {
|
sub traverse_pt {
|
||||||
my ($polynodes, $min_depth, $max_depth) = @_;
|
my ($polynodes) = @_;
|
||||||
|
|
||||||
# use a nearest neighbor search to order these children
|
# use a nearest neighbor search to order these children
|
||||||
# TODO: supply second argument to chained_path_items() too?
|
# TODO: supply second argument to chained_path_items() too?
|
||||||
@ -157,13 +157,8 @@ sub traverse_pt {
|
|||||||
my @polygons = ();
|
my @polygons = ();
|
||||||
foreach my $polynode (@$polynodes) {
|
foreach my $polynode (@$polynodes) {
|
||||||
# traverse the next depth
|
# traverse the next depth
|
||||||
push @polygons, traverse_pt(
|
push @polygons, traverse_pt($polynode->{children});
|
||||||
$polynode->{children},
|
push @polygons, $polynode->{outer} // [ reverse @{$polynode->{hole}} ];
|
||||||
(defined $min_depth ? $min_depth-1 : undef),
|
|
||||||
(defined $max_depth ? $max_depth-1 : undef),
|
|
||||||
) if !defined $max_depth || $max_depth >= 1;
|
|
||||||
push @polygons, $polynode->{outer} // [ reverse @{$polynode->{hole}} ]
|
|
||||||
if !defined $min_depth || $min_depth <= 0;
|
|
||||||
}
|
}
|
||||||
return @polygons;
|
return @polygons;
|
||||||
}
|
}
|
||||||
|
@ -335,38 +335,62 @@ sub make_perimeters {
|
|||||||
my $contours_pt = union_pt(\@contours, PFT_EVENODD);
|
my $contours_pt = union_pt(\@contours, PFT_EVENODD);
|
||||||
my $holes_pt = union_pt(\@holes, PFT_EVENODD);
|
my $holes_pt = union_pt(\@holes, PFT_EVENODD);
|
||||||
|
|
||||||
# find external perimeters
|
# prepare a coderef for traversing the PolyTree object
|
||||||
my $other_contours_pt = [ ];
|
|
||||||
|
|
||||||
# external contours are root items of $contours_pt
|
# external contours are root items of $contours_pt
|
||||||
# internal contours are the ones next to external
|
# internal contours are the ones next to external
|
||||||
my @external_contours = map $self->_perimeter($_, EXTR_ROLE_EXTERNAL_PERIMETER), traverse_pt($contours_pt, 0, 0);
|
my $traverse;
|
||||||
my @internal_contours = map $self->_perimeter($_, EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER), traverse_pt($contours_pt, 1, 1);
|
$traverse = sub {
|
||||||
my @other_contours = map $self->_perimeter($_), traverse_pt($contours_pt, 2);
|
my ($polynodes, $depth, $is_contour) = @_;
|
||||||
my @external_holes = map $self->_perimeter($_, EXTR_ROLE_EXTERNAL_PERIMETER), traverse_pt($holes_pt, 0, 0);
|
|
||||||
my @other_holes = map $self->_perimeter($_), traverse_pt($holes_pt, 1);
|
|
||||||
|
|
||||||
my @loops = (
|
# use a nearest neighbor search to order these children
|
||||||
@other_holes,
|
# TODO: supply second argument to chained_path_items() too?
|
||||||
@external_holes,
|
my @nodes = @{Slic3r::Geometry::chained_path_items(
|
||||||
@other_contours,
|
[ map [ ($_->{outer} ? $_->{outer}[0] : $_->{hole}[0]), $_ ], @$polynodes ],
|
||||||
@internal_contours,
|
)};
|
||||||
@external_contours,
|
|
||||||
);
|
|
||||||
@loops = reverse @loops if $Slic3r::Config->external_perimeters_first;
|
|
||||||
|
|
||||||
push @{ $self->perimeters }, @loops;
|
my @loops = ();
|
||||||
}
|
foreach my $polynode (@$polynodes) {
|
||||||
|
push @loops, $traverse->($polynode->{children}, $depth+1, $is_contour);
|
||||||
|
|
||||||
sub _perimeter {
|
my $role = EXTR_ROLE_PERIMETER;
|
||||||
my $self = shift;
|
if ($depth == 0) {
|
||||||
my ($polygon, $role) = @_;
|
$role = EXTR_ROLE_EXTERNAL_PERIMETER;
|
||||||
|
} elsif ($depth == 1 && $is_contour) {
|
||||||
return Slic3r::ExtrusionLoop->pack(
|
$role = EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER;
|
||||||
polygon => Slic3r::Polygon->new($polygon),
|
}
|
||||||
role => ($role // EXTR_ROLE_PERIMETER),
|
push @loops, Slic3r::ExtrusionLoop->pack(
|
||||||
|
polygon => Slic3r::Polygon->new($polynode->{outer} // [ reverse @{$polynode->{hole}} ]),
|
||||||
|
role => $role,
|
||||||
flow_spacing => $self->perimeter_flow->spacing,
|
flow_spacing => $self->perimeter_flow->spacing,
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
return @loops;
|
||||||
|
};
|
||||||
|
|
||||||
|
# order loops from inner to outer (in terms of object slices)
|
||||||
|
my @loops = (
|
||||||
|
(reverse $traverse->($holes_pt, 0)),
|
||||||
|
$traverse->($contours_pt, 0, 1),
|
||||||
|
);
|
||||||
|
|
||||||
|
# if brim will be printed, reverse the order of perimeters so that
|
||||||
|
# we continue inwards after having finished the brim
|
||||||
|
# TODO: add test for perimeter order
|
||||||
|
@loops = reverse @loops
|
||||||
|
if $Slic3r::Config->external_perimeters_first
|
||||||
|
|| $self->layer->id == 0 && $Slic3r::Config->brim_width > 0;
|
||||||
|
push @{ $self->perimeters }, @loops;
|
||||||
|
|
||||||
|
# add thin walls as perimeters
|
||||||
|
push @{ $self->perimeters }, Slic3r::ExtrusionPath::Collection->new(paths => [
|
||||||
|
map {
|
||||||
|
Slic3r::ExtrusionPath->pack(
|
||||||
|
polyline => ($_->isa('Slic3r::Polygon') ? $_->split_at_first_point : $_),
|
||||||
|
role => EXTR_ROLE_EXTERNAL_PERIMETER,
|
||||||
|
flow_spacing => $self->perimeter_flow->spacing,
|
||||||
|
);
|
||||||
|
} @{ $self->thin_walls }
|
||||||
|
])->chained_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub prepare_fill_surfaces {
|
sub prepare_fill_surfaces {
|
||||||
|
Loading…
Reference in New Issue
Block a user