Organize perimeters with a nearest point search to avoid unnecessary travel moves. #21
This commit is contained in:
parent
e860254780
commit
279bfbb10d
@ -29,7 +29,9 @@ sub shortest_path {
|
||||
my $start_at;
|
||||
CYCLE: while (@{$self->paths}) {
|
||||
# find nearest point
|
||||
$start_at = Slic3r::Point->new(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints ]));
|
||||
$start_at = $start_near
|
||||
? Slic3r::Point->new(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints ]))
|
||||
: $self->endpoints->[0];
|
||||
|
||||
# loop through paths to find the one that starts or ends at the point found
|
||||
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
|
||||
|
@ -17,6 +17,7 @@ our @EXPORT_OK = qw(
|
||||
clip_segment_complex_polygon longest_segment angle3points
|
||||
polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
|
||||
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges
|
||||
shortest_path
|
||||
);
|
||||
|
||||
use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
|
||||
@ -611,4 +612,29 @@ sub polygon_remove_acute_vertices {
|
||||
return polyline_remove_acute_vertices($points, 1);
|
||||
}
|
||||
|
||||
# accepts an arrayref; each item should be an arrayref whose first
|
||||
# item is the point to be used for the shortest path, and the second
|
||||
# one is the value to be returned in output (if the second item
|
||||
# is not provided, the point will be returned)
|
||||
sub shortest_path {
|
||||
my ($items, $start_near) = @_;
|
||||
|
||||
my %values = map +($_->[0] => $_->[1] || $_->[0]), @$items;
|
||||
my @points = map $_->[0], @$items;
|
||||
|
||||
my $result = [];
|
||||
my $last_point;
|
||||
if (!$start_near) {
|
||||
$start_near = shift @points;
|
||||
push @$result, $values{$start_near} if $start_near;
|
||||
}
|
||||
while (@points) {
|
||||
$start_near = nearest_point($start_near, [@points]);
|
||||
@points = grep $_ ne $start_near, @points;
|
||||
push @$result, $values{$start_near};
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -3,6 +3,7 @@ use Moo;
|
||||
|
||||
use Math::Clipper ':all';
|
||||
use Math::ConvexHull 1.0.4 qw(convex_hull);
|
||||
use Slic3r::Geometry qw(shortest_path);
|
||||
use XXX;
|
||||
|
||||
use constant X => 0;
|
||||
@ -31,6 +32,11 @@ sub make_perimeter {
|
||||
# )
|
||||
my @perimeters = (); # one item per depth; each item
|
||||
|
||||
# organize $layer->perimeter_surfaces using a shortest path search
|
||||
@{ $layer->perimeter_surfaces } = @{shortest_path([
|
||||
map [ $_->contour->points->[0], $_ ], @{ $layer->perimeter_surfaces },
|
||||
])};
|
||||
|
||||
foreach my $surface (@{ $layer->perimeter_surfaces }) {
|
||||
# the outer loop must be offsetted by half extrusion width inwards
|
||||
my @last_offsets = ($surface->expolygon);
|
||||
|
Loading…
Reference in New Issue
Block a user