diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 7d0556f893..ccbb5ee8d4 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->infill_flow->spacing / 2; + my $distance = $layer->infill_flow->scaled_spacing / 2; my @offsets = (); foreach my $surface (@surfaces) { my $expolygon = $surface->expolygon; diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index c0d172cfe3..699b526d9e 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -63,7 +63,7 @@ sub fill_surface { my $path = $loop->split_at_index($index); # clip the path to avoid the extruder to get exactly on the first point of the loop - $path->clip_end(scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.15); + $path->clip_end($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_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 1e407e2e6e..70dd1e2ad0 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 ? $self->layer->flow->width : $Slic3r::flow->width) * 0.4; + my $overlap_distance = $self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_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 121249eaa8..b4569dbc82 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -31,7 +31,7 @@ sub fill_surface { $flow_spacing = unscale $distance_between_lines; } - my $overlap_distance = scale($self->layer ? $self->layer->flow->width : $Slic3r::flow->width) * 0.4; + my $overlap_distance = $self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_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 index 9c01dd30c0..15e54cfcf7 100644 --- a/lib/Slic3r/Flow.pm +++ b/lib/Slic3r/Flow.pm @@ -1,13 +1,15 @@ package Slic3r::Flow; use Moo; -use Slic3r::Geometry qw(PI); +use Slic3r::Geometry qw(PI scale); has 'nozzle_diameter' => (is => 'ro', required => 1); has 'layer_height' => (is => 'ro', default => sub { $Slic3r::Config->layer_height }); has 'width' => (is => 'rwp', builder => 1); has 'spacing' => (is => 'lazy'); +has 'scaled_width' => (is => 'lazy'); +has 'scaled_spacing' => (is => 'lazy'); sub BUILD { my $self = shift; @@ -55,4 +57,14 @@ sub _build_spacing { return $self->width - &Slic3r::OVERLAP_FACTOR * ($self->width - $min_flow_spacing); } +sub _build_scaled_width { + my $self = shift; + return scale $self->width; +} + +sub _build_scaled_spacing { + my $self = shift; + return scale $self->spacing; +} + 1; diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index f465a6400b..5b5848cbe6 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -101,7 +101,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 ? $self->layer->flow->width : $Slic3r::flow->width) * 0.15); + $extrusion_path->clip_end($self->layer ? $self->layer->flow->scaled_width : $Slic3r::flow->scaled_width * 0.15); return '' if !@{$extrusion_path->polyline}; # extrude along the path diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 88ee6fb7d4..78de6499ef 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -83,7 +83,7 @@ sub make_surfaces { # the contours must be offsetted by half extrusion width inwards { - my $distance = scale $self->perimeter_flow->width / 2; + my $distance = $self->perimeter_flow->scaled_width / 2; my @surfaces = @{$self->slices}; @{$self->slices} = (); foreach my $surface (@surfaces) { @@ -104,10 +104,10 @@ sub make_surfaces { $self->thin_walls([]); if (@$diff) { - my $area_threshold = scale($self->perimeter_flow->spacing) ** 2; + my $area_threshold = $self->perimeter_flow->scaled_spacing ** 2; @$diff = grep $_->area > ($area_threshold), @$diff; - @{$self->thin_walls} = map $_->medial_axis(scale $self->perimeter_flow->width), @$diff; + @{$self->thin_walls} = map $_->medial_axis($self->perimeter_flow->scaled_width), @$diff; Slic3r::debugf " %d thin walls detected\n", scalar(@{$self->thin_walls}) if @{$self->thin_walls}; } @@ -125,7 +125,7 @@ sub make_surfaces { sub make_perimeters { my $self = shift; - my $gap_area_threshold = scale($self->perimeter_flow->width)** 2; + my $gap_area_threshold = $self->perimeter_flow->scaled_width ** 2; # this array will hold one arrayref per original surface (island); # each item of this arrayref is an arrayref representing a depth (from outer @@ -162,12 +162,12 @@ sub make_perimeters { # this compensation only works for circular holes, while it would # overcompensate for hexagons and other shapes having straight edges. # so we require a minimum number of vertices. - next unless $circumference / @$hole >= scale 3 * $Slic3r::flow->width; + next unless $circumference / @$hole >= 3 * $Slic3r::flow->scaled_width; # revert the compensation done in make_surfaces() and get the actual radius # of the hole - my $radius = ($circumference / PI / 2) - scale $self->perimeter_flow->spacing/2; - my $new_radius = (scale($self->perimeter_flow->width) + sqrt((scale($self->perimeter_flow->width)**2) + (4*($radius**2)))) / 2; + my $radius = ($circumference / PI / 2) - $self->perimeter_flow->scaled_spacing/2; + my $new_radius = ($self->perimeter_flow->scaled_width + sqrt(($self->perimeter_flow->scaled_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)); @@ -177,7 +177,7 @@ sub make_perimeters { } } - my $distance = scale $self->perimeter_flow->spacing; + my $distance = $self->perimeter_flow->scaled_spacing; my @gaps = (); # generate perimeters inwards (loop 0 is the external one) @@ -211,7 +211,7 @@ sub make_perimeters { # detect the small gaps that we need to treat like thin polygons, # thus generating the skeleton and using it to fill them push @{ $self->thin_fills }, - map $_->medial_axis(scale $self->perimeter_flow->width), + map $_->medial_axis($self->perimeter_flow->scaled_width), @gaps; Slic3r::debugf " %d gaps filled\n", scalar @{ $self->thin_fills } if @{ $self->thin_fills }; @@ -324,7 +324,7 @@ sub prepare_fill_surfaces { # remove unprintable regions (they would slow down the infill process and also cause # some weird failures during bridge neighbor detection) { - my $distance = scale $self->infill_flow->spacing / 2; + my $distance = $self->infill_flow->scaled_spacing / 2; @surfaces = map { my $surface = $_; diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index d4df4273b0..4c8cc0ba5f 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -573,7 +573,7 @@ sub make_brim { return unless $Slic3r::Config->brim_width > 0; my $flow = $Slic3r::first_layer_flow || $Slic3r::flow; - my $grow_distance = scale $flow->width / 2; + my $grow_distance = $flow->scaled_width / 2; my @islands = (); # array of polygons foreach my $obj_idx (0 .. $#{$self->objects}) { my $layer0 = $self->objects->[$obj_idx]->layers->[0]; @@ -593,7 +593,7 @@ sub make_brim { push @{$self->brim}, Slic3r::ExtrusionLoop->pack( polygon => Slic3r::Polygon->new($_), role => EXTR_ROLE_SKIRT, - ) for @{Math::Clipper::offset(\@islands, $i * scale $flow->spacing, 100, JT_SQUARE)}; + ) for @{Math::Clipper::offset(\@islands, $i * $flow->scaled_spacing, 100, JT_SQUARE)}; } } diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 48c0d402b8..b5a8e10da1 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -179,18 +179,17 @@ sub make_perimeters { if ($Slic3r::Config->extra_perimeters && $Slic3r::Config->perimeters > 0) { for my $region_id (0 .. ($self->print->regions_count-1)) { for my $layer_id (0 .. $self->layer_count-2) { - my $layerm = $self->layers->[$layer_id]->regions->[$region_id]; - my $upper_layerm = $self->layers->[$layer_id+1]->regions->[$region_id]; - my $perimeter_flow_spacing = $layerm->perimeter_flow->spacing; - my $scaled_perimeter_flow_spacing = scale $perimeter_flow_spacing; + my $layerm = $self->layers->[$layer_id]->regions->[$region_id]; + my $upper_layerm = $self->layers->[$layer_id+1]->regions->[$region_id]; + my $perimeter_flow = $layerm->perimeter_flow; - my $overlap = $perimeter_flow_spacing; # one perimeter + my $overlap = $perimeter_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 * $scaled_perimeter_flow_spacing), @{$upper_layerm->slices} ], - [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * $scaled_perimeter_flow_spacing)), @{$upper_layerm->slices} ], + [ map @$_, map $_->expolygon->offset_ex(+ 0.5 * $perimeter_flow->scaled_spacing), @{$upper_layerm->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- scale($overlap) + (0.5 * $perimeter_flow->scaled_spacing)), @{$upper_layerm->slices} ], ); next if !@$upper; @@ -199,10 +198,10 @@ sub make_perimeters { my $ignore = []; { my $diff = diff_ex( - [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::Config->perimeters-0.5) * $scaled_perimeter_flow_spacing), @{$layerm->slices} ], + [ map @$_, map $_->expolygon->offset_ex(- ($Slic3r::Config->perimeters-0.5) * $perimeter_flow->scaled_spacing), @{$layerm->slices} ], [ map @{$_->expolygon}, @{$upper_layerm->slices} ], ); - $ignore = [ map @$_, map $_->offset_ex($scaled_perimeter_flow_spacing), @$diff ]; + $ignore = [ map @$_, map $_->offset_ex($perimeter_flow->scaled_spacing), @$diff ]; } foreach my $slice (@{$layerm->slices}) { @@ -212,9 +211,9 @@ sub make_perimeters { # of our slice my $hypothetical_perimeter; { - my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * $scaled_perimeter_flow_spacing) ]; + my $outer = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-1.5) * $perimeter_flow->scaled_spacing) ]; last CYCLE if !@$outer; - my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * $scaled_perimeter_flow_spacing) ]; + my $inner = [ map @$_, $slice->expolygon->offset_ex(- ($hypothetical_perimeter_num-0.5) * $perimeter_flow->scaled_spacing) ]; last CYCLE if !@$inner; $hypothetical_perimeter = diff_ex($outer, $inner); } @@ -325,7 +324,7 @@ sub discover_horizontal_shells { Slic3r::debugf "==> DISCOVERING HORIZONTAL SHELLS\n"; - my $area_threshold = scale($Slic3r::flow->spacing) ** 2; + my $area_threshold = $Slic3r::flow->scaled_spacing ** 2; for my $region_id (0 .. ($self->print->regions_count-1)) { for (my $i = 0; $i < $self->layer_count; $i++) { @@ -333,7 +332,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::Config->perimeters * scale $layerm->perimeter_flow->width), + my @surfaces = map $_->offset($Slic3r::Config->perimeters * $layerm->perimeter_flow->scaled_width), grep $_->surface_type == $type, @{$layerm->fill_surfaces} or next; my $surfaces_p = [ map $_->p, @surfaces ]; Slic3r::debugf "Layer %d has %d surfaces of type '%s'\n", @@ -413,7 +412,7 @@ sub combine_infill { my $self = shift; return unless $Slic3r::Config->infill_every_layers > 1 && $Slic3r::Config->fill_density > 0; - my $area_threshold = scale($Slic3r::flow->spacing) ** 2; + my $area_threshold = $Slic3r::flow->scaled_spacing ** 2; for my $region_id (0 .. ($self->print->regions_count-1)) { # start from bottom, skip first layer @@ -505,7 +504,7 @@ sub generate_support_material { my $flow = $self->print->support_material_flow; my $threshold_rad = deg2rad($Slic3r::Config->support_material_threshold + 1); # +1 makes the threshold inclusive my $overhang_width = $threshold_rad == 0 ? undef : scale $Slic3r::Config->layer_height * ((cos $threshold_rad) / (sin $threshold_rad)); - my $distance_from_object = 1.5 * scale $flow->width; + my $distance_from_object = 1.5 * $flow->scaled_width; # determine support regions in each layer (for upper layers) Slic3r::debugf "Detecting regions\n"; @@ -529,7 +528,7 @@ sub generate_support_material { [ map @$_, @current_support_regions ], [ map @$_, map $_->offset_ex($distance_from_object), @{$layer->slices} ], ); - $_->simplify(scale $flow->spacing * 2) for @{$layers{$i}}; + $_->simplify($flow->scaled_spacing * 2) for @{$layers{$i}}; # step 2: get layer overhangs and put them into queue for adding support inside lower layers # we need an angle threshold for this @@ -551,7 +550,7 @@ sub generate_support_material { my $support_patterns = []; # in case we want cross-hatching { # 0.5 makes sure the paths don't get clipped externally when applying them to layers - my @support_material_areas = map $_->offset_ex(- 0.5 * scale $flow->width), + my @support_material_areas = map $_->offset_ex(- 0.5 * $flow->scaled_width), @{union_ex([ map $_->contour, map @$_, values %layers ])}; my $fill = Slic3r::Fill->new(print => $self->print);