Refactored Perimeter code with new Slic3r::Polygon and Slic3r::ExPolygon objects

Large refactoring. Speed gains. Removed convex hull for bridges.
This commit is contained in:
Alessandro Ranellucci 2011-10-15 11:36:05 +02:00
parent 2d784fac9b
commit 5090ae561c
11 changed files with 174 additions and 100 deletions

View file

@ -2,7 +2,6 @@ package Slic3r::Layer;
use Moo;
use Math::Clipper ':all';
use Math::ConvexHull qw(convex_hull);
use Slic3r::Geometry qw(polygon_lines points_coincide angle3points polyline_lines nearest_point
line_length);
use Slic3r::Geometry::Clipper qw(union_ex);
@ -63,10 +62,10 @@ has 'skirts' => (
);
# collection of surfaces generated by offsetting the innermost perimeter(s)
# they represent boundaries of areas to fill
# they represent boundaries of areas to fill (grouped by original objects)
has 'fill_surfaces' => (
is => 'rw',
#isa => 'ArrayRef[Slic3r::Surface::Collection]',
#isa => 'ArrayRef[ArrayRef[Slic3r::Surface]]',
default => sub { [] },
);
@ -156,7 +155,7 @@ sub make_surfaces {
}
my $n = 0;
my @polylines = ();
my @polygons = ();
while (my $first_line = shift @lines) {
my @points = @$first_line;
my %seen_points = map { $get_point_id->($points[$_]) => $_ } 0..1;
@ -219,14 +218,15 @@ sub make_surfaces {
}
pop @points;
Slic3r::debugf "Discovered polyline of %d points\n", scalar(@points);
push @polylines, [@points];
Slic3r::debugf "Discovered polygon of %d points\n", scalar(@points);
push @polygons, Slic3r::Polygon->new(@points);
$polygons[-1]->cleanup;
}
{
my $expolygons = union_ex([ @polylines ]);
my $expolygons = union_ex([ @polygons ]);
Slic3r::debugf " %d surface(s) detected from %d polylines\n",
scalar(@$expolygons), scalar(@polylines);
scalar(@$expolygons), scalar(@polygons);
push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_, surface_type => 'internal'), @$expolygons;
}
@ -279,7 +279,7 @@ sub process_bridges {
SURFACE: foreach my $surface (@bottom_surfaces) {
# since we can't print concave bridges, we transform the surface
# in a convex polygon; this will print thin membranes eventually
my $surface_p = convex_hull($surface->contour->p);
my $surface_p = $surface->contour->p;
# offset the surface a bit to avoid approximation issues when doing the
# intersection below (this is to make sure we overlap with supporting
@ -407,9 +407,9 @@ sub split_bridges_fills {
my $self = shift;
my $clipper = Math::Clipper->new;
foreach my $surf_coll (@{$self->fill_surfaces}) {
my @surfaces = @{$surf_coll->surfaces};
@{$surf_coll->surfaces} = ();
foreach my $surfaces (@{$self->fill_surfaces}) {
my @surfaces = @$surfaces;
@$surfaces = ();
# intersect fill_surfaces with bridges to get actual bridges
foreach my $bridge (@{$self->bridges}) {
@ -417,7 +417,7 @@ sub split_bridges_fills {
$clipper->add_subject_polygons([ map $_->p, @surfaces ]);
$clipper->add_clip_polygon($bridge->contour->p);
my $intersection = $clipper->ex_execute(CT_INTERSECTION, PFT_NONZERO, PFT_NONZERO);
push @{$surf_coll->surfaces}, map Slic3r::Surface::Bridge->cast_from_expolygon($_,
push @$surfaces, map Slic3r::Surface::Bridge->cast_from_expolygon($_,
surface_type => 'bottom',
bridge_angle => $bridge->bridge_angle,
), @$intersection;
@ -429,7 +429,7 @@ sub split_bridges_fills {
$clipper->add_subject_polygons([ $surface->p ]);
$clipper->add_clip_polygons([ map $_->contour->p, @{$self->bridges} ]);
my $difference = $clipper->ex_execute(CT_DIFFERENCE, PFT_NONZERO, PFT_NONZERO);
push @{$surf_coll->surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
push @$surfaces, map Slic3r::Surface->cast_from_expolygon($_,
surface_type => $surface->surface_type), @$difference;
}
}