diff --git a/README.markdown b/README.markdown index 8e25787b7..0f462301d 100644 --- a/README.markdown +++ b/README.markdown @@ -161,6 +161,7 @@ The author is Alessandro Ranellucci (me). home X axis [G28 X], disable motors [M84]). --layer-gcode Load layer-change G-code from the supplied file (default: nothing). --support-material Generate support material for overhangs + --randomize-start Randomize starting point across layers (default: yes) Retraction options: --retract-length Length of retraction in mm when pausing extrusion diff --git a/lib/Slic3r.pm b/lib/Slic3r.pm index f2ce94c37..bef33e02b 100644 --- a/lib/Slic3r.pm +++ b/lib/Slic3r.pm @@ -105,6 +105,7 @@ our $fill_pattern = 'rectilinear'; our $solid_fill_pattern = 'rectilinear'; our $fill_density = 0.4; # 1 = 100% our $fill_angle = 45; +our $randomize_start = 1; our $support_material = 0; our $support_material_tool = 0; our $start_gcode = "G28 ; home all axes"; diff --git a/lib/Slic3r/Config.pm b/lib/Slic3r/Config.pm index d21b02bc5..0c996890d 100644 --- a/lib/Slic3r/Config.pm +++ b/lib/Slic3r/Config.pm @@ -245,6 +245,11 @@ our $Options = { cli => 'fill-angle=i', type => 'i', }, + 'randomize_start' => { + label => 'Randomize starting points', + cli => 'randomize-start', + type => 'bool', + }, 'support_material' => { label => 'Generate support material', cli => 'support-material', diff --git a/lib/Slic3r/Extruder.pm b/lib/Slic3r/Extruder.pm index d771eaf27..99d895ae9 100644 --- a/lib/Slic3r/Extruder.pm +++ b/lib/Slic3r/Extruder.pm @@ -35,13 +35,14 @@ 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', + &EXTR_ROLE_PERIMETER => 'perimeter', + &EXTR_ROLE_SMALLPERIMETER => 'small_perimeter', + &EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER => '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); @@ -85,7 +86,14 @@ sub extrude_loop { $loop->polygon->make_counter_clockwise; # find the point of the loop that is closest to the current extruder position - my $start_at = $loop->nearest_point_to($self->last_pos); + # or randomize if requested + my $last_pos = $self->last_pos; + if ($Slic3r::randomize_start && $loop->role == EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER) { + srand $self->layer->id * 10; + $last_pos = Slic3r::Point->new(scale $Slic3r::print_center->[X], scale $Slic3r::bed_size->[Y]); + $last_pos->rotate(rand(2*PI), $Slic3r::print_center); + } + my $start_at = $loop->nearest_point_to($last_pos); # split the loop at the starting point and make a path my $extrusion_path = $loop->split_at($start_at); diff --git a/lib/Slic3r/ExtrusionPath.pm b/lib/Slic3r/ExtrusionPath.pm index 756594d2a..56e2c349e 100644 --- a/lib/Slic3r/ExtrusionPath.pm +++ b/lib/Slic3r/ExtrusionPath.pm @@ -3,8 +3,8 @@ 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_OK = qw(EXTR_ROLE_PERIMETER EXTR_ROLE_SMALLPERIMETER EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER + 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); @@ -23,13 +23,14 @@ has 'depth_layers' => (is => 'ro', default => sub {1}); has 'flow_spacing' => (is => 'rw'); 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; +use constant EXTR_ROLE_PERIMETER => 0; +use constant EXTR_ROLE_SMALLPERIMETER => 1; +use constant EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER => 2; +use constant EXTR_ROLE_FILL => 3; +use constant EXTR_ROLE_SOLIDFILL => 4; +use constant EXTR_ROLE_BRIDGE => 5; +use constant EXTR_ROLE_SKIRT => 6; +use constant EXTR_ROLE_SUPPORTMATERIAL => 7; sub BUILD { my $self = shift; diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index 919fcc63b..9e302f87f 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -44,7 +44,7 @@ sub new { }, print => { title => 'Print settings', - options => [qw(perimeters solid_layers fill_density fill_angle fill_pattern solid_fill_pattern support_material support_material_tool)], + options => [qw(perimeters solid_layers fill_density fill_angle fill_pattern solid_fill_pattern randomize_start support_material support_material_tool)], }, retract => { title => 'Retraction', diff --git a/lib/Slic3r/Layer.pm b/lib/Slic3r/Layer.pm index d4cd4a3c3..e915f8296 100644 --- a/lib/Slic3r/Layer.pm +++ b/lib/Slic3r/Layer.pm @@ -285,12 +285,10 @@ sub make_perimeters { } # do holes, then contours starting from innermost one - foreach my $polygon ((reverse @holes), (map $_->contour, map @$_, reverse @$island)) { - next unless $polygon->is_printable; - push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new( - polygon => $polygon, - role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : EXTR_ROLE_PERIMETER, - ); + $self->add_perimeter($_) for reverse @holes; + for my $depth (reverse 0 .. $#$island) { + my $role = $depth == $#$island ? EXTR_ROLE_CONTOUR_INTERNAL_PERIMETER : EXTR_ROLE_PERIMETER; + $self->add_perimeter($_, $role) for map $_->contour, @{$island->[$depth]}; } } @@ -304,6 +302,17 @@ sub make_perimeters { } } +sub add_perimeter { + my $self = shift; + my ($polygon, $role) = @_; + + return unless $polygon->is_printable; + push @{ $self->perimeters }, Slic3r::ExtrusionLoop->new( + polygon => $polygon, + role => (abs($polygon->length) <= $Slic3r::small_perimeter_length) ? EXTR_ROLE_SMALLPERIMETER : ($role // EXTR_ROLE_PERIMETER), #/ + ); +} + sub prepare_fill_surfaces { my $self = shift; diff --git a/slic3r.pl b/slic3r.pl index 61af30ff8..883cb0e68 100755 --- a/slic3r.pl +++ b/slic3r.pl @@ -197,6 +197,7 @@ $j home X axis [G28 X], disable motors [M84]). --layer-gcode Load layer-change G-code from the supplied file (default: nothing). --support-material Generate support material for overhangs + --randomize-start Randomize starting point across layers (default: yes) Retraction options: --retract-length Length of retraction in mm when pausing extrusion