New wipe feature

This commit is contained in:
Alessandro Ranellucci 2013-03-17 02:22:50 +01:00
parent 83065b0789
commit 7de8b20bc4
7 changed files with 71 additions and 6 deletions

View File

@ -239,6 +239,7 @@ The author of the Silk icon set is Mark James.
--retract-lift Lift Z by the given distance in mm when retracting (default: 0) --retract-lift Lift Z by the given distance in mm when retracting (default: 0)
--retract-layer-change --retract-layer-change
Enforce a retraction before each Z move (default: yes) Enforce a retraction before each Z move (default: yes)
--wipe Wipe the nozzle while doing a retraction (default: no)
Retraction options for multi-extruder setups: Retraction options for multi-extruder setups:
--retract-length-toolchange --retract-length-toolchange

View File

@ -794,6 +794,15 @@ END
deserialize => $deserialize_comma, deserialize => $deserialize_comma,
default => [1], default => [1],
}, },
'wipe' => {
label => 'Wipe before retract',
tooltip => 'This flag will move the nozzle while retracting to minimize the possible blob on leaky extruders.',
cli => 'wipe!',
type => 'bool',
serialize => $serialize_comma,
deserialize => $deserialize_comma,
default => [0],
},
'retract_length_toolchange' => { 'retract_length_toolchange' => {
label => 'Length', label => 'Length',
tooltip => 'When retraction is triggered before changing tool, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder).', tooltip => 'When retraction is triggered before changing tool, filament is pulled back by the specified amount (the length is measured on raw filament, before it enters the extruder).',
@ -1065,7 +1074,7 @@ sub new_from_cli {
} }
$args{$_} = $Options->{$_}{deserialize}->($args{$_}) $args{$_} = $Options->{$_}{deserialize}->($args{$_})
for grep exists $args{$_}, qw(print_center bed_size duplicate_grid extruder_offset retract_layer_change); for grep exists $args{$_}, qw(print_center bed_size duplicate_grid extruder_offset retract_layer_change wipe);
return $class->new(%args); return $class->new(%args);
} }

View File

@ -1,13 +1,13 @@
package Slic3r::Extruder; package Slic3r::Extruder;
use Moo; use Moo;
use Slic3r::Geometry qw(PI); use Slic3r::Geometry qw(PI scale);
use constant OPTIONS => [qw( use constant OPTIONS => [qw(
extruder_offset extruder_offset
nozzle_diameter filament_diameter extrusion_multiplier temperature first_layer_temperature nozzle_diameter filament_diameter extrusion_multiplier temperature first_layer_temperature
retract_length retract_lift retract_speed retract_restart_extra retract_before_travel retract_length retract_lift retract_speed retract_restart_extra retract_before_travel
retract_layer_change retract_length_toolchange retract_restart_extra_toolchange retract_layer_change retract_length_toolchange retract_restart_extra_toolchange wipe
)]; )];
has 'id' => (is => 'rw', required => 1); has 'id' => (is => 'rw', required => 1);
@ -18,6 +18,7 @@ has 'retracted' => (is => 'rw', default => sub {0} );
has 'restart_extra' => (is => 'rw', default => sub {0} ); has 'restart_extra' => (is => 'rw', default => sub {0} );
has 'e_per_mm3' => (is => 'lazy'); has 'e_per_mm3' => (is => 'lazy');
has 'retract_speed_mm_min' => (is => 'lazy'); has 'retract_speed_mm_min' => (is => 'lazy');
has 'scaled_wipe_distance' => (is => 'lazy'); # scaled mm
has '_mm3_per_mm_cache' => (is => 'ro', default => sub {{}}); has '_mm3_per_mm_cache' => (is => 'ro', default => sub {{}});
sub _build_bridge_flow { sub _build_bridge_flow {
@ -35,6 +36,11 @@ sub _build_retract_speed_mm_min {
return $self->retract_speed * 60; return $self->retract_speed * 60;
} }
sub _build_scaled_wipe_distance {
my $self = shift;
return scale $self->retract_length / $self->retract_speed * $Slic3r::Config->travel_speed;
}
sub make_flow { sub make_flow {
my $self = shift; my $self = shift;
return Slic3r::Flow->new(nozzle_diameter => $self->nozzle_diameter, @_); return Slic3r::Flow->new(nozzle_diameter => $self->nozzle_diameter, @_);

View File

@ -28,6 +28,7 @@ has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0
has 'last_speed' => (is => 'rw', default => sub {""}); has 'last_speed' => (is => 'rw', default => sub {""});
has 'last_f' => (is => 'rw', default => sub {""}); has 'last_f' => (is => 'rw', default => sub {""});
has 'last_fan_speed' => (is => 'rw', default => sub {0}); has 'last_fan_speed' => (is => 'rw', default => sub {0});
has 'wipe_path' => (is => 'rw');
has 'dec' => (is => 'ro', default => sub { 3 } ); has 'dec' => (is => 'ro', default => sub { 3 } );
# used for vibration limit: # used for vibration limit:
@ -150,6 +151,7 @@ sub extrude_loop {
# extrude along the path # extrude along the path
my $gcode = $self->extrude_path($extrusion_path, $description); my $gcode = $self->extrude_path($extrusion_path, $description);
$self->wipe_path($extrusion_path->polyline);
# make a little move inwards before leaving loop # make a little move inwards before leaving loop
if ($loop->role == EXTR_ROLE_EXTERNAL_PERIMETER) { if ($loop->role == EXTR_ROLE_EXTERNAL_PERIMETER) {
@ -236,12 +238,15 @@ sub extrude_path {
$path_length = unscale $path->length; $path_length = unscale $path->length;
$gcode .= $self->G2_G3($path->points->[-1], $path->orientation, $gcode .= $self->G2_G3($path->points->[-1], $path->orientation,
$path->center, $e * unscale $path_length, $description); $path->center, $e * unscale $path_length, $description);
$self->wipe_path(undef);
} else { } else {
foreach my $line ($path->lines) { foreach my $line ($path->lines) {
my $line_length = unscale $line->length; my $line_length = unscale $line->length;
$path_length += $line_length; $path_length += $line_length;
$gcode .= $self->G1($line->[B], undef, $e * $line_length, $description); $gcode .= $self->G1($line->[B], undef, $e * $line_length, $description);
} }
$self->wipe_path([ reverse @{$path->points}[0..$#{$path->points}] ])
if $Slic3r::Config->wipe;
} }
if ($Slic3r::Config->cooling) { if ($Slic3r::Config->cooling) {
@ -347,6 +352,14 @@ sub retract {
# if we already retracted, reduce the required amount of retraction # if we already retracted, reduce the required amount of retraction
$length -= $self->extruder->retracted; $length -= $self->extruder->retracted;
return "" unless $length > 0; return "" unless $length > 0;
my $gcode = "";
# wipe
my $wipe_path = ();
if ($Slic3r::Config->wipe && $self->wipe_path) {
$wipe_path = Slic3r::Polyline->new([ $self->last_pos, @{$self->wipe_path} ])
->clip_start($self->extruder->scaled_wipe_distance);
}
# prepare moves # prepare moves
$self->speed('retract'); $self->speed('retract');
@ -355,7 +368,6 @@ sub retract {
? undef ? undef
: [undef, $self->z + $self->extruder->retract_lift, 0, 'lift plate during travel']; : [undef, $self->z + $self->extruder->retract_lift, 0, 'lift plate during travel'];
my $gcode = "";
if (($Slic3r::Config->g0 || $Slic3r::Config->gcode_flavor eq 'mach3') && $params{travel_to}) { if (($Slic3r::Config->g0 || $Slic3r::Config->gcode_flavor eq 'mach3') && $params{travel_to}) {
if ($lift) { if ($lift) {
# combine lift and retract # combine lift and retract
@ -371,7 +383,17 @@ sub retract {
my $travel = [undef, $params{move_z}, $retract->[2], "change layer and $comment"]; my $travel = [undef, $params{move_z}, $retract->[2], "change layer and $comment"];
$gcode .= $self->G0(@$travel); $gcode .= $self->G0(@$travel);
} else { } else {
$gcode .= $self->G1(@$retract); if ($wipe_path) {
$self->speed('travel');
# subdivide the retraction
my $total_wipe_length = $wipe_path->length;
for (1 .. $#$wipe_path) {
my $segment_length = $wipe_path->[$_-1]->distance_to($wipe_path->[$_]);
$gcode .= $self->G1($wipe_path->[$_], undef, $retract->[2] * ($segment_length / $total_wipe_length), $retract->[3] . ";_WIPE");
}
} else {
$gcode .= $self->G1(@$retract);
}
if (!$self->lifted) { if (!$self->lifted) {
if (defined $params{move_z} && $self->extruder->retract_lift > 0) { if (defined $params{move_z} && $self->extruder->retract_lift > 0) {
my $travel = [undef, $params{move_z} + $self->extruder->retract_lift, 0, 'move to next layer (' . $self->layer->id . ') and lift']; my $travel = [undef, $params{move_z} + $self->extruder->retract_lift, 0, 'move to next layer (' . $self->layer->id . ') and lift'];

View File

@ -164,6 +164,7 @@ sub scale {
return $self; return $self;
} }
# removes the given distance from the end of the polyline
sub clip_end { sub clip_end {
my $self = shift; my $self = shift;
my ($distance) = @_; my ($distance) = @_;
@ -184,6 +185,30 @@ sub clip_end {
} }
} }
# only keeps the given distance at the beginning of the polyline
sub clip_start {
my $self = shift;
my ($distance) = @_;
my $points = [];
for (my $i = 1; $distance > 0 && $i <= $#$self; $i++) {
my $point = $self->[$i];
my $segment_length = $point->distance_to($self->[$i-1]);
if ($segment_length <= $distance) {
$distance -= $segment_length;
push @$points, $point;
next;
}
my $new_point = Slic3r::Geometry::point_along_segment($self->[$i-1], $point, $distance);
push @$points, Slic3r::Point->new($new_point);
$distance = 0;
}
return (ref $self)->new($points);
}
package Slic3r::Polyline::Collection; package Slic3r::Polyline::Collection;
use Moo; use Moo;

View File

@ -957,7 +957,7 @@ sub write_gcode {
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100; Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;
if ($speed_factor < 1) { if ($speed_factor < 1) {
$gcode =~ s/^(?=.*? [XY])(?=.*? E)(?<!;_BRIDGE_FAN_START\n)(G1 .*?F)(\d+(?:\.\d+)?)/ $gcode =~ s/^(?=.*? [XY])(?=.*? E)(?!;_WIPE)(?<!;_BRIDGE_FAN_START\n)(G1 .*?F)(\d+(?:\.\d+)?)/
my $new_speed = $2 * $speed_factor; my $new_speed = $2 * $speed_factor;
$1 . sprintf("%.${dec}f", $new_speed < $min_print_speed ? $min_print_speed : $new_speed) $1 . sprintf("%.${dec}f", $new_speed < $min_print_speed ? $min_print_speed : $new_speed)
/gexm; /gexm;
@ -973,6 +973,7 @@ sub write_gcode {
$gcode =~ s/^;_BRIDGE_FAN_START\n/ $gcodegen->set_fan($Slic3r::Config->bridge_fan_speed, 1) /gmex; $gcode =~ s/^;_BRIDGE_FAN_START\n/ $gcodegen->set_fan($Slic3r::Config->bridge_fan_speed, 1) /gmex;
$gcode =~ s/^;_BRIDGE_FAN_END\n/ $gcodegen->set_fan($fan_speed, 1) /gmex; $gcode =~ s/^;_BRIDGE_FAN_END\n/ $gcodegen->set_fan($fan_speed, 1) /gmex;
} }
$gcode =~ s/;_WIPE//g;
return $gcode; return $gcode;
}; };

View File

@ -292,6 +292,7 @@ $j
--retract-lift Lift Z by the given distance in mm when retracting (default: $config->{retract_lift}[0]) --retract-lift Lift Z by the given distance in mm when retracting (default: $config->{retract_lift}[0])
--retract-layer-change --retract-layer-change
Enforce a retraction before each Z move (default: yes) Enforce a retraction before each Z move (default: yes)
--wipe Wipe the nozzle while doing a retraction (default: no)
Retraction options for multi-extruder setups: Retraction options for multi-extruder setups:
--retract-length-toolchange --retract-length-toolchange