From 4cdd0f6fd0452173fac55895c8f01ec3896cf97b Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sun, 27 Nov 2011 10:12:44 +0100 Subject: [PATCH] Bugfix: sparse and wrong infill was generated for objects with null fill density. Also fixed a division by zero. --- lib/Slic3r/Extruder.pm | 2 +- lib/Slic3r/Layer.pm | 27 +++++++++++++++++++-------- lib/Slic3r/Print.pm | 7 +++++++ lib/Slic3r/Skein.pm | 6 +++--- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index cb24fe973..f873ad4e3 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -89,7 +89,7 @@ sub extrude { my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::resolution; my $distance_threshold = $Slic3r::retract_before_travel; $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) { $gcode .= $self->retract(travel_to => $path->points->[0]); diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index a4ad47382..187e6ffbe 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -311,17 +311,28 @@ sub remove_small_surfaces { my $self = shift; my @good_surfaces = (); - my $surface_count = scalar @{$self->surfaces}; - foreach my $surface (@{$self->surfaces}) { - next if !$surface->contour->is_printable; - @{$surface->holes} = grep $_->is_printable, @{$surface->holes}; - push @good_surfaces, $surface; + my $distance = ($Slic3r::flow_width / 2 / $Slic3r::resolution); + + my @surfaces = @{$self->surfaces}; + @{$self->surfaces} = (); + 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", - ($surface_count - @good_surfaces), $self->id - if @good_surfaces != $surface_count; + (@surfaces - @{$self->surfaces}), $self->id + if @{$self->surfaces} != @surfaces; } sub remove_small_perimeters { diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 1a13c4ea6..7835d746c 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -171,6 +171,13 @@ sub detect_surfaces_type { Slic3r::debugf " layer %d has %d bottom, %d top and %d internal surfaces\n", $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 { diff --git a/lib/Slic3r/Skein.pm b/lib/Slic3r/Skein.pm index 2a93d559c..100dac930 100644 --- a/lib/Slic3r/Skein.pm +++ b/lib/Slic3r/Skein.pm @@ -35,9 +35,9 @@ sub go { $perimeter_maker->make_perimeter($_) for @{$print->layers}; } - # this will prepare surfaces for perimeters by merging all - # surfaces in each layer; it will also clip $layer->surfaces - # to the infill boundaries and split them in top/bottom/internal surfaces + # this will clip $layer->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..."); $print->detect_surfaces_type;