diff --git a/MANIFEST b/MANIFEST index 3ef71cec0..1568fc498 100644 --- a/MANIFEST +++ b/MANIFEST @@ -18,6 +18,7 @@ lib/Slic3r/Fill/Line.pm lib/Slic3r/Fill/OctagramSpiral.pm lib/Slic3r/Fill/PlanePath.pm lib/Slic3r/Fill/Rectilinear.pm +lib/Slic3r/Flow.pm lib/Slic3r/Format/AMF.pm lib/Slic3r/Format/AMF/Parser.pm lib/Slic3r/Format/OBJ.pm diff --git a/README.markdown b/README.markdown index 9041b8823..c43b2880a 100644 --- a/README.markdown +++ b/README.markdown @@ -210,6 +210,10 @@ The author is Alessandro Ranellucci. 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%) + --perimeters-extrusion-width + Set a different extrusion width for perimeters + --infill-extrusion-width + Set a different extrusion width for infill --bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: 1) diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index bd7eedde6..3eec3d000 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -33,6 +33,7 @@ use Slic3r::ExtrusionPath; use Slic3r::ExtrusionPath::Arc; use Slic3r::ExtrusionPath::Collection; use Slic3r::Fill; +use Slic3r::Flow; use Slic3r::Format::AMF; use Slic3r::Format::OBJ; use Slic3r::Format::STL; @@ -100,16 +101,16 @@ our $_first_layer_height = undef; # mm (computed) 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; +our $extrusion_width = 0; +our $first_layer_extrusion_width = 0; +our $perimeters_extrusion_width = 0; +our $infill_extrusion_width = 0; +our $bridge_flow_ratio = 1; +our $overlap_factor = 0.5; +our $flow = Slic3r::Flow->new; +our $first_layer_flow = undef; +our $perimeters_flow = Slic3r::Flow->new; +our $infill_flow = Slic3r::Flow->new; # print options our $perimeters = 3; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index 495fbf9d4..5fba4b903 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -204,10 +204,20 @@ our $Options = { type => 'f', }, 'first_layer_extrusion_width' => { - label => 'First layer extrusion width (mm or %; leave zero to use default)', + label => 'First layer extrusion width (mm or % or 0 for default)', cli => 'first-layer-extrusion-width=s', type => 'f', }, + 'perimeters_extrusion_width' => { + label => 'Perimeters extrusion width (mm or % or 0 for default)', + cli => 'perimeters-extrusion-width=s', + type => 'f', + }, + 'infill_extrusion_width' => { + label => 'Infill extrusion width (mm or % or 0 for default)', + cli => 'infill-extrusion-width=s', + type => 'f', + }, 'bridge_flow_ratio' => { label => 'Bridge flow ratio', cli => 'bridge-flow-ratio=f', @@ -596,16 +606,13 @@ sub validate { if $Slic3r::_first_layer_height > $Slic3r::nozzle_diameter; # 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"; + $Slic3r::flow->calculate($Slic3r::extrusion_width); + $Slic3r::first_layer_flow->calculate($Slic3r::first_layer_extrusion_width) + if $Slic3r::first_layer_extrusion_width; + $Slic3r::perimeters_flow->calculate($Slic3r::perimeters_extrusion_width || $Slic3r::extrusion_width); + $Slic3r::infill_flow->calculate($Slic3r::infill_extrusion_width || $Slic3r::extrusion_width); + Slic3r::debugf "Default flow width = %s, spacing = %s, min_spacing = %d\n", + $Slic3r::flow->width, $Slic3r::flow->spacing, $Slic3r::flow->min_spacing; # --perimeters die "Invalid value for --perimeters\n" @@ -723,44 +730,4 @@ 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 ef5cd79b2..b54cae00a 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($self->layer->flow_width || $Slic3r::flow_width) * 0.15); + $extrusion_path->clip_end(scale($self->layer ? $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 * ($self->layer->flow_width || $Slic3r::flow_width) / $Slic3r::fill_density * sqrt(2) + $distance_threshold = 2 * ($self->layer ? $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,9 +145,9 @@ sub extrude_path { $gcode .= $self->unretract if $self->retracted; # calculate extrusion length per distance unit - my $s = $path->flow_spacing || $self->layer->flow_spacing || $Slic3r::flow_spacing; + my $s = $path->flow_spacing || $self->layer ? $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); + my $w = ($s - ($self->layer ? $self->layer->flow->min_spacing : $Slic3r::flow->min_spacing) * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor); my $area; if ($path->role == EXTR_ROLE_BRIDGE) { diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index bfdb1d8bb..368fbe454 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 $layer->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 = $layer->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 92c5b50c8..920f00ac2 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($self->layer->flow_width || $Slic3r::flow_width) * 0.15); + $path->clip_end(scale($self->layer ? $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 350863f85..924bf7f81 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($self->layer->flow_width || $Slic3r::flow_width) * 0.4; + my $overlap_distance = scale($self->layer ? $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 3e2f0e5a3..b13342436 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($self->layer->flow_width || $Slic3r::flow_width) * 0.4; + my $overlap_distance = scale($self->layer ? $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/Flow.pm b/lib/Slic3r/Flow.pm new file mode 100644 index 000000000..6a5675c3a --- /dev/null +++ b/lib/Slic3r/Flow.pm @@ -0,0 +1,53 @@ +package Slic3r::Flow; +use Moo; + +use Slic3r::Geometry qw(PI); + +has 'width' => (is => 'rw'); +has 'min_spacing' => (is => 'rw'); +has 'spacing' => (is => 'rw'); + +sub calculate { + my $self = shift; + 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); + + $self->width($flow_width); + $self->min_spacing($min_flow_spacing); + $self->spacing($flow_spacing); +} + +1; diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index bd6cfb3a4..681adacf4 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 first_layer_extrusion_width bridge_flow_ratio)], + options => [qw(extrusion_width first_layer_extrusion_width perimeters_extrusion_width infill_extrusion_width bridge_flow_ratio)], }, output => { title => 'Output', diff --git a/lib/Slic3r/Geometry.pm b/lib/Slic3r/Geometry.pm index 304a0fecf..8a9e5ac32 100644 --- a/lib/Slic3r/Geometry.pm +++ b/lib/Slic3r/Geometry.pm @@ -890,7 +890,7 @@ sub arrange { # margin needed for the skirt my $skirt_margin; if ($Slic3r::skirts > 0) { - $skirt_margin = ($Slic3r::flow_spacing * $Slic3r::skirts + $Slic3r::skirt_distance) * 2; + $skirt_margin = ($Slic3r::flow->spacing * $Slic3r::skirts + $Slic3r::skirt_distance) * 2; } else { $skirt_margin = 0; } diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index b59b112d1..531f08435 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -19,8 +19,9 @@ 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'); +has 'flow' => (is => 'lazy'); +has 'perimeters_flow' => (is => 'lazy'); +has 'infill_flow' => (is => 'lazy'); # collection of spare segments generated by slicing the original geometry; # these need to be merged in continuos (closed) polylines @@ -101,14 +102,25 @@ sub _build_height { return $self->id == 0 ? $Slic3r::_first_layer_height : $Slic3r::layer_height; } -sub _build_flow_spacing { +sub _build_flow { my $self = shift; - return $self->id == 0 ? $Slic3r::first_layer_flow_spacing : $Slic3r::flow_spacing; + return $self->id == 0 && $Slic3r::first_layer_flow + ? $Slic3r::first_layer_flow + : $Slic3r::flow; } -sub _build_flow_width { +sub _build_perimeters_flow { my $self = shift; - return $self->id == 0 ? $Slic3r::first_layer_flow_width : $Slic3r::flow_width; + return $self->id == 0 && $Slic3r::first_layer_flow + ? $Slic3r::first_layer_flow + : $Slic3r::perimeters_flow; +} + +sub _build_infill_flow { + my $self = shift; + return $self->id == 0 && $Slic3r::first_layer_flow + ? $Slic3r::first_layer_flow + : $Slic3r::infill_flow; } sub add_line { @@ -139,7 +151,7 @@ sub make_surfaces { # the contours must be offsetted by half extrusion width inwards { - my $distance = scale $self->flow_width / 2; + my $distance = scale $self->perimeters_flow->width / 2; my @surfaces = @{$self->slices}; @{$self->slices} = (); foreach my $surface (@surfaces) { @@ -158,12 +170,12 @@ sub make_surfaces { ); if (@$diff) { - my $area_threshold = scale($self->flow_spacing) ** 2; + my $area_threshold = scale($self->perimeters_flow->spacing) ** 2; @$diff = grep $_->area > ($area_threshold), @$diff; push @{$self->thin_walls}, grep $_, - map $_->medial_axis(scale $self->flow_width), + map $_->medial_axis(scale $self->perimeters_flow->width), @$diff; Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls}; @@ -213,8 +225,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 $self->flow_spacing/2; - my $new_radius = (scale($self->flow_width) + sqrt((scale($self->flow_width)**2) + (4*($radius**2)))) / 2; + my $radius = ($circumference / PI / 2) - scale $self->perimeters_flow->spacing/2; + my $new_radius = (scale($self->perimeters_flow->width) + sqrt((scale($self->perimeters_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)); @@ -233,7 +245,7 @@ sub make_perimeters { push @{ $perimeters[-1] }, [@last_offsets]; # offset distance for inner loops - $distance = scale $self->flow_spacing; + $distance = scale $self->perimeters_flow->spacing; } # create one more offset to be used as boundary for fill @@ -249,7 +261,7 @@ sub make_perimeters { ); push @{ $self->thin_fills }, grep $_, - map $_->medial_axis(scale $self->flow_width), + map $_->medial_axis(scale $self->perimeters_flow->width), @$small_gaps if 0; } } @@ -321,7 +333,7 @@ sub add_perimeter { my $self = shift; my ($polygon, $role) = @_; - return unless $polygon->is_printable($self->flow_width); + return unless $polygon->is_printable($self->perimeters_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), #/ @@ -336,7 +348,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 * $self->flow_spacing / $Slic3r::scaling_factor)**2) * PI; + my $min_area = ((7 * $self->infill_flow->spacing / $Slic3r::scaling_factor)**2) * PI; my $small_internal = [ grep { $_->expolygon->contour->area <= $min_area } grep { $_->surface_type == S_TYPE_INTERNAL } @@ -369,7 +381,7 @@ sub prepare_fill_surfaces { sub remove_small_surfaces { my $self = shift; - my $distance = scale $self->flow_spacing / 2; + my $distance = scale $self->infill_flow->spacing / 2; my @surfaces = @{$self->fill_surfaces}; @{$self->fill_surfaces} = (); @@ -429,7 +441,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 $self->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 71c6857b3..87036a24f 100644 --- a/lib/Slic3r/Polygon.pm +++ b/lib/Slic3r/Polygon.pm @@ -114,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($flow_width || $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 cf54569b7..7bf490c56 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -410,7 +410,7 @@ sub make_skirt { # draw outlines from outside to inside my @skirt = (); for (my $i = $Slic3r::skirts - 1; $i >= 0; $i--) { - my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow_spacing * $i)); + my $distance = scale ($Slic3r::skirt_distance + ($Slic3r::flow->spacing * $i)); my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND); push @skirt, Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@{$outline->[0]}), @@ -440,9 +440,9 @@ sub write_gcode { extrusion_multiplier perimeter_speed infill_speed travel_speed scale)) { 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; + 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; print $fh "\n"; # set up our extruder object diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 9e451eb9e..006320a5f 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -174,13 +174,13 @@ sub make_perimeters { my $layer = $self->layers->[$layer_id]; my $upper_layer = $self->layers->[$layer_id+1]; - my $overlap = $layer->flow_spacing; # one perimeter + my $overlap = $layer->perimeters_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 $layer->flow_spacing), @{$upper_layer->slices} ], - [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->flow_spacing)), @{$upper_layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * scale $layer->perimeters_flow->spacing), @{$upper_layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * scale $layer->perimeters_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 $layer->flow_spacing), @{$layer->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::perimeters-0.5) * scale $layer->perimeters_flow->spacing), @{$layer->slices} ], [ map @{$_->expolygon}, @{$upper_layer->slices} ], ); - $ignore = [ map @$_, map $_->offset_ex(scale $layer->flow_spacing), @$diff ]; + $ignore = [ map @$_, map $_->offset_ex(scale $layer->perimeters_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 $layer->flow_spacing) ]; + my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * scale $layer->perimeters_flow->spacing) ]; last CYCLE if !@$outer; - my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->flow_spacing) ]; + my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * scale $layer->perimeters_flow->spacing) ]; last CYCLE if !@$inner; $hypothetical_perimeter = diff_ex($outer, $inner); } @@ -236,7 +236,7 @@ sub detect_surfaces_type { [ map { ref $_ eq 'ARRAY' ? $_ : ref $_ eq 'Slic3r::ExPolygon' ? @$_ : $_->p } @$clip_surfaces ], 1, ); - return grep $_->contour->is_printable($layer->flow_width), + return grep $_->contour->is_printable($layer->flow->width), map Slic3r::Surface->new(expolygon => $_, surface_type => $result_type), @$expolygons; }; @@ -310,14 +310,14 @@ sub discover_horizontal_shells { Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n"; - my $area_threshold = scale($Slic3r::flow_spacing) ** 2; + my $area_threshold = scale($Slic3r::flow->spacing) ** 2; for (my $i = 0; $i < $self->layer_count; $i++) { my $layer = $self->layers->[$i]; 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 $layer->flow_width), + my @surfaces = map $_->offset($Slic3r::perimeters * scale $layer->perimeters_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", @@ -396,7 +396,7 @@ sub infill_every_layers { my $self = shift; return unless $Slic3r::infill_every_layers > 1 && $Slic3r::fill_density > 0; - my $area_threshold = scale($Slic3r::flow_spacing) ** 2; + my $area_threshold = scale($Slic3r::flow->spacing) ** 2; # start from bottom, skip first layer for (my $i = 1; $i < $self->layer_count; $i++) { @@ -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 $layer->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 $layer->flow_spacing * 3) for @a; + $_->simplify(scale $layer->flow->spacing * 3) for @a; push @unsupported_expolygons, @a; } } @@ -541,7 +541,7 @@ sub generate_support_material { #bridge_angle => $Slic3r::fill_angle + 45 + $angle, ), density => 0.20, - flow_spacing => $Slic3r::flow_spacing, + flow_spacing => $Slic3r::flow->spacing, ); my $params = shift @paths; diff --git a/slic3r.pl b/slic3r.pl index 058aaac09..1ad8c2a1f 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -256,6 +256,10 @@ $j (like 0.65) or a percentage over layer height (like 200%) --first-layer-extrusion-width Set a different extrusion width for first layer + --perimeters-extrusion-width + Set a different extrusion width for perimeters + --infill-extrusion-width + Set a different extrusion width for infill --bridge-flow-ratio Multiplier for extrusion when bridging (> 0, default: $Slic3r::bridge_flow_ratio) EOF