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
|
--solid-infill-below-area
|
||||||
Force solid infill when a region has a smaller area than this threshold
|
Force solid infill when a region has a smaller area than this threshold
|
||||||
(mm^2, default: 70)
|
(mm^2, default: 70)
|
||||||
|
--infill-only-where-needed
|
||||||
|
Only infill under ceilings (default: no)
|
||||||
|
|
||||||
Support material options:
|
Support material options:
|
||||||
--support-material Generate support material for overhangs
|
--support-material Generate support material for overhangs
|
||||||
|
@ -380,6 +380,13 @@ our $Options = {
|
|||||||
min => 0,
|
min => 0,
|
||||||
default => 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
|
# flow options
|
||||||
'extrusion_width' => {
|
'extrusion_width' => {
|
||||||
|
@ -417,7 +417,8 @@ sub build {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title => 'Advanced',
|
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 Moo;
|
||||||
|
|
||||||
use Slic3r::ExtrusionPath ':roles';
|
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::Geometry::Clipper qw(safety_offset union_ex diff_ex intersection_ex);
|
||||||
use Slic3r::Surface ':types';
|
use Slic3r::Surface ':types';
|
||||||
|
|
||||||
@ -16,6 +16,7 @@ has 'layer' => (
|
|||||||
has 'region' => (is => 'ro', required => 1);
|
has 'region' => (is => 'ro', required => 1);
|
||||||
has 'perimeter_flow' => (is => 'rw');
|
has 'perimeter_flow' => (is => 'rw');
|
||||||
has 'infill_flow' => (is => 'rw');
|
has 'infill_flow' => (is => 'rw');
|
||||||
|
has 'overhang_width' => (is => 'lazy');
|
||||||
|
|
||||||
# collection of spare segments generated by slicing the original geometry;
|
# collection of spare segments generated by slicing the original geometry;
|
||||||
# these need to be merged in continuos (closed) polylines
|
# these need to be merged in continuos (closed) polylines
|
||||||
@ -64,6 +65,12 @@ sub _update_flows {
|
|||||||
: $self->region->flows->{infill});
|
: $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
|
# build polylines from lines
|
||||||
sub make_surfaces {
|
sub make_surfaces {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
@ -367,6 +367,7 @@ sub export_gcode {
|
|||||||
# they will be split in internal and internal-solid surfaces
|
# they will be split in internal and internal-solid surfaces
|
||||||
$status_cb->(60, "Generating horizontal shells");
|
$status_cb->(60, "Generating horizontal shells");
|
||||||
$_->discover_horizontal_shells for @{$self->objects};
|
$_->discover_horizontal_shells for @{$self->objects};
|
||||||
|
$_->clip_fill_surfaces for @{$self->objects};
|
||||||
|
|
||||||
# combine fill surfaces to honor the "infill every N layers" option
|
# combine fill surfaces to honor the "infill every N layers" option
|
||||||
$status_cb->(70, "Combining infill");
|
$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 {
|
sub discover_horizontal_shells {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
|
||||||
@ -580,13 +627,15 @@ sub generate_support_material {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
return if $self->layer_count < 2;
|
return if $self->layer_count < 2;
|
||||||
|
|
||||||
my $threshold_rad = $Slic3r::Config->support_material_threshold
|
my $overhang_width;
|
||||||
? deg2rad($Slic3r::Config->support_material_threshold + 1) # +1 makes the threshold inclusive
|
if ($Slic3r::Config->support_material_threshold) {
|
||||||
: PI/2 - atan2($self->layers->[1]->regions->[0]->perimeter_flow->width/$Slic3r::Config->layer_height/2, 1);
|
my $threshold_rad = deg2rad($Slic3r::Config->support_material_threshold + 1); # +1 makes the threshold inclusive
|
||||||
Slic3r::debugf "Threshold angle = %d°\n", rad2deg($threshold_rad);
|
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 $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 $distance_from_object = 1.5 * $flow->scaled_width;
|
||||||
my $pattern_spacing = ($Slic3r::Config->support_material_spacing > $flow->spacing)
|
my $pattern_spacing = ($Slic3r::Config->support_material_spacing > $flow->spacing)
|
||||||
? $Slic3r::Config->support_material_spacing
|
? $Slic3r::Config->support_material_spacing
|
||||||
|
@ -245,6 +245,8 @@ $j
|
|||||||
--solid-infill-below-area
|
--solid-infill-below-area
|
||||||
Force solid infill when a region has a smaller area than this threshold
|
Force solid infill when a region has a smaller area than this threshold
|
||||||
(mm^2, default: $config->{solid_infill_below_area})
|
(mm^2, default: $config->{solid_infill_below_area})
|
||||||
|
--infill-only-where-needed
|
||||||
|
Only infill under ceilings (default: no)
|
||||||
|
|
||||||
Support material options:
|
Support material options:
|
||||||
--support-material Generate support material for overhangs
|
--support-material Generate support material for overhangs
|
||||||
|
Loading…
Reference in New Issue
Block a user