Skip to content

Commit

Permalink
New wipe feature
Browse files Browse the repository at this point in the history
  • Loading branch information
alranel committed Mar 17, 2013
1 parent 83065b0 commit 7de8b20
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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-layer-change
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:
--retract-length-toolchange
Expand Down
11 changes: 10 additions & 1 deletion lib/Slic3r/Config.pm
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,15 @@ END
deserialize => $deserialize_comma,
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' => {
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).',
Expand Down Expand Up @@ -1065,7 +1074,7 @@ sub new_from_cli {
}

$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);
}
Expand Down
10 changes: 8 additions & 2 deletions lib/Slic3r/Extruder.pm
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package Slic3r::Extruder;
use Moo;

use Slic3r::Geometry qw(PI);
use Slic3r::Geometry qw(PI scale);

use constant OPTIONS => [qw(
extruder_offset
nozzle_diameter filament_diameter extrusion_multiplier temperature first_layer_temperature
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);
Expand All @@ -18,6 +18,7 @@ has 'retracted' => (is => 'rw', default => sub {0} );
has 'restart_extra' => (is => 'rw', default => sub {0} );
has 'e_per_mm3' => (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 {{}});

sub _build_bridge_flow {
Expand All @@ -35,6 +36,11 @@ sub _build_retract_speed_mm_min {
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 {
my $self = shift;
return Slic3r::Flow->new(nozzle_diameter => $self->nozzle_diameter, @_);
Expand Down
26 changes: 24 additions & 2 deletions lib/Slic3r/GCode.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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_f' => (is => 'rw', default => sub {""});
has 'last_fan_speed' => (is => 'rw', default => sub {0});
has 'wipe_path' => (is => 'rw');
has 'dec' => (is => 'ro', default => sub { 3 } );

# used for vibration limit:
Expand Down Expand Up @@ -150,6 +151,7 @@ sub extrude_loop {

# extrude along the path
my $gcode = $self->extrude_path($extrusion_path, $description);
$self->wipe_path($extrusion_path->polyline);

# make a little move inwards before leaving loop
if ($loop->role == EXTR_ROLE_EXTERNAL_PERIMETER) {
Expand Down Expand Up @@ -236,12 +238,15 @@ sub extrude_path {
$path_length = unscale $path->length;
$gcode .= $self->G2_G3($path->points->[-1], $path->orientation,
$path->center, $e * unscale $path_length, $description);
$self->wipe_path(undef);
} else {
foreach my $line ($path->lines) {
my $line_length = unscale $line->length;
$path_length += $line_length;
$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) {
Expand Down Expand Up @@ -347,6 +352,14 @@ sub retract {
# if we already retracted, reduce the required amount of retraction
$length -= $self->extruder->retracted;
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
$self->speed('retract');
Expand All @@ -355,7 +368,6 @@ sub retract {
? undef
: [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 ($lift) {
# combine lift and retract
Expand All @@ -371,7 +383,17 @@ sub retract {
my $travel = [undef, $params{move_z}, $retract->[2], "change layer and $comment"];
$gcode .= $self->G0(@$travel);
} 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 (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'];
Expand Down
25 changes: 25 additions & 0 deletions lib/Slic3r/Polyline.pm
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ sub scale {
return $self;
}

# removes the given distance from the end of the polyline
sub clip_end {
my $self = shift;
my ($distance) = @_;
Expand All @@ -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;
use Moo;

Expand Down
3 changes: 2 additions & 1 deletion lib/Slic3r/Print.pm
Original file line number Diff line number Diff line change
Expand Up @@ -957,7 +957,7 @@ sub write_gcode {
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;

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;
$1 . sprintf("%.${dec}f", $new_speed < $min_print_speed ? $min_print_speed : $new_speed)
/gexm;
Expand All @@ -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_END\n/ $gcodegen->set_fan($fan_speed, 1) /gmex;
}
$gcode =~ s/;_WIPE//g;

return $gcode;
};
Expand Down
1 change: 1 addition & 0 deletions slic3r.pl
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ sub usage {
--retract-lift Lift Z by the given distance in mm when retracting (default: $config->{retract_lift}[0])
--retract-layer-change
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:
--retract-length-toolchange
Expand Down

0 comments on commit 7de8b20

Please sign in to comment.