Bugfix: sparse and wrong infill was generated for objects with null fill density. Also fixed a division by zero.

This commit is contained in:
Alessandro Ranellucci 2011-11-27 10:12:44 +01:00
parent 22551b64de
commit 4cdd0f6fd0
4 changed files with 30 additions and 12 deletions

View File

@ -89,7 +89,7 @@ sub extrude {
my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::resolution; my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::resolution;
my $distance_threshold = $Slic3r::retract_before_travel; my $distance_threshold = $Slic3r::retract_before_travel;
$distance_threshold = 2 * $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2) $distance_threshold = 2 * $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2)
if $description =~ /fill/; if $Slic3r::fill_density > 0 && $description =~ /fill/;
if ($distance_from_last_pos >= $distance_threshold) { if ($distance_from_last_pos >= $distance_threshold) {
$gcode .= $self->retract(travel_to => $path->points->[0]); $gcode .= $self->retract(travel_to => $path->points->[0]);

View File

@ -311,17 +311,28 @@ sub remove_small_surfaces {
my $self = shift; my $self = shift;
my @good_surfaces = (); my @good_surfaces = ();
my $surface_count = scalar @{$self->surfaces}; my $distance = ($Slic3r::flow_width / 2 / $Slic3r::resolution);
foreach my $surface (@{$self->surfaces}) {
next if !$surface->contour->is_printable; my @surfaces = @{$self->surfaces};
@{$surface->holes} = grep $_->is_printable, @{$surface->holes}; @{$self->surfaces} = ();
push @good_surfaces, $surface; foreach my $surface (@surfaces) {
# offset inwards
my @offsets = $surface->expolygon->offset_ex(-$distance);
# offset the results outwards again and merge the results
@offsets = map $_->offset_ex($distance), @offsets;
@offsets = @{ union_ex([ map @$_, @offsets ]) };
# the difference between $surface->expolygon and @offsets
# is what we can't print since it's too small
push @{$self->surfaces}, map Slic3r::Surface->cast_from_expolygon($_,
surface_type => $surface->surface_type), @offsets;
} }
@{$self->surfaces} = @good_surfaces;
Slic3r::debugf "removed %d small surfaces at layer %d\n", Slic3r::debugf "removed %d small surfaces at layer %d\n",
($surface_count - @good_surfaces), $self->id (@surfaces - @{$self->surfaces}), $self->id
if @good_surfaces != $surface_count; if @{$self->surfaces} != @surfaces;
} }
sub remove_small_perimeters { sub remove_small_perimeters {

View File

@ -171,6 +171,13 @@ sub detect_surfaces_type {
Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n", Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n",
$layer->id, scalar(@bottom), scalar(@top), scalar(@internal); $layer->id, scalar(@bottom), scalar(@top), scalar(@internal);
} }
# remove internal surfaces if no infill is requested
if ($Slic3r::fill_density == 0) {
foreach my $layer (@{$self->layers}) {
@{$layer->surfaces} = grep $_->surface_type ne 'internal', @{$layer->surfaces};
}
}
} }
sub discover_horizontal_shells { sub discover_horizontal_shells {

View File

@ -35,9 +35,9 @@ sub go {
$perimeter_maker->make_perimeter($_) for @{$print->layers}; $perimeter_maker->make_perimeter($_) for @{$print->layers};
} }
# this will prepare surfaces for perimeters by merging all # this will clip $layer->surfaces to the infill boundaries
# surfaces in each layer; it will also clip $layer->surfaces # and split them in top/bottom/internal surfaces;
# to the infill boundaries and split them in top/bottom/internal surfaces # if fill density is null, it will delete all internal surfaces
$self->status_cb->(30, "Detecting solid surfaces..."); $self->status_cb->(30, "Detecting solid surfaces...");
$print->detect_surfaces_type; $print->detect_surfaces_type;