diff --git a/lib/Slic3r/ExtrusionLoop.pm b/lib/Slic3r/ExtrusionLoop.pm index 710beaa41..2c9cffa19 100644 --- a/lib/Slic3r/ExtrusionLoop.pm +++ b/lib/Slic3r/ExtrusionLoop.pm @@ -2,4 +2,11 @@ package Slic3r::ExtrusionLoop; use strict; use warnings; +use parent qw(Exporter); + +our @EXPORT_OK = qw(EXTRL_ROLE_DEFAULT EXTRL_ROLE_EXTERNAL_PERIMETER + EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER); +our %EXPORT_TAGS = (roles => \@EXPORT_OK); + + 1; diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm index a03ff487e..20c7930ed 100644 --- a/lib/Slic3r/ExtrusionPath.pm +++ b/lib/Slic3r/ExtrusionPath.pm @@ -4,10 +4,9 @@ use warnings; use parent qw(Exporter); -our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER - EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER EXTR_ROLE_OVERHANG_PERIMETER +our @EXPORT_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_EXTERNAL_PERIMETER EXTR_ROLE_OVERHANG_PERIMETER EXTR_ROLE_FILL EXTR_ROLE_SOLIDFILL EXTR_ROLE_TOPSOLIDFILL EXTR_ROLE_BRIDGE - EXTR_ROLE_INTERNALBRIDGE EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_GAPFILL); + EXTR_ROLE_SKIRT EXTR_ROLE_SUPPORTMATERIAL EXTR_ROLE_GAPFILL); our %EXPORT_TAGS = (roles => \@EXPORT_OK); 1; diff --git a/lib/Slic3r/Fill.pm b/lib/Slic3r/Fill.pm index 678e71f9a..6d1fae502 100644 --- a/lib/Slic3r/Fill.pm +++ b/lib/Slic3r/Fill.pm @@ -230,9 +230,7 @@ sub make_fill { $collection->append( map Slic3r::ExtrusionPath->new( polyline => $_, - role => ($surface->surface_type == S_TYPE_INTERNALBRIDGE - ? EXTR_ROLE_INTERNALBRIDGE - : $is_bridge + role => ($is_bridge ? EXTR_ROLE_BRIDGE : $is_solid ? (($surface->surface_type == S_TYPE_TOP) ? EXTR_ROLE_TOPSOLIDFILL : EXTR_ROLE_SOLIDFILL) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index 907a0048a..6e9ed68b0 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -2,6 +2,7 @@ package Slic3r::GCode; use Moo; use List::Util qw(min max first); +use Slic3r::ExtrusionLoop ':roles'; use Slic3r::ExtrusionPath ':roles'; use Slic3r::Flow ':roles'; use Slic3r::Geometry qw(epsilon scale unscale scaled_epsilon points_coincide PI X Y B); @@ -76,12 +77,10 @@ my %role_speeds = ( &EXTR_ROLE_PERIMETER => 'perimeter', &EXTR_ROLE_EXTERNAL_PERIMETER => 'external_perimeter', &EXTR_ROLE_OVERHANG_PERIMETER => 'bridge', - &EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER => 'perimeter', &EXTR_ROLE_FILL => 'infill', &EXTR_ROLE_SOLIDFILL => 'solid_infill', &EXTR_ROLE_TOPSOLIDFILL => 'top_solid_infill', &EXTR_ROLE_BRIDGE => 'bridge', - &EXTR_ROLE_INTERNALBRIDGE => 'bridge', &EXTR_ROLE_SKIRT => 'perimeter', &EXTR_ROLE_GAPFILL => 'gap_fill', ); @@ -217,7 +216,7 @@ sub extrude_loop { # find the point of the loop that is closest to the current extruder position # or randomize if requested my $last_pos = $self->last_pos; - if ($self->print_config->randomize_start && $loop->role == EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER) { + if ($self->print_config->randomize_start && $loop->role == EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER) { $last_pos = Slic3r::Point->new(scale $self->print_config->print_center->[X], scale $self->print_config->bed_size->[Y]); $last_pos->rotate(rand(2*PI), $self->print_config->print_center); } diff --git a/lib/Slic3r/Layer/Region.pm b/lib/Slic3r/Layer/Region.pm index 184f7bab6..8f77ec2d0 100644 --- a/lib/Slic3r/Layer/Region.pm +++ b/lib/Slic3r/Layer/Region.pm @@ -2,6 +2,7 @@ package Slic3r::Layer::Region; use Moo; use List::Util qw(sum first); +use Slic3r::ExtrusionLoop ':roles'; use Slic3r::ExtrusionPath ':roles'; use Slic3r::Flow ':roles'; use Slic3r::Geometry qw(PI A B scale unscale chained_path points_coincide); @@ -257,13 +258,15 @@ sub make_perimeters { foreach my $polynode (@$polynodes) { my $polygon = ($polynode->{outer} // $polynode->{hole})->clone; - my $role = EXTR_ROLE_PERIMETER; + my $role = EXTR_ROLE_PERIMETER; + my $loop_role = EXTRL_ROLE_DEFAULT; if ($is_contour ? $depth == 0 : !@{ $polynode->{children} }) { # external perimeters are root level in case of contours # and items with no children in case of holes - $role = EXTR_ROLE_EXTERNAL_PERIMETER; + $role = EXTR_ROLE_EXTERNAL_PERIMETER; + $loop_role = EXTRL_ROLE_EXTERNAL_PERIMETER; } elsif ($depth == 1 && $is_contour) { - $role = EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER; + $loop_role = EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER; } # detect overhanging/bridging perimeters @@ -309,6 +312,7 @@ sub make_perimeters { ); } my $loop = Slic3r::ExtrusionLoop->new_from_paths(@paths); + $loop->role($loop_role); # return ccw contours and cw holes # GCode.pm will convert all of them to ccw, but it needs to know diff --git a/t/perimeters.t b/t/perimeters.t index b12b8f938..58ebc3ed1 100644 --- a/t/perimeters.t +++ b/t/perimeters.t @@ -1,4 +1,4 @@ -use Test::More tests => 9; +use Test::More tests => 10; use strict; use warnings; @@ -265,4 +265,11 @@ use Slic3r::Test; 'overhangs printed with bridge speed'; } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('randomize_start', 1); + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + ok Slic3r::Test::gcode($print), 'successful generation of G-code with randomize_start option'; +} + __END__ diff --git a/xs/src/ExtrusionEntity.cpp b/xs/src/ExtrusionEntity.cpp index 5b15ee02e..0abab7510 100644 --- a/xs/src/ExtrusionEntity.cpp +++ b/xs/src/ExtrusionEntity.cpp @@ -72,23 +72,21 @@ ExtrusionPath::is_perimeter() const { return this->role == erPerimeter || this->role == erExternalPerimeter - || this->role == erOverhangPerimeter - || this->role == erContourInternalPerimeter; + || this->role == erOverhangPerimeter; } bool ExtrusionPath::is_fill() const { - return this->role == erFill - || this->role == erSolidFill - || this->role == erTopSolidFill; + return this->role == erInternalInfill + || this->role == erSolidInfill + || this->role == erTopSolidInfill; } bool ExtrusionPath::is_bridge() const { - return this->role == erBridge - || this->role == erInternalBridge + return this->role == erBridgeInfill || this->role == erOverhangPerimeter; } diff --git a/xs/src/ExtrusionEntity.hpp b/xs/src/ExtrusionEntity.hpp index 8504aa0ed..40e939d0e 100644 --- a/xs/src/ExtrusionEntity.hpp +++ b/xs/src/ExtrusionEntity.hpp @@ -11,19 +11,25 @@ class ExPolygonCollection; class ExtrusionEntityCollection; class Extruder; +/* Each ExtrusionRole value identifies a distinct set of { extruder, speed } */ enum ExtrusionRole { erPerimeter, erExternalPerimeter, erOverhangPerimeter, - erContourInternalPerimeter, - erFill, - erSolidFill, - erTopSolidFill, - erBridge, - erInternalBridge, + erInternalInfill, + erSolidInfill, + erTopSolidInfill, + erBridgeInfill, + erGapFill, erSkirt, erSupportMaterial, - erGapFill, +}; + +/* Special flags describing loop */ +enum ExtrusionLoopRole { + elrDefault, + elrExternalPerimeter, + elrContourInternalPerimeter, }; class ExtrusionEntity @@ -47,7 +53,7 @@ class ExtrusionPath : public ExtrusionEntity float width; float height; - ExtrusionPath() : mm3_per_mm(-1), width(-1), height(-1) {}; + ExtrusionPath(ExtrusionRole role) : role(role), mm3_per_mm(-1), width(-1), height(-1) {}; ExtrusionPath* clone() const; void reverse(); Point first_point() const; @@ -74,7 +80,9 @@ class ExtrusionLoop : public ExtrusionEntity { public: ExtrusionPaths paths; + ExtrusionLoopRole role; + ExtrusionLoop(ExtrusionLoopRole role = elrDefault) : role(role) {}; operator Polygon() const; ExtrusionLoop* clone() const; bool make_clockwise(); diff --git a/xs/xsp/ExtrusionLoop.xsp b/xs/xsp/ExtrusionLoop.xsp index 731c7ef59..3ab469bc5 100644 --- a/xs/xsp/ExtrusionLoop.xsp +++ b/xs/xsp/ExtrusionLoop.xsp @@ -41,5 +41,31 @@ ExtrusionLoop::arrayref() OUTPUT: RETVAL +ExtrusionLoopRole +ExtrusionLoop::role(...) + CODE: + if (items > 1) { + THIS->role = (ExtrusionLoopRole)SvUV(ST(1)); + } + RETVAL = THIS->role; + OUTPUT: + RETVAL + %} }; + +%package{Slic3r::ExtrusionLoop}; +%{ + +IV +_constant() + ALIAS: + EXTRL_ROLE_DEFAULT = elrDefault + EXTRL_ROLE_EXTERNAL_PERIMETER = elrExternalPerimeter + EXTRL_ROLE_CONTOUR_INTERNAL_PERIMETER = erInternalInfill + PROTOTYPE: + CODE: + RETVAL = ix; + OUTPUT: RETVAL + +%} diff --git a/xs/xsp/ExtrusionPath.xsp b/xs/xsp/ExtrusionPath.xsp index 1b2782258..c465cc041 100644 --- a/xs/xsp/ExtrusionPath.xsp +++ b/xs/xsp/ExtrusionPath.xsp @@ -39,9 +39,8 @@ _new(CLASS, polyline_sv, role, mm3_per_mm, width, height) float width; float height; CODE: - RETVAL = new ExtrusionPath (); + RETVAL = new ExtrusionPath (role); RETVAL->polyline.from_SV_check(polyline_sv); - RETVAL->role = role; RETVAL->mm3_per_mm = mm3_per_mm; RETVAL->width = width; RETVAL->height = height; @@ -135,15 +134,13 @@ _constant() EXTR_ROLE_PERIMETER = erPerimeter EXTR_ROLE_EXTERNAL_PERIMETER = erExternalPerimeter EXTR_ROLE_OVERHANG_PERIMETER = erOverhangPerimeter - EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER = erContourInternalPerimeter - EXTR_ROLE_FILL = erFill - EXTR_ROLE_SOLIDFILL = erSolidFill - EXTR_ROLE_TOPSOLIDFILL = erTopSolidFill - EXTR_ROLE_BRIDGE = erBridge - EXTR_ROLE_INTERNALBRIDGE = erInternalBridge + EXTR_ROLE_FILL = erInternalInfill + EXTR_ROLE_SOLIDFILL = erSolidInfill + EXTR_ROLE_TOPSOLIDFILL = erTopSolidInfill + EXTR_ROLE_BRIDGE = erBridgeInfill + EXTR_ROLE_GAPFILL = erGapFill EXTR_ROLE_SKIRT = erSkirt EXTR_ROLE_SUPPORTMATERIAL = erSupportMaterial - EXTR_ROLE_GAPFILL = erGapFill PROTOTYPE: CODE: RETVAL = ix; diff --git a/xs/xsp/my.map b/xs/xsp/my.map index b122d95d7..b0aed2e49 100644 --- a/xs/xsp/my.map +++ b/xs/xsp/my.map @@ -111,6 +111,7 @@ Ref O_OBJECT_SLIC3R_T Clone O_OBJECT_SLIC3R_T +ExtrusionLoopRole T_UV ExtrusionRole T_UV FlowRole T_UV PrintStep T_UV diff --git a/xs/xsp/typemap.xspt b/xs/xsp/typemap.xspt index 945b104bf..7cf7c8458 100644 --- a/xs/xsp/typemap.xspt +++ b/xs/xsp/typemap.xspt @@ -112,6 +112,12 @@ $CVar = (SurfaceType)SvUV($PerlVar); %}; }; +%typemap{ExtrusionLoopRole}{parsed}{ + %cpp_type{ExtrusionLoopRole}; + %precall_code{% + $CVar = (ExtrusionLoopRole)SvUV($PerlVar); + %}; +}; %typemap{ExtrusionRole}{parsed}{ %cpp_type{ExtrusionRole}; %precall_code{%