diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index fe20f50df..afacbd4f3 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -1,6 +1,7 @@ package Slic3r::Extruder; use Moo; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(scale unscale); has 'layer' => (is => 'rw'); @@ -33,6 +34,16 @@ has 'speeds' => ( }}, ); +my %role_speeds = ( + &EXTR_ROLE_PERIMETER => 'perimeter', + &EXTR_ROLE_SMALLPERIMETER => 'small_perimeter', + &EXTR_ROLE_FILL => 'infill', + &EXTR_ROLE_SOLIDFILL => 'solid_infill', + &EXTR_ROLE_BRIDGE => 'bridge', + &EXTR_ROLE_SKIRT => 'perimeter', + &EXTR_ROLE_SUPPORTMATERIAL => 'perimeter', +); + use Slic3r::Geometry qw(points_coincide PI X Y); sub change_layer { @@ -126,7 +137,7 @@ sub extrude_path { my $w = ($s - $Slic3r::min_flow_spacing * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor); my $area; - if ($path->role eq 'bridge') { + if ($path->role == EXTR_ROLE_BRIDGE) { $area = ($s**2) * PI/4; } elsif ($w >= ($Slic3r::nozzle_diameter + $h)) { # rectangle with semicircles at the ends @@ -142,14 +153,7 @@ sub extrude_path { * (4 / (($Slic3r::filament_diameter ** 2) * PI)); # extrude arc or line - $self->speed( - $path->role =~ /^(perimeter|skirt|support-material)$/o ? 'perimeter' - : $path->role eq 'small-perimeter' ? 'small_perimeter' - : $path->role eq 'fill' ? 'infill' - : $path->role eq 'solid-fill' ? 'solid_infill' - : $path->role eq 'bridge' ? 'bridge' - : die "Unknown role: " . $path->role - ); + $self->speed( $role_speeds{$path->role} || die "Unknown role: " . $path->role ); my $path_length = 0; if ($path->isa('Slic3r::ExtrusionPath::Arc')) { $path_length = $path->length; diff --git a/lib/Slic3r/ExtrusionLoop.pm b/lib/Slic3r/ExtrusionLoop.pm index 1c4c327bb..5f00906cc 100644 --- a/lib/Slic3r/ExtrusionLoop.pm +++ b/lib/Slic3r/ExtrusionLoop.pm @@ -1,7 +1,6 @@ package Slic3r::ExtrusionLoop; use Moo; - # the underlying Slic3r::Polygon objects holds the geometry has 'polygon' => ( is => 'ro', @@ -9,7 +8,7 @@ has 'polygon' => ( handles => [qw(is_printable nearest_point_to)], ); -# perimeter/fill/solid-fill/bridge/skirt +# see EXTR_ROLE_* constants in ExtrusionPath.pm has 'role' => (is => 'rw', required => 1); sub BUILD { diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm index 6927cc0b0..67bdf3577 100644 --- a/lib/Slic3r/ExtrusionPath.pm +++ b/lib/Slic3r/ExtrusionPath.pm @@ -1,6 +1,13 @@ package Slic3r::ExtrusionPath; use Moo; +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_SMALLPERIMETER EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL + EXTR_ROLE_BRIDGE EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL); +our %EXPORT_TAGS = (roles => \@EXPORT_OK); + + use Slic3r::Geometry qw(PI X Y epsilon deg2rad rotate_points); # the underlying Slic3r::Polyline objects holds the geometry @@ -16,8 +23,14 @@ has 'depth_layers' => (is => 'ro', default => sub {1}); has 'flow_spacing' => (is => 'rw'); -# perimeter/fill/solid-fill/bridge/skirt/support-material has 'role' => (is => 'rw', required => 1); +use constant EXTR_ROLE_PERIMETER => 0; +use constant EXTR_ROLE_SMALLPERIMETER => 1; +use constant EXTR_ROLE_FILL => 2; +use constant EXTR_ROLE_SOLIDFILL => 3; +use constant EXTR_ROLE_BRIDGE => 4; +use constant EXTR_ROLE_SKIRT => 5; +use constant EXTR_ROLE_SUPPORTMATERIAL => 6; sub BUILD { my $self = shift; diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 1842d4f6d..6a892277b 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -11,6 +11,7 @@ use Slic3r::Fill::Line; use Slic3r::Fill::OctagramSpiral; use Slic3r::Fill::PlanePath; use Slic3r::Fill::Rectilinear; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(X Y scale shortest_path); use Slic3r::Geometry::Clipper qw(union_ex diff_ex); @@ -165,7 +166,9 @@ sub make_fill { paths => [ map Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@$_), - role => ($is_bridge ? 'bridge' : $is_solid ? 'solid-fill' : 'fill'), + role => ($is_bridge ? EXTR_ROLE_BRIDGE + : $is_solid ? EXTR_ROLE_SOLIDFILL + : EXTR_ROLE_FILL), depth_layers => $surface->depth_layers, flow_spacing => $params->{flow_spacing}, ), @paths, @@ -178,8 +181,8 @@ sub make_fill { paths => [ map { $_->isa('Slic3r::Polygon') - ? Slic3r::ExtrusionLoop->new(polygon => $_, role => 'solid-fill')->split_at($_->[0]) - : Slic3r::ExtrusionPath->new(polyline => $_, role => 'solid-fill') + ? Slic3r::ExtrusionLoop->new(polygon => $_, role => EXTR_ROLE_SOLIDFILL)->split_at($_->[0]) + : Slic3r::ExtrusionPath->new(polyline => $_, role => EXTR_ROLE_SOLIDFILL) } @{$layer->thin_fills}, ], ) if @{$layer->thin_fills}; diff --git a/lib/Slic3r/Fill/Concentric.pm b/lib/Slic3r/Fill/Concentric.pm index 5c97490d0..b3d4fbedf 100644 --- a/lib/Slic3r/Fill/Concentric.pm +++ b/lib/Slic3r/Fill/Concentric.pm @@ -3,6 +3,7 @@ use Moo; extends 'Slic3r::Fill::Base'; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(scale unscale X1 Y1 X2 Y2); sub fill_surface { @@ -50,7 +51,7 @@ sub fill_surface { ($bounding_box->[X1] + $bounding_box->[X2]) / 2, ($bounding_box->[Y1] + $bounding_box->[Y2]) / 2, ); - foreach my $loop (map Slic3r::ExtrusionLoop->new(polygon => $_, role => 'fill'), @loops) { + foreach my $loop (map Slic3r::ExtrusionLoop->new(polygon => $_, role => EXTR_ROLE_FILL), @loops) { # extrude all loops ccw $loop->polygon->make_counter_clockwise; diff --git a/lib/Slic3r/Fill/Rectilinear.pm b/lib/Slic3r/Fill/Rectilinear.pm index af1508c52..ad6a82e45 100644 --- a/lib/Slic3r/Fill/Rectilinear.pm +++ b/lib/Slic3r/Fill/Rectilinear.pm @@ -57,7 +57,7 @@ sub fill_surface { # connect lines { my $collection = Slic3r::ExtrusionPath::Collection->new( - paths => [ map Slic3r::ExtrusionPath->new(polyline => Slic3r::Polyline->new(@$_), role => 'bogus'), @paths ], + paths => [ map Slic3r::ExtrusionPath->new(polyline => Slic3r::Polyline->new(@$_), role => -1), @paths ], ); @paths = (); diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index 6002b5e73..2e0b48ec8 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -2,6 +2,7 @@ package Slic3r::Layer; use Moo; use Math::Clipper ':all'; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(scale unscale collinear X Y A B PI rad2deg_dir bounding_box_center shortest_path); use Slic3r::Geometry::Clipper qw(union_ex diff_ex intersection_ex xor_ex is_counter_clockwise); @@ -283,26 +284,26 @@ sub make_perimeters { } foreach my $hole (reverse @holes) { - push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $hole, role => 'perimeter'); + push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $hole, role => EXTR_ROLE_PERIMETER); } # do contours starting from innermost one foreach my $contour (map $_->contour, map @$_, reverse @$island) { - push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $contour, role => 'perimeter'); + push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $contour, role => EXTR_ROLE_PERIMETER); } } # detect small perimeters by checking their area for (@{ $self->perimeters }) { - $_->role('small-perimeter') if abs($_->polygon->length) <= $Slic3r::small_perimeter_length; + $_->role(EXTR_ROLE_SMALLPERIMETER) if abs($_->polygon->length) <= $Slic3r::small_perimeter_length; } # add thin walls as perimeters for (@{ $self->thin_walls }) { if ($_->isa('Slic3r::Polygon')) { - push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $_, role => 'perimeter'); + push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new(polygon => $_, role => EXTR_ROLE_PERIMETER); } else { - push @{ $self->perimeters }, Slic3r::ExtrusionPath->new(polyline => $_, role => 'perimeter'); + push @{ $self->perimeters }, Slic3r::ExtrusionPath->new(polyline => $_, role => EXTR_ROLE_PERIMETER); } } } diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 2a1aad22f..c064ee68b 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -3,6 +3,7 @@ use Moo; use File::Basename qw(basename fileparse); use Math::ConvexHull 1.0.4 qw(convex_hull); +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 PI scale unscale move_points); use Slic3r::Geometry::Clipper qw(diff_ex union_ex offset JT_ROUND); use Time::HiRes qw(gettimeofday tv_interval); @@ -369,7 +370,7 @@ sub make_skirt { my $outline = offset([$convex_hull], $distance, $Slic3r::scaling_factor * 100, JT_ROUND); push @skirt, Slic3r::ExtrusionLoop->new( polygon => Slic3r::Polygon->new(@{$outline->[0]}), - role => 'skirt', + role => EXTR_ROLE_SKIRT, ); } push @{$self->skirt}, @skirt; diff --git a/lib/Slic3r/Print/Object.pm b/lib/Slic3r/Print/Object.pm index 5e403f8fd..60d91143a 100644 --- a/lib/Slic3r/Print/Object.pm +++ b/lib/Slic3r/Print/Object.pm @@ -1,6 +1,7 @@ package Slic3r::Print::Object; use Moo; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(scale unscale); use Slic3r::Geometry::Clipper qw(diff_ex intersection_ex union_ex); @@ -542,7 +543,7 @@ sub generate_support_material { push @patterns, map Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(@$_), - role => 'support-material', + role => EXTR_ROLE_SUPPORTMATERIAL, depth_layers => 1, flow_spacing => $params->{flow_spacing}, ), @paths; diff --git a/t/arcs.t b/t/arcs.t index 2589e908f..b63c2660e 100644 --- a/t/arcs.t +++ b/t/arcs.t @@ -10,6 +10,7 @@ BEGIN { } use Slic3r; +use Slic3r::ExtrusionPath ':roles'; use Slic3r::Geometry qw(epsilon); { @@ -19,7 +20,7 @@ use Slic3r::Geometry qw(epsilon); [306517.1,219034.23], [286979.42,248012.49], [258001.16,267550.17], [222515.14,274714.47], [187029.11,267550.17], [158050.85,248012.49], [138513.17,219034.23], [131348.87,183548.2], [86948.77,175149.09], [119825.35,100585], - ), role => 'fill'); + ), role => EXTR_ROLE_FILL); my $collection = Slic3r::ExtrusionPath::Collection->new(paths => [$path]); $collection->detect_arcs(30); @@ -37,10 +38,10 @@ use Slic3r::Geometry qw(epsilon); [13.8268343236509,19.2387953251129], [14.5399049973955,18.9100652418837], [15.2249856471595,18.5264016435409], [15.8778525229247,18.0901699437495], [16.4944804833018,17.6040596560003], - ), role => 'fill'); + ), role => EXTR_ROLE_FILL); my $path2 = Slic3r::ExtrusionPath->new( polyline => Slic3r::Polyline->new(reverse @{$path1->points}), - role => 'fill', + role => EXTR_ROLE_FILL, ); my $collection1 = Slic3r::ExtrusionPath::Collection->new(paths => [$path1]);