New wipe feature
This commit is contained in:
parent
83065b0789
commit
7de8b20bc4
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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, @_);
|
||||||
|
@ -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
|
||||||
@ -370,8 +382,18 @@ sub retract {
|
|||||||
# combine Z change and retraction
|
# combine Z change and retraction
|
||||||
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 {
|
||||||
|
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 {
|
} else {
|
||||||
$gcode .= $self->G1(@$retract);
|
$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'];
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user