New --spiral-vase option to continously raise Z when printing single-walled vases. #997
This commit is contained in:
parent
baa1a8c736
commit
ccdb29ddc9
1
MANIFEST
1
MANIFEST
@ -27,6 +27,7 @@ lib/Slic3r/GCode.pm
|
||||
lib/Slic3r/GCode/CoolingBuffer.pm
|
||||
lib/Slic3r/GCode/MotionPlanner.pm
|
||||
lib/Slic3r/GCode/Reader.pm
|
||||
lib/Slic3r/GCode/SpiralVase.pm
|
||||
lib/Slic3r/Geometry.pm
|
||||
lib/Slic3r/Geometry/Clipper.pm
|
||||
lib/Slic3r/GUI.pm
|
||||
|
@ -198,6 +198,8 @@ The author of the Silk icon set is Mark James.
|
||||
--randomize-start Randomize starting point across layers (default: yes)
|
||||
--avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (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
|
||||
Disable retraction when travelling between infill paths inside the same island.
|
||||
(default: yes)
|
||||
|
@ -48,6 +48,7 @@ use Slic3r::GCode;
|
||||
use Slic3r::GCode::CoolingBuffer;
|
||||
use Slic3r::GCode::MotionPlanner;
|
||||
use Slic3r::GCode::Reader;
|
||||
use Slic3r::GCode::SpiralVase;
|
||||
use Slic3r::Geometry qw(PI);
|
||||
use Slic3r::Layer;
|
||||
use Slic3r::Layer::Region;
|
||||
|
@ -586,6 +586,13 @@ our $Options = {
|
||||
type => 'bool',
|
||||
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' => {
|
||||
label => 'Only retract when crossing perimeters',
|
||||
tooltip => 'Disables retraction when travelling between infill paths inside the same island.',
|
||||
|
40
lib/Slic3r/GCode/SpiralVase.pm
Normal file
40
lib/Slic3r/GCode/SpiralVase.pm
Normal 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;
|
@ -412,7 +412,7 @@ sub build {
|
||||
},
|
||||
{
|
||||
title => 'Advanced',
|
||||
options => [qw(avoid_crossing_perimeters external_perimeters_first)],
|
||||
options => [qw(avoid_crossing_perimeters external_perimeters_first spiral_vase)],
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -63,6 +63,14 @@ sub _trigger_config {
|
||||
# G-code flavors
|
||||
$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';
|
||||
|
||||
# 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 {
|
||||
@ -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 {
|
||||
@ -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
|
||||
my $skirt_done = 0; # count of skirt layers done
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -251,6 +251,8 @@ $j
|
||||
--randomize-start Randomize starting point across layers (default: yes)
|
||||
--avoid-crossing-perimeters Optimize travel moves so that no perimeters are crossed (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
|
||||
Disable retraction when travelling between infill paths inside the same island.
|
||||
(default: no)
|
||||
|
Loading…
Reference in New Issue
Block a user