Print solid infill without cutting an internal surface under small regions such as pillars. #39
This commit is contained in:
parent
47c0da8110
commit
8aca717209
4 changed files with 24 additions and 7 deletions
|
@ -51,9 +51,15 @@ sub offset {
|
||||||
$miterLimit ||= 2;
|
$miterLimit ||= 2;
|
||||||
|
|
||||||
my $offsets = Math::Clipper::offset($self, $distance, $scale, $joinType, $miterLimit);
|
my $offsets = Math::Clipper::offset($self, $distance, $scale, $joinType, $miterLimit);
|
||||||
|
return @$offsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub offset_ex {
|
||||||
|
my $self = shift;
|
||||||
|
my @offsets = $self->offset(@_);
|
||||||
|
|
||||||
# apply holes to the right contours
|
# apply holes to the right contours
|
||||||
return @{ union_ex($offsets) };
|
return @{ union_ex(\@offsets) };
|
||||||
}
|
}
|
||||||
|
|
||||||
sub encloses_point {
|
sub encloses_point {
|
||||||
|
|
|
@ -42,7 +42,7 @@ sub make_perimeter {
|
||||||
push @perimeters, [];
|
push @perimeters, [];
|
||||||
for (my $loop = 0; $loop < $Slic3r::perimeter_offsets; $loop++) {
|
for (my $loop = 0; $loop < $Slic3r::perimeter_offsets; $loop++) {
|
||||||
# offsetting a polygon can result in one or many offset polygons
|
# offsetting a polygon can result in one or many offset polygons
|
||||||
@last_offsets = map $_->offset(-$distance), @last_offsets;
|
@last_offsets = map $_->offset_ex(-$distance), @last_offsets;
|
||||||
push @{ $perimeters[-1] }, [@last_offsets];
|
push @{ $perimeters[-1] }, [@last_offsets];
|
||||||
|
|
||||||
# offset distance for inner loops
|
# offset distance for inner loops
|
||||||
|
@ -54,7 +54,7 @@ sub make_perimeter {
|
||||||
$distance -= $Slic3r::flow_width * $Slic3r::perimeter_infill_overlap_ratio / $Slic3r::resolution;
|
$distance -= $Slic3r::flow_width * $Slic3r::perimeter_infill_overlap_ratio / $Slic3r::resolution;
|
||||||
my @fill_surfaces = map Slic3r::Surface->cast_from_expolygon
|
my @fill_surfaces = map Slic3r::Surface->cast_from_expolygon
|
||||||
($_, surface_type => $surface->surface_type),
|
($_, surface_type => $surface->surface_type),
|
||||||
map $_->offset(-$distance), @last_offsets;
|
map $_->offset_ex(-$distance), @last_offsets;
|
||||||
|
|
||||||
push @{ $layer->fill_surfaces }, [@fill_surfaces] if @fill_surfaces;
|
push @{ $layer->fill_surfaces }, [@fill_surfaces] if @fill_surfaces;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,4 +65,9 @@ sub rotate {
|
||||||
@$self = rotate_points($angle, $center, @$self);
|
@$self = rotate_points($angle, $center, @$self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub area {
|
||||||
|
my $self = shift;
|
||||||
|
return Slic3r::Geometry::Clipper::area($self);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
|
@ -2,7 +2,7 @@ package Slic3r::Print;
|
||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use Math::ConvexHull 1.0.4 qw(convex_hull);
|
use Math::ConvexHull 1.0.4 qw(convex_hull);
|
||||||
use Slic3r::Geometry qw(X Y);
|
use Slic3r::Geometry qw(X Y PI);
|
||||||
use Slic3r::Geometry::Clipper qw(explode_expolygons safety_offset diff_ex intersection_ex
|
use Slic3r::Geometry::Clipper qw(explode_expolygons safety_offset diff_ex intersection_ex
|
||||||
offset JT_ROUND JT_MITER);
|
offset JT_ROUND JT_MITER);
|
||||||
use XXX;
|
use XXX;
|
||||||
|
@ -101,8 +101,14 @@ sub detect_surfaces_type {
|
||||||
# find top surfaces (difference between current surfaces
|
# find top surfaces (difference between current surfaces
|
||||||
# of current layer and upper one)
|
# of current layer and upper one)
|
||||||
if ($upper_layer) {
|
if ($upper_layer) {
|
||||||
# offset upper layer surfaces by extrusion_width * perimeters
|
# only consider those upper surfaces that are not small
|
||||||
@top = $surface_difference->($layer->surfaces, $upper_layer->surfaces, 'top');
|
# (if they're too small, the interface with them can be treated
|
||||||
|
# like a continuous solid surface instead of cutting a little
|
||||||
|
# internal surface in it)
|
||||||
|
my $min_area = ((7 * $Slic3r::flow_width / $Slic3r::resolution)**2) * PI;
|
||||||
|
my $upper_surfaces = [ grep { $_->expolygon->contour->area > $min_area } @{$upper_layer->surfaces} ];
|
||||||
|
|
||||||
|
@top = $surface_difference->($layer->surfaces, $upper_surfaces, 'top');
|
||||||
} else {
|
} else {
|
||||||
# if no upper layer, all surfaces of this one are solid
|
# if no upper layer, all surfaces of this one are solid
|
||||||
@top = @{$layer->surfaces};
|
@top = @{$layer->surfaces};
|
||||||
|
@ -195,7 +201,7 @@ sub discover_horizontal_shells {
|
||||||
Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
|
Slic3r::debugf " looking for neighbors on layer %d...\n", $n;
|
||||||
|
|
||||||
foreach my $surfaces (@{$self->layers->[$n]->fill_surfaces}) {
|
foreach my $surfaces (@{$self->layers->[$n]->fill_surfaces}) {
|
||||||
my $neighbor_polygons = [ map $_->p, grep $_->surface_type =~ /internal/, @$surfaces ];
|
my $neighbor_polygons = [ map $_->p, grep $_->surface_type eq 'internal', @$surfaces ];
|
||||||
|
|
||||||
# find intersection between @surfaces and current layer's surfaces
|
# find intersection between @surfaces and current layer's surfaces
|
||||||
# intersections have contours and holes
|
# intersections have contours and holes
|
||||||
|
|
Loading…
Reference in a new issue