New --perimeters-extrusion-width and --infill-extrusion-width options. #302

This commit is contained in:
Alessandro Ranellucci 2012-06-06 18:05:03 +02:00
parent 8a031fe501
commit 82dd3c7a3e
17 changed files with 150 additions and 108 deletions

View file

@ -19,8 +19,9 @@ has 'slicing_errors' => (is => 'rw');
has 'slice_z' => (is => 'lazy');
has 'print_z' => (is => 'lazy');
has 'height' => (is => 'lazy');
has 'flow_spacing' => (is => 'lazy');
has 'flow_width' => (is => 'lazy');
has 'flow' => (is => 'lazy');
has 'perimeters_flow' => (is => 'lazy');
has 'infill_flow' => (is => 'lazy');
# collection of spare segments generated by slicing the original geometry;
# these need to be merged in continuos (closed) polylines
@ -101,14 +102,25 @@ sub _build_height {
return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height;
}
sub _build_flow_spacing {
sub _build_flow {
my $self = shift;
return $self->id == 0 ? $Slic3r::first_layer_flow_spacing : $Slic3r::flow_spacing;
return $self->id == 0 && $Slic3r::first_layer_flow
? $Slic3r::first_layer_flow
: $Slic3r::flow;
}
sub _build_flow_width {
sub _build_perimeters_flow {
my $self = shift;
return $self->id == 0 ? $Slic3r::first_layer_flow_width : $Slic3r::flow_width;
return $self->id == 0 && $Slic3r::first_layer_flow
? $Slic3r::first_layer_flow
: $Slic3r::perimeters_flow;
}
sub _build_infill_flow {
my $self = shift;
return $self->id == 0 && $Slic3r::first_layer_flow
? $Slic3r::first_layer_flow
: $Slic3r::infill_flow;
}
sub add_line {
@ -139,7 +151,7 @@ sub make_surfaces {
# the contours must be offsetted by half extrusion width inwards
{
my $distance = scale $self->flow_width / 2;
my $distance = scale $self->perimeters_flow->width / 2;
my @surfaces = @{$self->slices};
@{$self->slices} = ();
foreach my $surface (@surfaces) {
@ -158,12 +170,12 @@ sub make_surfaces {
);
if (@$diff) {
my $area_threshold = scale($self->flow_spacing) ** 2;
my $area_threshold = scale($self->perimeters_flow->spacing) ** 2;
@$diff = grep $_->area > ($area_threshold), @$diff;
push @{$self->thin_walls},
grep $_,
map $_->medial_axis(scale $self->flow_width),
map $_->medial_axis(scale $self->perimeters_flow->width),
@$diff;
Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls};
@ -213,8 +225,8 @@ sub make_perimeters {
next unless $circumference <= $Slic3r::small_perimeter_length;
# revert the compensation done in make_surfaces() and get the actual radius
# of the hole
my $radius = ($circumference / PI / 2) - scale $self->flow_spacing/2;
my $new_radius = (scale($self->flow_width) + sqrt((scale($self->flow_width)**2) + (4*($radius**2)))) / 2;
my $radius = ($circumference / PI / 2) - scale $self->perimeters_flow->spacing/2;
my $new_radius = (scale($self->perimeters_flow->width) + sqrt((scale($self->perimeters_flow->width)**2) + (4*($radius**2)))) / 2;
# holes are always turned to contours, so reverse point order before and after
$hole->reverse;
my @offsetted = $hole->offset(+ ($new_radius - $radius));
@ -233,7 +245,7 @@ sub make_perimeters {
push @{ $perimeters[-1] }, [@last_offsets];
# offset distance for inner loops
$distance = scale $self->flow_spacing;
$distance = scale $self->perimeters_flow->spacing;
}
# create one more offset to be used as boundary for fill
@ -249,7 +261,7 @@ sub make_perimeters {
);
push @{ $self->thin_fills },
grep $_,
map $_->medial_axis(scale $self->flow_width),
map $_->medial_axis(scale $self->perimeters_flow->width),
@$small_gaps if 0;
}
}
@ -321,7 +333,7 @@ sub add_perimeter {
my $self = shift;
my ($polygon, $role) = @_;
return unless $polygon->is_printable($self->flow_width);
return unless $polygon->is_printable($self->perimeters_flow->width);
push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(
polygon => $polygon,
role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/
@ -336,7 +348,7 @@ sub prepare_fill_surfaces {
# merge too small internal surfaces with their surrounding tops
# (if they're too small, they can be treated as solid)
{
my $min_area = ((7 * $self->flow_spacing / $Slic3r::scaling_factor)**2) * PI;
my $min_area = ((7 * $self->infill_flow->spacing / $Slic3r::scaling_factor)**2) * PI;
my $small_internal = [
grep { $_->expolygon->contour->area <= $min_area }
grep { $_->surface_type == S_TYPE_INTERNAL }
@ -369,7 +381,7 @@ sub prepare_fill_surfaces {
sub remove_small_surfaces {
my $self = shift;
my $distance = scale $self->flow_spacing / 2;
my $distance = scale $self->infill_flow->spacing / 2;
my @surfaces = @{$self->fill_surfaces};
@{$self->fill_surfaces} = ();
@ -429,7 +441,7 @@ sub process_bridges {
# offset the contour and intersect it with the internal surfaces to discover
# which of them has contact with our bridge
my @supporting_surfaces = ();
my ($contour_offset) = $expolygon->contour->offset(scale $self->flow_spacing * sqrt(2));
my ($contour_offset) = $expolygon->contour->offset(scale $self->flow->spacing * sqrt(2));
foreach my $internal_surface (@internal_surfaces) {
my $intersection = intersection_ex([$contour_offset], [$internal_surface->p]);
if (@$intersection) {