2011-09-26 08:52:58 +00:00
|
|
|
package Slic3r::ExtrusionPath::Collection;
|
|
|
|
use Moo;
|
|
|
|
|
|
|
|
use XXX;
|
|
|
|
|
|
|
|
has 'paths' => (
|
|
|
|
is => 'rw',
|
|
|
|
#isa => 'ArrayRef[Slic3r::ExtrusionPath]',
|
|
|
|
default => sub { [] },
|
|
|
|
);
|
|
|
|
|
|
|
|
sub add {
|
|
|
|
my $self = shift;
|
|
|
|
my ($path) = @_;
|
|
|
|
|
|
|
|
push @{$self->paths}, $path;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub endpoints {
|
|
|
|
my $self = shift;
|
|
|
|
my ($as_arrayref) = @_;
|
|
|
|
return map $_->endpoints($as_arrayref), @{$self->paths};
|
|
|
|
}
|
|
|
|
|
|
|
|
sub shortest_path {
|
|
|
|
my $self = shift;
|
|
|
|
my ($start_near) = @_;
|
|
|
|
|
|
|
|
# get point as arrayref
|
|
|
|
$start_near = $start_near->p if $start_near && ref $start_near ne 'ARRAY';
|
|
|
|
|
|
|
|
my @paths = ();
|
|
|
|
my $start_at;
|
|
|
|
CYCLE: while (@{$self->paths}) {
|
|
|
|
# find nearest point
|
|
|
|
$start_at = Slic3r::Point->cast(Slic3r::Geometry::nearest_point($start_near, [ $self->endpoints(1) ]));
|
|
|
|
|
|
|
|
# loop through paths to find the one that starts or ends at the point found
|
|
|
|
PATH: for (my $i = 0; $i <= $#{$self->paths}; $i++) {
|
|
|
|
if ($start_at->id eq $self->paths->[$i]->points->[0]->id) {
|
|
|
|
push @paths, splice @{$self->paths}, $i, 1;
|
|
|
|
} elsif ($start_at->id eq $self->paths->[$i]->points->[-1]->id) {
|
|
|
|
$self->paths->[$i]->reverse;
|
|
|
|
push @paths, splice @{$self->paths}, $i, 1;
|
|
|
|
} else {
|
|
|
|
next PATH;
|
|
|
|
}
|
|
|
|
$start_near = $paths[-1]->points->[-1]->p;
|
|
|
|
next CYCLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return @paths;
|
|
|
|
}
|
|
|
|
|
2011-10-01 12:26:54 +00:00
|
|
|
sub cleanup {
|
|
|
|
my $self = shift;
|
|
|
|
|
|
|
|
# split paths at angles that are too acute to be printed as they will cause blobs
|
|
|
|
@{$self->paths} = map $_->split_at_acute_angles, @{$self->paths};
|
|
|
|
}
|
|
|
|
|
2011-09-26 08:52:58 +00:00
|
|
|
1;
|