New option to only infill where strictly needed for supporting ceilings

This commit is contained in:
Alessandro Ranellucci 2013-02-09 23:36:32 +01:00
parent cf8cfc1380
commit cac79c0575
7 changed files with 77 additions and 8 deletions

View File

@ -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

View File

@ -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' => {

View File

@ -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)],
},
]);

View File

@ -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;

View File

@ -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");

View File

@ -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);
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

View File

@ -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