From d6d6a51e0df96524daacc744e0472e7016a892f3 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Sat, 5 Apr 2014 10:54:24 +0200 Subject: [PATCH] Fix for incomplete extrusion on solid surfaces --- lib/Slic3r/Fill.pm | 26 +++++++++++++++----------- lib/Slic3r/Fill/Rectilinear.pm | 2 +- lib/Slic3r/Print/SupportMaterial.pm | 2 ++ t/fill.t | 3 ++- xs/src/Flow.cpp | 6 ++++++ 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 968b27f6..c22b9186 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -182,11 +182,9 @@ sub make_fill { next if $surface->surface_type == S_TYPE_INTERNALVOID; my $filler = $layerm->config->fill_pattern; my $density = $fill_density; - my $flow = ($surface->surface_type == S_TYPE_TOP) - ? $layerm->flow(FLOW_ROLE_TOP_SOLID_INFILL) - : $surface->is_solid - ? $solid_infill_flow - : $infill_flow; + my $role = ($surface->surface_type == S_TYPE_TOP) ? FLOW_ROLE_TOP_SOLID_INFILL + : $surface->is_solid ? FLOW_ROLE_SOLID_INFILL + : FLOW_ROLE_INFILL; my $is_bridge = $layerm->id > 0 && $surface->is_bridge; my $is_solid = $surface->is_solid; @@ -196,7 +194,6 @@ sub make_fill { $filler = $layerm->config->solid_fill_pattern; if ($is_bridge) { $filler = 'rectilinear'; - $flow = $layerm->flow(FLOW_ROLE_SOLID_INFILL, 1); } elsif ($surface->surface_type == S_TYPE_INTERNALSOLID) { $filler = 'rectilinear'; } @@ -204,19 +201,26 @@ sub make_fill { next SURFACE unless $density > 0; } + my $h = $surface->thickness == -1 ? $layerm->height : $surface->thickness; + my $flow = $layerm->region->flow( + $role, + $h, + $is_bridge, + $layerm->id == 0, + ); + my $f = $self->filler($filler); $f->layer_id($layerm->id); $f->angle($layerm->config->fill_angle); my ($params, @polylines) = $f->fill_surface( $surface, - density => $density/100, - flow => $flow, + density => $density/100, + flow => $flow, + layer_height => $h, ); next unless @polylines; - my $h = $surface->thickness; - $h = $layerm->height if $h == -1; - my $mm3_per_mm = $params->{flow}->mm3_per_mm($h); + my $mm3_per_mm = $flow->mm3_per_mm($h); # save into layer push @fills, my $collection = Slic3r::ExtrusionPath::Collection->new; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index d8ba2870..15b93613 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -33,7 +33,7 @@ sub fill_surface { $flow = Slic3r::Flow->new_from_spacing( spacing => unscale($line_spacing), nozzle_diameter => $flow->nozzle_diameter, - layer_height => $surface->thickness, + layer_height => ($params{layer_height} or die "No layer_height supplied to fill_surface()"), bridge => $flow->bridge, ); } else { diff --git a/lib/Slic3r/Print/SupportMaterial.pm b/lib/Slic3r/Print/SupportMaterial.pm index 712d09ab..864d2682 100644 --- a/lib/Slic3r/Print/SupportMaterial.pm +++ b/lib/Slic3r/Print/SupportMaterial.pm @@ -552,6 +552,7 @@ sub generate_toolpaths { Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL), density => $interface_density, flow => $interface_flow, + layer_height => $layer->height, complete => 1, ); my $mm3_per_mm = $params->{flow}->mm3_per_mm($layer->height); @@ -602,6 +603,7 @@ sub generate_toolpaths { Slic3r::Surface->new(expolygon => $expolygon, surface_type => S_TYPE_INTERNAL), density => $density, flow => $base_flow, + layer_height => $layer->height, complete => 1, ); my $mm3_per_mm = $params->{flow}->mm3_per_mm($layer->height); diff --git a/t/fill.t b/t/fill.t index 365d8e06..1192f81e 100644 --- a/t/fill.t +++ b/t/fill.t @@ -51,7 +51,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } ); foreach my $angle (0, 45) { $surface->expolygon->rotate(Slic3r::Geometry::deg2rad($angle), [0,0]); - my ($params, @paths) = $filler->fill_surface($surface, flow => $flow, density => 0.4); + my ($params, @paths) = $filler->fill_surface($surface, flow => $flow, layer_height => 0.4, density => 0.4); is scalar @paths, 1, 'one continuous path'; } } @@ -76,6 +76,7 @@ sub scale_points (@) { map [scale $_->[X], scale $_->[Y]], @_ } my ($params, @paths) = $filler->fill_surface( $surface, flow => $flow, + layer_height => 0.4, density => $density // 1, ); diff --git a/xs/src/Flow.cpp b/xs/src/Flow.cpp index e5e7dc2b..13c12bef 100644 --- a/xs/src/Flow.cpp +++ b/xs/src/Flow.cpp @@ -5,6 +5,9 @@ namespace Slic3r { Flow Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &width, float nozzle_diameter, float height, float bridge_flow_ratio) { + // we need layer height unless it's a bridge + if (height <= 0 && bridge_flow_ratio == 0) CONFESS("Invalid flow height supplied to new_from_config_width()"); + float w; if (!width.percent && width.value == 0) { w = Flow::_width(role, nozzle_diameter, height, bridge_flow_ratio); @@ -19,6 +22,9 @@ Flow::new_from_config_width(FlowRole role, const ConfigOptionFloatOrPercent &wid Flow Flow::new_from_spacing(float spacing, float nozzle_diameter, float height, bool bridge) { + // we need layer height unless it's a bridge + if (height <= 0 && !bridge) CONFESS("Invalid flow height supplied to new_from_spacing()"); + float w = Flow::_width_from_spacing(spacing, nozzle_diameter, height, bridge); Flow flow(w, spacing, nozzle_diameter); flow.bridge = bridge;