67 lines
1.5 KiB
Perl
67 lines
1.5 KiB
Perl
|
package Slic3r::ExPolygon;
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
|
||
|
# an ExPolygon is a polygon with holes
|
||
|
|
||
|
use Math::Clipper qw(CT_UNION PFT_NONZERO JT_MITER);
|
||
|
use Slic3r::Geometry::Clipper qw(union_ex);
|
||
|
|
||
|
# the constructor accepts an array of polygons
|
||
|
# or a Math::Clipper ExPolygon (hashref)
|
||
|
sub new {
|
||
|
my $class = shift;
|
||
|
my $self;
|
||
|
if (@_ == 1 && ref $_[0] eq 'HASH') {
|
||
|
$self = [
|
||
|
Slic3r::Polygon->new($_[0]{outer}),
|
||
|
map Slic3r::Polygon->new($_), @{$_[0]{holes}},
|
||
|
];
|
||
|
} else {
|
||
|
$self = [@_];
|
||
|
}
|
||
|
bless $self, $class;
|
||
|
$self;
|
||
|
}
|
||
|
|
||
|
# this class method accepts an array of polygons and returns
|
||
|
# an array of expolygons with the right holes applied to the
|
||
|
# right contours
|
||
|
sub make {
|
||
|
my $class = shift;
|
||
|
return map $class->new($_), @{ union_ex(\@_) };
|
||
|
}
|
||
|
|
||
|
sub contour {
|
||
|
my $self = shift;
|
||
|
return $self->[0];
|
||
|
}
|
||
|
|
||
|
sub holes {
|
||
|
my $self = shift;
|
||
|
return @$self[1..$#$self];
|
||
|
}
|
||
|
|
||
|
sub clipper_expolygon {
|
||
|
my $self = shift;
|
||
|
return {
|
||
|
outer => $self->contour,
|
||
|
holes => [ $self->holes ],
|
||
|
};
|
||
|
}
|
||
|
|
||
|
sub offset {
|
||
|
my $self = shift;
|
||
|
my ($distance, $scale, $joinType, $miterLimit) = @_;
|
||
|
$scale ||= $Slic3r::resolution * 1000000;
|
||
|
$joinType = JT_MITER if !defined $joinType;
|
||
|
$miterLimit ||= 2;
|
||
|
|
||
|
my $offsets = Math::Clipper::offset($self, $distance, $scale, $joinType, $miterLimit);
|
||
|
|
||
|
# apply holes to the right contours
|
||
|
return (ref $self)->make(@$offsets);
|
||
|
}
|
||
|
|
||
|
1;
|