PrusaSlicer-NonPlainar/lib/Slic3r/ExPolygon.pm

67 lines
1.5 KiB
Perl
Raw Normal View History

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;