From 8a031fe501a7025c4acab8544af8eb1e769a2bef Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Wed, 6 Jun 2012 17:29:12 +0200 Subject: [PATCH] New --first-layer-extrusion-width option. #385 --- lib/Slic3r.pm | 4 ++ lib/Slic3r/Config.pm | 94 +++++++++++++++++++++------------- lib/Slic3r/Extruder.pm | 6 +-- lib/Slic3r/Fill.pm | 4 +- lib/Slic3r/Fill/Concentric.pm | 2 +- lib/Slic3r/Fill/Honeycomb.pm | 2 +- lib/Slic3r/Fill/Rectilinear.pm | 2 +- lib/Slic3r/GUI/SkeinPanel.pm | 2 +- lib/Slic3r/Layer.pm | 34 ++++++++---- lib/Slic3r/Polygon.pm | 3 +- lib/Slic3r/Print.pm | 2 + lib/Slic3r/Print/Object.pm | 36 ++++++------- slic3r.pl | 2 + 13 files changed, 117 insertions(+), 76 deletions(-) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index efe5fd3ae..bd7eedde6 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -101,11 +101,15 @@ our $infill_every_layers = 1; # flow options our $extrusion_width = 0; +our $first_layer_extrusion_width = 0; our $bridge_flow_ratio = 1; our $overlap_factor = 0.5; our $flow_width; our $min_flow_spacing; our $flow_spacing; +our $first_layer_flow_width; +our $first_layer_min_flow_spacing; +our $first_layer_flow_spacing; # print options our $perimeters = 3; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index de3f9fce6..495fbf9d4 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -159,7 +159,7 @@ our $Options = { }, 'first_layer_speed' => { label => 'First layer speed (mm/s or %)', - cli => 'first-layer-speed=f', + cli => 'first-layer-speed=s', type => 'f', }, @@ -188,7 +188,7 @@ our $Options = { }, 'first_layer_height' => { label => 'First layer height (mm or %)', - cli => 'first-layer-height=f', + cli => 'first-layer-height=s', type => 'f', }, 'infill_every_layers' => { @@ -200,7 +200,12 @@ our $Options = { # flow options 'extrusion_width' => { label => 'Extrusion width (mm or %; leave zero to calculate automatically)', - cli => 'extrusion-width=f', + cli => 'extrusion-width=s', + type => 'f', + }, + 'first_layer_extrusion_width' => { + label => 'First layer extrusion width (mm or %; leave zero to use default)', + cli => 'first-layer-extrusion-width=s', type => 'f', }, 'bridge_flow_ratio' => { @@ -283,7 +288,7 @@ our $Options = { deserialize => sub { join "\n", split /\\n/, $_[0] }, }, 'layer_gcode' => { - label => 'Layer Change G-code', + label => 'Layer change G-code', cli => 'layer-gcode=s', type => 's', multiline => 1, @@ -590,43 +595,18 @@ sub validate { die "First layer height can't be greater than --nozzle-diameter\n" if $Slic3r::_first_layer_height > $Slic3r::nozzle_diameter; - if ($Slic3r::extrusion_width) { - $Slic3r::flow_width = $Slic3r::extrusion_width =~ /^(\d+(?:\.\d+)?)%$/ - ? ($Slic3r::layer_height * $1 / 100) - : $Slic3r::extrusion_width; - } else { - # here we calculate a sane default by matching the flow speed (at the nozzle) - # and the feed rate - my $volume = ($Slic3r::nozzle_diameter**2) * PI/4; - my $shape_threshold = $Slic3r::nozzle_diameter * $Slic3r::layer_height - + ($Slic3r::layer_height**2) * PI/4; - if ($volume >= $shape_threshold) { - # rectangle with semicircles at the ends - $Slic3r::flow_width = (($Slic3r::nozzle_diameter**2) * PI + ($Slic3r::layer_height**2) * (4 - PI)) / (4 * $Slic3r::layer_height); - } else { - # rectangle with squished semicircles at the ends - $Slic3r::flow_width = $Slic3r::nozzle_diameter * ($Slic3r::nozzle_diameter/$Slic3r::layer_height - 4/PI + 1); - } - - my $min_flow_width = $Slic3r::nozzle_diameter * 1.05; - my $max_flow_width = $Slic3r::nozzle_diameter * 1.4; - $Slic3r::flow_width = $max_flow_width if $Slic3r::flow_width > $max_flow_width; - $Slic3r::flow_width = $min_flow_width if $Slic3r::flow_width < $min_flow_width; - } - - if ($Slic3r::flow_width >= ($Slic3r::nozzle_diameter + $Slic3r::layer_height)) { - # rectangle with semicircles at the ends - $Slic3r::min_flow_spacing = $Slic3r::flow_width - $Slic3r::layer_height * (1 - PI/4); - } else { - # rectangle with shrunk semicircles at the ends - $Slic3r::min_flow_spacing = $Slic3r::flow_width * (1 - PI/4) + $Slic3r::nozzle_diameter * PI/4; - } - $Slic3r::flow_spacing = $Slic3r::flow_width - $Slic3r::overlap_factor * ($Slic3r::flow_width - $Slic3r::min_flow_spacing); - + # calculate flow + ($Slic3r::flow_width, $Slic3r::min_flow_spacing, $Slic3r::flow_spacing) = calculate_flow($Slic3r::extrusion_width); Slic3r::debugf "Flow width = $Slic3r::flow_width\n"; Slic3r::debugf "Flow spacing = $Slic3r::flow_spacing\n"; Slic3r::debugf "Min flow spacing = $Slic3r::min_flow_spacing\n"; + # calculate first layer flow + ($Slic3r::first_layer_flow_width, $Slic3r::first_layer_min_flow_spacing, $Slic3r::first_layer_flow_spacing) = calculate_flow($Slic3r::first_layer_extrusion_width || $Slic3r::extrusion_width); + Slic3r::debugf "First Layer Flow width = $Slic3r::first_layer_flow_width\n"; + Slic3r::debugf "First Layer Flow spacing = $Slic3r::first_layer_flow_spacing\n"; + Slic3r::debugf "First Layer Min flow spacing = $Slic3r::first_layer_min_flow_spacing\n"; + # --perimeters die "Invalid value for --perimeters\n" if $Slic3r::perimeters < 0; @@ -743,4 +723,44 @@ sub replace_options { return $string; } +sub calculate_flow { + my ($extrusion_width) = @_; + + my ($flow_width, $min_flow_spacing, $flow_spacing); + if ($extrusion_width) { + $flow_width = $extrusion_width =~ /^(\d+(?:\.\d+)?)%$/ + ? ($Slic3r::layer_height * $1 / 100) + : $extrusion_width; + } else { + # here we calculate a sane default by matching the flow speed (at the nozzle) + # and the feed rate + my $volume = ($Slic3r::nozzle_diameter**2) * PI/4; + my $shape_threshold = $Slic3r::nozzle_diameter * $Slic3r::layer_height + + ($Slic3r::layer_height**2) * PI/4; + if ($volume >= $shape_threshold) { + # rectangle with semicircles at the ends + $flow_width = (($Slic3r::nozzle_diameter**2) * PI + ($Slic3r::layer_height**2) * (4 - PI)) / (4 * $Slic3r::layer_height); + } else { + # rectangle with squished semicircles at the ends + $flow_width = $Slic3r::nozzle_diameter * ($Slic3r::nozzle_diameter/$Slic3r::layer_height - 4/PI + 1); + } + + my $min_flow_width = $Slic3r::nozzle_diameter * 1.05; + my $max_flow_width = $Slic3r::nozzle_diameter * 1.4; + $flow_width = $max_flow_width if $flow_width > $max_flow_width; + $flow_width = $min_flow_width if $flow_width < $min_flow_width; + } + + if ($flow_width >= ($Slic3r::nozzle_diameter + $Slic3r::layer_height)) { + # rectangle with semicircles at the ends + $min_flow_spacing = $flow_width - $Slic3r::layer_height * (1 - PI/4); + } else { + # rectangle with shrunk semicircles at the ends + $min_flow_spacing = $flow_width * (1 - PI/4) + $Slic3r::nozzle_diameter * PI/4; + } + $flow_spacing = $flow_width - $Slic3r::overlap_factor * ($flow_width - $min_flow_spacing); + + return ($flow_width, $min_flow_spacing, $flow_spacing); +} + 1; diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index f58bb2ab9..ef5cd79b2 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -102,7 +102,7 @@ sub extrude_loop { # clip the path to avoid the extruder to get exactly on the first point of the loop; # if polyline was shorter than the clipping distance we'd get a null polyline, so # we discard it in that case - $extrusion_path->clip_end(scale $Slic3r::flow_width * 0.15); + $extrusion_path->clip_end(scale($self->layer->flow_width || $Slic3r::flow_width) * 0.15); return '' if !@{$extrusion_path->polyline}; # extrude along the path @@ -129,7 +129,7 @@ sub extrude_path { { my $distance_from_last_pos = $self->last_pos->distance_to($path->points->[0]) * $Slic3r::scaling_factor; my $distance_threshold = $Slic3r::retract_before_travel; - $distance_threshold = 2 * $Slic3r::flow_width / $Slic3r::fill_density * sqrt(2) + $distance_threshold = 2 * ($self->layer->flow_width || $Slic3r::flow_width) / $Slic3r::fill_density * sqrt(2) if $Slic3r::fill_density > 0 && $description =~ /fill/; if ($distance_from_last_pos >= $distance_threshold) { @@ -145,7 +145,7 @@ sub extrude_path { $gcode .= $self->unretract if $self->retracted; # calculate extrusion length per distance unit - my $s = $path->flow_spacing || $Slic3r::flow_spacing; + my $s = $path->flow_spacing || $self->layer->flow_spacing || $Slic3r::flow_spacing; my $h = $path->depth_layers * $self->layer->height; my $w = ($s - $Slic3r::min_flow_spacing * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor); diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 0bb20e007..bfdb1d8bb 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -99,7 +99,7 @@ sub make_fill { # add spacing between adjacent surfaces { - my $distance = scale $Slic3r::flow_spacing / 2; + my $distance = scale $layer->flow_spacing / 2; my @offsets = (); foreach my $surface (@surfaces) { my $expolygon = $surface->expolygon; @@ -137,7 +137,7 @@ sub make_fill { SURFACE: foreach my $surface (@surfaces) { my $filler = $Slic3r::fill_pattern; my $density = $Slic3r::fill_density; - my $flow_spacing = $Slic3r::flow_spacing; + my $flow_spacing = $layer->flow_spacing; my $is_bridge = $layer->id > 0 && $surface->surface_type == S_TYPE_BOTTOM; my $is_solid = (grep { $surface->surface_type == $_ } S_TYPE_TOP, S_TYPE_BOTTOM, S_TYPE_INTERNALSOLID) ? 1 : 0; diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index 7fb0f87c9..92c5b50c8 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -64,7 +64,7 @@ sub fill_surface { $path->deserialize; # clip the path to avoid the extruder to get exactly on the first point of the loop - $path->clip_end(scale $Slic3r::flow_width * 0.15); + $path->clip_end(scale($self->layer->flow_width || $Slic3r::flow_width) * 0.15); push @paths, $path->points if @{$path->points}; } diff --git a/lib/Slic3r/Fill/Honeycomb.pm b/lib/Slic3r/Fill/Honeycomb.pm index 0ae87aca8..350863f85 100644 --- a/lib/Slic3r/Fill/Honeycomb.pm +++ b/lib/Slic3r/Fill/Honeycomb.pm @@ -21,7 +21,7 @@ sub fill_surface { # infill math my $min_spacing = scale $params{flow_spacing}; my $distance = $min_spacing / $params{density}; - my $overlap_distance = scale $Slic3r::flow_width * 0.4; + my $overlap_distance = scale($self->layer->flow_width || $Slic3r::flow_width) * 0.4; my $cache_id = sprintf "d%s_s%s_a%s", $params{density}, $params{flow_spacing}, $rotate_vector->[0][0]; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index f7133f7b3..3e2f0e5a3 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -32,7 +32,7 @@ sub fill_surface { $flow_spacing = unscale $distance_between_lines; } - my $overlap_distance = scale $Slic3r::flow_width * 0.4; + my $overlap_distance = scale($self->layer->flow_width || $Slic3r::flow_width) * 0.4; my $x = $bounding_box->[X1]; my $is_line_pattern = $self->isa('Slic3r::Fill::Line'); diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index b61c40804..bd6cfb3a4 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -70,7 +70,7 @@ sub new { }, extrusion => { title => 'Extrusion', - options => [qw(extrusion_width bridge_flow_ratio)], + options => [qw(extrusion_width first_layer_extrusion_width bridge_flow_ratio)], }, output => { title => 'Output', diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index a85a68c17..b59b112d1 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -19,6 +19,8 @@ has 'slicing_errors' => (is => 'rw'); has 'slice_z' => (is => 'lazy'); has 'print_z' => (is => 'lazy'); has 'height' => (is => 'lazy'); +has 'flow_spacing' => (is => 'lazy'); +has 'flow_width' => (is => 'lazy'); # collection of spare segments generated by slicing the original geometry; # these need to be merged in continuos (closed) polylines @@ -99,6 +101,16 @@ sub _build_height { return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height; } +sub _build_flow_spacing { + my $self = shift; + return $self->id == 0 ? $Slic3r::first_layer_flow_spacing : $Slic3r::flow_spacing; +} + +sub _build_flow_width { + my $self = shift; + return $self->id == 0 ? $Slic3r::first_layer_flow_width : $Slic3r::flow_width; +} + sub add_line { my $self = shift; my ($line) = @_; @@ -127,7 +139,7 @@ sub make_surfaces { # the contours must be offsetted by half extrusion width inwards { - my $distance = scale $Slic3r::flow_width / 2; + my $distance = scale $self->flow_width / 2; my @surfaces = @{$self->slices}; @{$self->slices} = (); foreach my $surface (@surfaces) { @@ -146,12 +158,12 @@ sub make_surfaces { ); if (@$diff) { - my $area_threshold = scale($Slic3r::flow_spacing) ** 2; + my $area_threshold = scale($self->flow_spacing) ** 2; @$diff = grep $_->area > ($area_threshold), @$diff; push @{$self->thin_walls}, grep $_, - map $_->medial_axis(scale $Slic3r::flow_width), + map $_->medial_axis(scale $self->flow_width), @$diff; Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls}; @@ -201,8 +213,8 @@ sub make_perimeters { next unless $circumference <= $Slic3r::small_perimeter_length; # revert the compensation done in make_surfaces() and get the actual radius # of the hole - my $radius = ($circumference / PI / 2) - scale $Slic3r::flow_spacing/2; - my $new_radius = (scale($Slic3r::flow_width) + sqrt((scale($Slic3r::flow_width)**2) + (4*($radius**2)))) / 2; + my $radius = ($circumference / PI / 2) - scale $self->flow_spacing/2; + my $new_radius = (scale($self->flow_width) + sqrt((scale($self->flow_width)**2) + (4*($radius**2)))) / 2; # holes are always turned to contours, so reverse point order before and after $hole->reverse; my @offsetted = $hole->offset(+ ($new_radius - $radius)); @@ -221,7 +233,7 @@ sub make_perimeters { push @{ $perimeters[-1] }, [@last_offsets]; # offset distance for inner loops - $distance = scale $Slic3r::flow_spacing; + $distance = scale $self->flow_spacing; } # create one more offset to be used as boundary for fill @@ -237,7 +249,7 @@ sub make_perimeters { ); push @{ $self->thin_fills }, grep $_, - map $_->medial_axis(scale $Slic3r::flow_width), + map $_->medial_axis(scale $self->flow_width), @$small_gaps if 0; } } @@ -309,7 +321,7 @@ sub add_perimeter { my $self = shift; my ($polygon, $role) = @_; - return unless $polygon->is_printable; + return unless $polygon->is_printable($self->flow_width); push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new( polygon => $polygon, role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/ @@ -324,7 +336,7 @@ sub prepare_fill_surfaces { # merge too small internal surfaces with their surrounding tops # (if they're too small, they can be treated as solid) { - my $min_area = ((7 * $Slic3r::flow_spacing / $Slic3r::scaling_factor)**2) * PI; + my $min_area = ((7 * $self->flow_spacing / $Slic3r::scaling_factor)**2) * PI; my $small_internal = [ grep { $_->expolygon->contour->area <= $min_area } grep { $_->surface_type == S_TYPE_INTERNAL } @@ -357,7 +369,7 @@ sub prepare_fill_surfaces { sub remove_small_surfaces { my $self = shift; - my $distance = scale $Slic3r::flow_spacing / 2; + my $distance = scale $self->flow_spacing / 2; my @surfaces = @{$self->fill_surfaces}; @{$self->fill_surfaces} = (); @@ -417,7 +429,7 @@ sub process_bridges { # offset the contour and intersect it with the internal surfaces to discover # which of them has contact with our bridge my @supporting_surfaces = (); - my ($contour_offset) = $expolygon->contour->offset(scale $Slic3r::flow_spacing * sqrt(2)); + my ($contour_offset) = $expolygon->contour->offset(scale $self->flow_spacing * sqrt(2)); foreach my $internal_surface (@internal_surfaces) { my $intersection = intersection_ex([$contour_offset], [$internal_surface->p]); if (@$intersection) { diff --git a/lib/Slic3r/Polygon.pm b/lib/Slic3r/Polygon.pm index ece4aec4e..71c6857b3 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -103,6 +103,7 @@ sub subdivide { # returns false if the polyline is too tight to be printed sub is_printable { my $self = shift; + my ($flow_width) = @_; # try to get an inwards offset # for a distance equal to half of the extrusion width; @@ -113,7 +114,7 @@ sub is_printable { # detect them and we would be discarding them. my $p = $self->clone; $p->make_counter_clockwise; - return $p->offset(scale $Slic3r::flow_width / 2) ? 1 : 0; + return $p->offset(scale($flow_width || $Slic3r::flow_width) / 2) ? 1 : 0; } sub is_valid { diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 848c8f42e..cf54569b7 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -441,6 +441,8 @@ sub write_gcode { printf $fh "; %s = %s\n", $_, Slic3r::Config->get($_); } printf $fh "; single wall width = %.2fmm\n", $Slic3r::flow_width; + printf $fh "; first layer single wall width = %.2fmm\n", $Slic3r::first_layer_flow_width + if $Slic3r::first_layer_flow_width != $Slic3r::flow_width; print $fh "\n"; # set up our extruder object diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index ca4c544ea..9e451eb9e 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -169,18 +169,18 @@ sub make_perimeters { # compare each layer to the one below, and mark those slices needing # one additional inner perimeter, like the top of domed objects- - # this algorithm makes sure that almost one perimeter is overlapping: - my $overlap = $Slic3r::flow_spacing; - + # this algorithm makes sure that almost one perimeter is overlapping for my $layer_id (0 .. $self->layer_count-2) { my $layer = $self->layers->[$layer_id]; my $upper_layer = $self->layers->[$layer_id+1]; + my $overlap = $layer->flow_spacing; # one perimeter + # compute polygons representing the thickness of the first external perimeter of # the upper layer slices my $upper = diff_ex( - [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $Slic3r::flow_spacing), @{$upper_layer->slices} ], - [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $Slic3r::flow_spacing)), @{$upper_layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->flow_spacing), @{$upper_layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->flow_spacing)), @{$upper_layer->slices} ], ); next if !@$upper; @@ -189,10 +189,10 @@ sub make_perimeters { my $ignore = []; { my $diff = diff_ex( - [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $Slic3r::flow_spacing), @{$layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->flow_spacing), @{$layer->slices} ], [ map @{$_->expolygon}, @{$upper_layer->slices} ], ); - $ignore = [ map @$_, map $_->offset_ex(scale $Slic3r::flow_spacing), @$diff ]; + $ignore = [ map @$_, map $_->offset_ex(scale $layer->flow_spacing), @$diff ]; } foreach my $slice (@{$layer->slices}) { @@ -202,9 +202,9 @@ sub make_perimeters { # of our slice my $hypothetical_perimeter; { - my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $Slic3r::flow_spacing) ]; + my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->flow_spacing) ]; last CYCLE if !@$outer; - my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $Slic3r::flow_spacing) ]; + my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->flow_spacing) ]; last CYCLE if !@$inner; $hypothetical_perimeter = diff_ex($outer, $inner); } @@ -230,13 +230,13 @@ sub detect_surfaces_type { # prepare a reusable subroutine to make surface differences my $surface_difference = sub { - my ($subject_surfaces, $clip_surfaces, $result_type) = @_; + my ($subject_surfaces, $clip_surfaces, $result_type, $layer) = @_; my $expolygons = diff_ex( [ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$subject_surfaces ], [ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$clip_surfaces ], 1, ); - return grep $_->contour->is_printable, + return grep $_->contour->is_printable($layer->flow_width), map Slic3r::Surface->new(expolygon => $_, surface_type => $result_type), @$expolygons; }; @@ -251,7 +251,7 @@ sub detect_surfaces_type { # find top surfaces (difference between current surfaces # of current layer and upper one) if ($upper_layer) { - @top = $surface_difference->($layer->slices, $upper_layer->slices, S_TYPE_TOP); + @top = $surface_difference->($layer->slices, $upper_layer->slices, S_TYPE_TOP, $layer); } else { # if no upper layer, all surfaces of this one are solid @top = @{$layer->slices}; @@ -261,7 +261,7 @@ sub detect_surfaces_type { # find bottom surfaces (difference between current surfaces # of current layer and lower one) if ($lower_layer) { - @bottom = $surface_difference->($layer->slices, $lower_layer->slices, S_TYPE_BOTTOM); + @bottom = $surface_difference->($layer->slices, $lower_layer->slices, S_TYPE_BOTTOM, $layer); } else { # if no lower layer, all surfaces of this one are solid @bottom = @{$layer->slices}; @@ -274,11 +274,11 @@ sub detect_surfaces_type { if (@top && @bottom) { my $overlapping = intersection_ex([ map $_->p, @top ], [ map $_->p, @bottom ]); Slic3r::debugf " layer %d contains %d membrane(s)\n", $layer->id, scalar(@$overlapping); - @top = $surface_difference->([@top], $overlapping, S_TYPE_TOP); + @top = $surface_difference->([@top], $overlapping, S_TYPE_TOP, $layer); } # find internal surfaces (difference between top/bottom surfaces and others) - @internal = $surface_difference->($layer->slices, [@top, @bottom], S_TYPE_INTERNAL); + @internal = $surface_difference->($layer->slices, [@top, @bottom], S_TYPE_INTERNAL, $layer); # save surfaces to layer @{$layer->slices} = (@bottom, @top, @internal); @@ -317,7 +317,7 @@ sub discover_horizontal_shells { foreach my $type (S_TYPE_TOP, S_TYPE_BOTTOM) { # find surfaces of current type for current layer # and offset them to take perimeters into account - my @surfaces = map $_->offset($Slic3r::perimeters * scale $Slic3r::flow_width), + my @surfaces = map $_->offset($Slic3r::perimeters * scale $layer->flow_width), grep $_->surface_type == $type, @{$layer->fill_surfaces} or next; my $surfaces_p = [ map $_->p, @surfaces ]; Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n", @@ -512,13 +512,13 @@ sub generate_support_material { # those parts. a visibility check algorithm is needed. # @a = @{diff_ex( # [ map $_->p, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices} ], - # [ map @$_, map $_->expolygon->offset_ex(scale $Slic3r::flow_spacing * $Slic3r::perimeters), + # [ map @$_, map $_->expolygon->offset_ex(scale $layer->flow_spacing * $Slic3r::perimeters), # grep $_->surface_type == S_TYPE_BOTTOM && defined $_->bridge_angle, # @{$layer->fill_surfaces} ], # )}; @a = map $_->expolygon->clone, grep $_->surface_type == S_TYPE_BOTTOM, @{$layer->slices}; - $_->simplify(scale $Slic3r::flow_spacing * 3) for @a; + $_->simplify(scale $layer->flow_spacing * 3) for @a; push @unsupported_expolygons, @a; } } diff --git a/slic3r.pl b/slic3r.pl index 607b4ba20..058aaac09 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -254,6 +254,8 @@ $j Flow options (advanced): --extrusion-width Set extrusion width manually; it accepts either an absolute value in mm (like 0.65) or a percentage over layer height (like 200%) + --first-layer-extrusion-width + Set a different extrusion width for first layer --bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: $Slic3r::bridge_flow_ratio) EOF