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;
|
my $start_at;
|
||||||
CYCLE: while (@{$self->paths}) {
|
CYCLE: while (@{$self->paths}) {
|
||||||
# find nearest point
|
# 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
|
# loop through paths to find the one that starts or ends at the point found
|
||||||
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
|
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
|
||||||
|
@ -17,6 +17,7 @@ our @EXPORT_OK = qw(
|
|||||||
clip_segment_complex_polygon longest_segment angle3points
|
clip_segment_complex_polygon longest_segment angle3points
|
||||||
polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
|
polyline_remove_parallel_continuous_edges polyline_remove_acute_vertices
|
||||||
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges
|
polygon_remove_acute_vertices polygon_remove_parallel_continuous_edges
|
||||||
|
shortest_path
|
||||||
);
|
);
|
||||||
|
|
||||||
use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
|
use Slic3r::Geometry::DouglasPeucker qw(Douglas_Peucker);
|
||||||
@ -611,4 +612,29 @@ sub polygon_remove_acute_vertices {
|
|||||||
return polyline_remove_acute_vertices($points, 1);
|
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;
|
1;
|
||||||
|
@ -3,6 +3,7 @@ use Moo;
|
|||||||
|
|
||||||
use Math::Clipper ':all';
|
use Math::Clipper ':all';
|
||||||
use Math::ConvexHull 1.0.4 qw(convex_hull);
|
use Math::ConvexHull 1.0.4 qw(convex_hull);
|
||||||
|
use Slic3r::Geometry qw(shortest_path);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
use constant X => 0;
|
use constant X => 0;
|
||||||
@ -31,6 +32,11 @@ sub make_perimeter {
|
|||||||
# )
|
# )
|
||||||
my @perimeters = (); # one item per depth; each item
|
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 }) {
|
foreach my $surface (@{ $layer->perimeter_surfaces }) {
|
||||||
# the outer loop must be offsetted by half extrusion width inwards
|
# the outer loop must be offsetted by half extrusion width inwards
|
||||||
my @last_offsets = ($surface->expolygon);
|
my @last_offsets = ($surface->expolygon);
|
||||||
|
Loading…
Reference in New Issue
Block a user