New --spiral-vase option to continously raise Z when printing single-walled vases. #997

This commit is contained in:
Alessandro Ranellucci 2013-05-13 20:15:45 +02:00
parent baa1a8c736
commit ccdb29ddc9
8 changed files with 81 additions and 1 deletions

View File

@ -27,6 +27,7 @@ lib/Slic3r/GCode.pm
lib/Slic3r/GCode/CoolingBuffer.pm lib/Slic3r/GCode/CoolingBuffer.pm
lib/Slic3r/GCode/MotionPlanner.pm lib/Slic3r/GCode/MotionPlanner.pm
lib/Slic3r/GCode/Reader.pm lib/Slic3r/GCode/Reader.pm
lib/Slic3r/GCode/SpiralVase.pm
lib/Slic3r/Geometry.pm lib/Slic3r/Geometry.pm
lib/Slic3r/Geometry/Clipper.pm lib/Slic3r/Geometry/Clipper.pm
lib/Slic3r/GUI.pm lib/Slic3r/GUI.pm

View File

@ -198,6 +198,8 @@ The author of the Silk icon set is Mark James.
--randomize-start Randomize starting point across layers (default: yes) --randomize-start Randomize starting point across layers (default: yes)
--avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (default: no) --avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (default: no)
--external-perimeters-first Reverse perimeter order. (default: no) --external-perimeters-first Reverse perimeter order. (default: no)
--spiral-vase Experimental option to raise Z gradually when printing single-walled vases
(default: no)
--only-retract-when-crossing-perimeters --only-retract-when-crossing-perimeters
Disable retraction when travelling between infill paths inside the same island. Disable retraction when travelling between infill paths inside the same island.
(default: yes) (default: yes)

View File

@ -48,6 +48,7 @@ use Slic3r::GCode;
use Slic3r::GCode::CoolingBuffer; use Slic3r::GCode::CoolingBuffer;
use Slic3r::GCode::MotionPlanner; use Slic3r::GCode::MotionPlanner;
use Slic3r::GCode::Reader; use Slic3r::GCode::Reader;
use Slic3r::GCode::SpiralVase;
use Slic3r::Geometry qw(PI); use Slic3r::Geometry qw(PI);
use Slic3r::Layer; use Slic3r::Layer;
use Slic3r::Layer::Region; use Slic3r::Layer::Region;

View File

@ -586,6 +586,13 @@ our $Options = {
type => 'bool', type => 'bool',
default => 0, default => 0,
}, },
'spiral_vase' => {
label => 'Spiral vase',
tooltip => 'This experimental feature will raise Z gradually while printing a single-walled object in order to remove any visible seam. By enabling this option other settings will be overridden to enforce a single perimeter, no infill, no top solid layers, no support material. You can still set any number of bottom solid layers as well as skirt/brim loops. It won\'t work when printing more than an object.',
cli => 'spiral-vase!',
type => 'bool',
default => 0,
},
'only_retract_when_crossing_perimeters' => { 'only_retract_when_crossing_perimeters' => {
label => 'Only retract when crossing perimeters', label => 'Only retract when crossing perimeters',
tooltip => 'Disables retraction when travelling between infill paths inside the same island.', tooltip => 'Disables retraction when travelling between infill paths inside the same island.',

View File

@ -0,0 +1,40 @@
package Slic3r::GCode::SpiralVase;
use Moo;
use Slic3r::Geometry qw(unscale);
sub process_layer {
my $self = shift;
my ($gcode, $layer) = @_;
my $total_layer_length = 0;
Slic3r::GCode::Reader->new(gcode => $gcode)->parse(sub {
my ($reader, $cmd, $args, $info) = @_;
$total_layer_length += $info->{dist_XY}
if $cmd eq 'G1' && $info->{extruding};
});
my $new_gcode = "";
my $layer_height = $layer->height;
my $z = unscale($layer->print_z) - $layer_height;
Slic3r::GCode::Reader->new(gcode => $gcode)->parse(sub {
my ($reader, $cmd, $args, $info) = @_;
if ($cmd eq 'G1' && exists $args->{Z}) {
my $line = $info->{raw};
$line =~ s/Z([^ ]+)/Z$z/;
$new_gcode .= "$line\n";
} elsif ($cmd eq 'G1' && !exists $args->{Z} && $info->{extruding} && $info->{dist_XY}) {
$z += $info->{dist_XY} * $layer_height / $total_layer_length;
my $line = $info->{raw};
$line =~ s/^G1 /sprintf 'G1 Z%.3f ', $z/e;
$new_gcode .= "$line\n";
} else {
$new_gcode .= "$info->{raw}\n";
}
});
return $new_gcode;
}
1;

View File

@ -412,7 +412,7 @@ sub build {
}, },
{ {
title => 'Advanced', title => 'Advanced',
options => [qw(avoid_crossing_perimeters external_perimeters_first)], options => [qw(avoid_crossing_perimeters external_perimeters_first spiral_vase)],
}, },
]); ]);

View File

@ -63,6 +63,14 @@ sub _trigger_config {
# G-code flavors # G-code flavors
$self->config->set('extrusion_axis', 'A') if $self->config->gcode_flavor eq 'mach3'; $self->config->set('extrusion_axis', 'A') if $self->config->gcode_flavor eq 'mach3';
$self->config->set('extrusion_axis', '') if $self->config->gcode_flavor eq 'no-extrusion'; $self->config->set('extrusion_axis', '') if $self->config->gcode_flavor eq 'no-extrusion';
# enforce some settings when spiral_vase is set
if ($self->config->spiral_vase) {
$self->config->set('perimeters', 1);
$self->config->set('fill_density', 0);
$self->config->set('top_solid_layers', 0);
$self->config->set('support_material', 0);
}
} }
sub _build_has_support_material { sub _build_has_support_material {
@ -184,6 +192,12 @@ sub validate {
} }
} }
} }
if ($Slic3r::Config->spiral_vase) {
if ((map @{$_->copies}, @{$self->objects}) > 1) {
die "The Spiral Vase option can only be used when printing a single object.\n";
}
}
} }
sub init_extruders { sub init_extruders {
@ -794,6 +808,11 @@ sub write_gcode {
)); ));
} }
# prepare the SpiralVase processor if it's possible
my $spiralvase = $Slic3r::Config->spiral_vase
? Slic3r::GCode::SpiralVase->new
: undef;
# prepare the logic to print one layer # prepare the logic to print one layer
my $skirt_done = 0; # count of skirt layers done my $skirt_done = 0; # count of skirt layers done
my $brim_done = 0; my $brim_done = 0;
@ -956,6 +975,14 @@ sub write_gcode {
} }
} }
} }
# apply spiral vase post-processing if this layer contains suitable geometry
$gcode = $spiralvase->process_layer($gcode, $layer)
if defined $spiralvase
&& ($layer->id > 0 || $Slic3r::Config->brim_width == 0)
&& ($layer->id >= $Slic3r::Config->skirt_height)
&& ($layer->id >= $Slic3r::Config->bottom_solid_layers);
return $gcode; return $gcode;
}; };

View File

@ -251,6 +251,8 @@ $j
--randomize-start Randomize starting point across layers (default: yes) --randomize-start Randomize starting point across layers (default: yes)
--avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (default: no) --avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (default: no)
--external-perimeters-first Reverse perimeter order. (default: no) --external-perimeters-first Reverse perimeter order. (default: no)
--spiral-vase Experimental option to raise Z gradually when printing single-walled vases
(default: no)
--only-retract-when-crossing-perimeters --only-retract-when-crossing-perimeters
Disable retraction when travelling between infill paths inside the same island. Disable retraction when travelling between infill paths inside the same island.
(default: no) (default: no)