Generate boundaries of areas to fill (includes some refactoring)
This commit is contained in:
parent
416ad241ea
commit
428006264d
@ -3,6 +3,7 @@ package Slic3r;
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
|
use Slic3r::ExtrusionPath;
|
||||||
use Slic3r::Layer;
|
use Slic3r::Layer;
|
||||||
use Slic3r::Line;
|
use Slic3r::Line;
|
||||||
use Slic3r::Perimeter;
|
use Slic3r::Perimeter;
|
||||||
|
6
lib/Slic3r/ExtrusionPath.pm
Normal file
6
lib/Slic3r/ExtrusionPath.pm
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package Slic3r::ExtrusionPath;
|
||||||
|
use Moose;
|
||||||
|
|
||||||
|
extends 'Slic3r::Polyline';
|
||||||
|
|
||||||
|
1;
|
@ -3,12 +3,16 @@ use Moose;
|
|||||||
|
|
||||||
use XXX;
|
use XXX;
|
||||||
|
|
||||||
|
# a sequential number of layer, starting at 0
|
||||||
has 'id' => (
|
has 'id' => (
|
||||||
is => 'ro',
|
is => 'ro',
|
||||||
isa => 'Int',
|
isa => 'Int',
|
||||||
required => 1,
|
required => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# index of points generated by slicing the original geometry
|
||||||
|
# keys are stringified coordinates (example: "0,0")
|
||||||
|
# each points connects exactly two segments
|
||||||
has 'pointmap' => (
|
has 'pointmap' => (
|
||||||
traits => ['Hash'],
|
traits => ['Hash'],
|
||||||
is => 'rw',
|
is => 'rw',
|
||||||
@ -19,12 +23,15 @@ has 'pointmap' => (
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# collection of segments generated by slicing the original geometry
|
||||||
|
# each segment is part of a closed polyline
|
||||||
has 'lines' => (
|
has 'lines' => (
|
||||||
is => 'rw',
|
is => 'rw',
|
||||||
isa => 'ArrayRef[Slic3r::Line]',
|
isa => 'ArrayRef[Slic3r::Line]',
|
||||||
default => sub { [] },
|
default => sub { [] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# collection of surfaces generated by slicing the original geometry
|
||||||
has 'surfaces' => (
|
has 'surfaces' => (
|
||||||
traits => ['Array'],
|
traits => ['Array'],
|
||||||
is => 'rw',
|
is => 'rw',
|
||||||
@ -32,9 +39,19 @@ has 'surfaces' => (
|
|||||||
default => sub { [] },
|
default => sub { [] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
# ordered collection of extrusion paths to build all perimeters
|
||||||
has 'perimeters' => (
|
has 'perimeters' => (
|
||||||
is => 'rw',
|
is => 'rw',
|
||||||
isa => 'ArrayRef[Slic3r::Polyline]',
|
isa => 'ArrayRef[Slic3r::ExtrusionPath]',
|
||||||
|
default => sub { [] },
|
||||||
|
);
|
||||||
|
|
||||||
|
# collection of surfaces generated by offsetting the innermost perimeter(s)
|
||||||
|
# they represent boundaries of areas to fill
|
||||||
|
has 'fill_surfaces' => (
|
||||||
|
traits => ['Array'],
|
||||||
|
is => 'rw',
|
||||||
|
isa => 'ArrayRef[Slic3r::Surface]',
|
||||||
default => sub { [] },
|
default => sub { [] },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -29,34 +29,22 @@ sub make_perimeter {
|
|||||||
|
|
||||||
# create other offsets
|
# create other offsets
|
||||||
for (my $loop = 1; $loop < $Slic3r::perimeter_offsets; $loop++) {
|
for (my $loop = 1; $loop < $Slic3r::perimeter_offsets; $loop++) {
|
||||||
my ($contour_p, @holes_p) = map $self->_mgp_from_points_ref($_), @{ $perimeters[-1]->polygons };
|
|
||||||
|
|
||||||
# generate offsets
|
# offsetting a polygon can result in one or many offset polygons
|
||||||
my $contour_offsets = $contour_p->offset_polygon($Slic3r::flow_width / $Slic3r::resolution);
|
my @offsets = $self->offset_polygon($perimeters[-1]);
|
||||||
my @hole_offsets = map @$_, map $_->offset_polygon(- $Slic3r::flow_width / $Slic3r::resolution), @holes_p;
|
|
||||||
|
|
||||||
# now we subtract perimeter offsets from the contour offset polygon
|
foreach my $offset_polygon (@offsets) {
|
||||||
# this will generate a single polygon with correct holes and also
|
my ($contour_p, @holes_p) = @{ $offset_polygon->polygons };
|
||||||
# will take care of collisions between contour offset and holes
|
|
||||||
foreach my $contour_points (@$contour_offsets) {
|
|
||||||
my $tmp = $self->_mgp_from_points_ref($contour_points)->convert2gpc;
|
|
||||||
foreach my $hole_points (@hole_offsets) {
|
|
||||||
$hole_points = $self->_mgp_from_points_ref($hole_points)->convert2gpc;
|
|
||||||
$tmp = GpcClip('DIFFERENCE', $tmp, $hole_points);
|
|
||||||
}
|
|
||||||
|
|
||||||
my ($result) = Gpc2Polygons($tmp);
|
|
||||||
# now we've got $result, which is a Math::Geometry::Planar
|
|
||||||
# representing the inner surface including hole perimeters
|
|
||||||
|
|
||||||
my $result_polylines = $result->polygons;
|
|
||||||
|
|
||||||
($contour_p, @holes_p) = @$result_polylines;
|
|
||||||
push @{ $contours{$surface} }, $contour_p;
|
push @{ $contours{$surface} }, $contour_p;
|
||||||
push @{ $holes{$surface} }, @holes_p;
|
push @{ $holes{$surface} }, @holes_p;
|
||||||
push @perimeters, $result;
|
push @perimeters, $offset_polygon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# create one more offset to be used as boundary for fill
|
||||||
|
push @{ $layer->fill_surfaces },
|
||||||
|
map Slic3r::Surface->new_from_mgp($_), $self->offset_polygon($perimeters[-1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
# generate paths for holes
|
# generate paths for holes
|
||||||
@ -82,10 +70,42 @@ sub make_perimeter {
|
|||||||
# away from it to avoid the extruder to get two times there
|
# away from it to avoid the extruder to get two times there
|
||||||
push @path_points, @$points, $points->[0];
|
push @path_points, @$points, $points->[0];
|
||||||
}
|
}
|
||||||
push @{ $layer->perimeters }, Slic3r::Polyline->new_from_points(reverse @path_points);
|
push @{ $layer->perimeters }, Slic3r::ExtrusionPath->new_from_points(reverse @path_points);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub offset_polygon {
|
||||||
|
my $self = shift;
|
||||||
|
my ($polygon) = @_;
|
||||||
|
|
||||||
|
# $polygon holds a Math::Geometry::Planar object representing
|
||||||
|
# a polygon and its holes
|
||||||
|
my ($contour_p, @holes_p) = map $self->_mgp_from_points_ref($_), @{ $polygon->polygons };
|
||||||
|
|
||||||
|
# generate offsets
|
||||||
|
my $contour_offsets = $contour_p->offset_polygon($Slic3r::flow_width / $Slic3r::resolution);
|
||||||
|
my @hole_offsets = map @$_, map $_->offset_polygon(- $Slic3r::flow_width / $Slic3r::resolution), @holes_p;
|
||||||
|
|
||||||
|
# now we subtract perimeter offsets from the contour offset polygon
|
||||||
|
# this will generate a single polygon with correct holes and also
|
||||||
|
# will take care of collisions between contour offset and holes
|
||||||
|
my @resulting_offsets = ();
|
||||||
|
foreach my $contour_points (@$contour_offsets) {
|
||||||
|
my $tmp = $self->_mgp_from_points_ref($contour_points)->convert2gpc;
|
||||||
|
foreach my $hole_points (@hole_offsets) {
|
||||||
|
$hole_points = $self->_mgp_from_points_ref($hole_points)->convert2gpc;
|
||||||
|
$tmp = GpcClip('DIFFERENCE', $tmp, $hole_points);
|
||||||
|
}
|
||||||
|
|
||||||
|
my ($result) = Gpc2Polygons($tmp);
|
||||||
|
# now we've got $result, which is a Math::Geometry::Planar
|
||||||
|
# representing the inner surface including hole perimeters
|
||||||
|
push @resulting_offsets, $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return @resulting_offsets;
|
||||||
|
}
|
||||||
|
|
||||||
sub _mgp_from_points_ref {
|
sub _mgp_from_points_ref {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($points) = @_;
|
my ($points) = @_;
|
||||||
|
@ -40,7 +40,7 @@ sub new_from_points {
|
|||||||
: $_
|
: $_
|
||||||
} @points;
|
} @points;
|
||||||
|
|
||||||
my $polyline = __PACKAGE__->new;
|
my $polyline = $class->new;
|
||||||
my $previous_point;
|
my $previous_point;
|
||||||
$previous_point = $points[-1] if $class eq 'Slic3r::Polyline::Closed';
|
$previous_point = $points[-1] if $class eq 'Slic3r::Polyline::Closed';
|
||||||
foreach my $point (@points) {
|
foreach my $point (@points) {
|
||||||
|
@ -42,6 +42,20 @@ sub BUILD {
|
|||||||
$_->hole_of($self) for @{ $self->holes };
|
$_->hole_of($self) for @{ $self->holes };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub new_from_mgp {
|
||||||
|
my $self = shift;
|
||||||
|
my ($polygon) = @_;
|
||||||
|
|
||||||
|
my ($contour_p, @holes_p) = @{ $polygon->polygons };
|
||||||
|
|
||||||
|
return __PACKAGE__->new(
|
||||||
|
contour => Slic3r::Polyline::Closed->new_from_points(@$contour_p),
|
||||||
|
holes => [
|
||||||
|
map Slic3r::Polyline::Closed->new_from_points(@$_), @holes_p
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
sub id {
|
sub id {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->contour->id;
|
return $self->contour->id;
|
||||||
|
Loading…
Reference in New Issue
Block a user