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 warnings;
|
||||
|
||||
use Slic3r::ExtrusionPath;
|
||||
use Slic3r::Layer;
|
||||
use Slic3r::Line;
|
||||
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;
|
||||
|
||||
# a sequential number of layer, starting at 0
|
||||
has 'id' => (
|
||||
is => 'ro',
|
||||
isa => 'Int',
|
||||
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' => (
|
||||
traits => ['Hash'],
|
||||
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' => (
|
||||
is => 'rw',
|
||||
isa => 'ArrayRef[Slic3r::Line]',
|
||||
default => sub { [] },
|
||||
);
|
||||
|
||||
# collection of surfaces generated by slicing the original geometry
|
||||
has 'surfaces' => (
|
||||
traits => ['Array'],
|
||||
is => 'rw',
|
||||
@ -32,9 +39,19 @@ has 'surfaces' => (
|
||||
default => sub { [] },
|
||||
);
|
||||
|
||||
# ordered collection of extrusion paths to build all perimeters
|
||||
has 'perimeters' => (
|
||||
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 { [] },
|
||||
);
|
||||
|
||||
|
@ -29,34 +29,22 @@ sub make_perimeter {
|
||||
|
||||
# create other offsets
|
||||
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
|
||||
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;
|
||||
# offsetting a polygon can result in one or many offset polygons
|
||||
my @offsets = $self->offset_polygon($perimeters[-1]);
|
||||
|
||||
# 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
|
||||
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);
|
||||
}
|
||||
foreach my $offset_polygon (@offsets) {
|
||||
my ($contour_p, @holes_p) = @{ $offset_polygon->polygons };
|
||||
|
||||
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 @{ $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
|
||||
@ -82,10 +70,42 @@ sub make_perimeter {
|
||||
# away from it to avoid the extruder to get two times there
|
||||
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 {
|
||||
my $self = shift;
|
||||
my ($points) = @_;
|
||||
|
@ -40,7 +40,7 @@ sub new_from_points {
|
||||
: $_
|
||||
} @points;
|
||||
|
||||
my $polyline = __PACKAGE__->new;
|
||||
my $polyline = $class->new;
|
||||
my $previous_point;
|
||||
$previous_point = $points[-1] if $class eq 'Slic3r::Polyline::Closed';
|
||||
foreach my $point (@points) {
|
||||
|
@ -42,6 +42,20 @@ sub BUILD {
|
||||
$_->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 {
|
||||
my $self = shift;
|
||||
return $self->contour->id;
|
||||
|
Loading…
Reference in New Issue
Block a user