New option to only infill where strictly needed for supporting ceilings
This commit is contained in:
parent
cf8cfc1380
commit
cac79c0575
@ -197,6 +197,8 @@ The author of the Silk icon set is Mark James.
|
||||
--solid-infill-below-area
|
||||
Force solid infill when a region has a smaller area than this threshold
|
||||
(mm^2, default: 70)
|
||||
--infill-only-where-needed
|
||||
Only infill under ceilings (default: no)
|
||||
|
||||
Support material options:
|
||||
--support-material Generate support material for overhangs
|
||||
|
@ -380,6 +380,13 @@ our $Options = {
|
||||
min => 0,
|
||||
default => 0,
|
||||
},
|
||||
'infill_only_where_needed' => {
|
||||
label => 'Only infill where needed',
|
||||
tooltip => 'This option will limit infill to the areas actually needed for supporting ceilings (it will act as internal support material).',
|
||||
cli => 'infill-only-where-needed!',
|
||||
type => 'bool',
|
||||
default => 0,
|
||||
},
|
||||
|
||||
# flow options
|
||||
'extrusion_width' => {
|
||||
|
@ -417,7 +417,8 @@ sub build {
|
||||
},
|
||||
{
|
||||
title => 'Advanced',
|
||||
options => [qw(infill_every_layers solid_infill_every_layers fill_angle solid_infill_below_area only_retract_when_crossing_perimeters)],
|
||||
options => [qw(infill_every_layers infill_only_where_needed solid_infill_every_layers fill_angle
|
||||
solid_infill_below_area only_retract_when_crossing_perimeters)],
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -2,7 +2,7 @@ package Slic3r::Layer::Region;
|
||||
use Moo;
|
||||
|
||||
use Slic3r::ExtrusionPath ':roles';
|
||||
use Slic3r::Geometry qw(scale chained_path_items);
|
||||
use Slic3r::Geometry qw(PI scale chained_path_items);
|
||||
use Slic3r::Geometry::Clipper qw(safety_offset union_ex diff_ex intersection_ex);
|
||||
use Slic3r::Surface ':types';
|
||||
|
||||
@ -16,6 +16,7 @@ has 'layer' => (
|
||||
has 'region' => (is => 'ro', required => 1);
|
||||
has 'perimeter_flow' => (is => 'rw');
|
||||
has 'infill_flow' => (is => 'rw');
|
||||
has 'overhang_width' => (is => 'lazy');
|
||||
|
||||
# collection of spare segments generated by slicing the original geometry;
|
||||
# these need to be merged in continuos (closed) polylines
|
||||
@ -64,6 +65,12 @@ sub _update_flows {
|
||||
: $self->region->flows->{infill});
|
||||
}
|
||||
|
||||
sub _build_overhang_width {
|
||||
my $self = shift;
|
||||
my $threshold_rad = PI/2 - atan2($self->perimeter_flow->width / $self->height / 2, 1);
|
||||
return scale($self->height * ((cos $threshold_rad) / (sin $threshold_rad)));
|
||||
}
|
||||
|
||||
# build polylines from lines
|
||||
sub make_surfaces {
|
||||
my $self = shift;
|
||||
|
@ -367,6 +367,7 @@ sub export_gcode {
|
||||
# they will be split in internal and internal-solid surfaces
|
||||
$status_cb->(60, "Generating horizontal shells");
|
||||
$_->discover_horizontal_shells for @{$self->objects};
|
||||
$_->clip_fill_surfaces for @{$self->objects};
|
||||
|
||||
# combine fill surfaces to honor the "infill every N layers" option
|
||||
$status_cb->(70, "Combining infill");
|
||||
|
@ -375,6 +375,53 @@ sub detect_surfaces_type {
|
||||
}
|
||||
}
|
||||
|
||||
sub clip_fill_surfaces {
|
||||
my $self = shift;
|
||||
return unless $Slic3r::Config->infill_only_where_needed;
|
||||
|
||||
# We only want infill under ceilings; this is almost like an
|
||||
# internal support material.
|
||||
|
||||
my $additional_margin = scale 3;
|
||||
|
||||
my @overhangs = ();
|
||||
for my $layer_id (reverse 0..$#{$self->layers}) {
|
||||
my $layer = $self->layers->[$layer_id];
|
||||
|
||||
# clip this layer's internal surfaces to @overhangs
|
||||
foreach my $layerm (@{$layer->regions}) {
|
||||
my @new_internal = map Slic3r::Surface->new(
|
||||
expolygon => $_,
|
||||
surface_type => S_TYPE_INTERNAL,
|
||||
),
|
||||
@{intersection_ex(
|
||||
[ map @$_, @overhangs ],
|
||||
[ map @{$_->expolygon}, grep $_->surface_type == S_TYPE_INTERNAL, @{$layerm->fill_surfaces} ],
|
||||
)};
|
||||
@{$layerm->fill_surfaces} = (
|
||||
@new_internal,
|
||||
(grep $_->surface_type != S_TYPE_INTERNAL, @{$layerm->fill_surfaces}),
|
||||
);
|
||||
}
|
||||
|
||||
# get this layer's overhangs
|
||||
if ($layer_id > 0) {
|
||||
my $lower_layer = $self->layers->[$layer_id-1];
|
||||
# loop through layer regions so that we can use each region's
|
||||
# specific overhang width
|
||||
foreach my $layerm (@{$layer->regions}) {
|
||||
my $overhang_width = $layerm->overhang_width;
|
||||
# we want to support any solid surface, not just tops
|
||||
# (internal solids might have been generated)
|
||||
push @overhangs, map $_->offset_ex($additional_margin), @{intersection_ex(
|
||||
[ map @{$_->expolygon}, grep $_->surface_type != S_TYPE_INTERNAL, @{$layerm->fill_surfaces} ],
|
||||
[ map @$_, map $_->offset_ex(-$overhang_width), @{$lower_layer->slices} ],
|
||||
)};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub discover_horizontal_shells {
|
||||
my $self = shift;
|
||||
|
||||
@ -580,13 +627,15 @@ sub generate_support_material {
|
||||
my $self = shift;
|
||||
return if $self->layer_count < 2;
|
||||
|
||||
my $threshold_rad = $Slic3r::Config->support_material_threshold
|
||||
? deg2rad($Slic3r::Config->support_material_threshold + 1) # +1 makes the threshold inclusive
|
||||
: PI/2 - atan2($self->layers->[1]->regions->[0]->perimeter_flow->width/$Slic3r::Config->layer_height/2, 1);
|
||||
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad);
|
||||
|
||||
my $overhang_width;
|
||||
if ($Slic3r::Config->support_material_threshold) {
|
||||
my $threshold_rad = deg2rad($Slic3r::Config->support_material_threshold + 1); # +1 makes the threshold inclusive
|
||||
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad);
|
||||
$overhang_width = scale $Slic3r::Config->layer_height * ((cos $threshold_rad) / (sin $threshold_rad));
|
||||
} else {
|
||||
$overhang_width = $self->layers->[1]->regions->[0]->overhang_width;
|
||||
}
|
||||
my $flow = $self->print->support_material_flow;
|
||||
my $overhang_width = $threshold_rad == 0 ? undef : scale $Slic3r::Config->layer_height * ((cos $threshold_rad) / (sin $threshold_rad));
|
||||
my $distance_from_object = 1.5 * $flow->scaled_width;
|
||||
my $pattern_spacing = ($Slic3r::Config->support_material_spacing > $flow->spacing)
|
||||
? $Slic3r::Config->support_material_spacing
|
||||
|
@ -245,6 +245,8 @@ $j
|
||||
--solid-infill-below-area
|
||||
Force solid infill when a region has a smaller area than this threshold
|
||||
(mm^2, default: $config->{solid_infill_below_area})
|
||||
--infill-only-where-needed
|
||||
Only infill under ceilings (default: no)
|
||||
|
||||
Support material options:
|
||||
--support-material Generate support material for overhangs
|
||||
|
Loading…
Reference in New Issue
Block a user