Cooling and fan control. #110
This commit is contained in:
parent
f4fde54bf3
commit
1d0a852679
@ -38,6 +38,7 @@ Slic3r current key features are:
|
|||||||
* ability to scale, rotate and duplicate input object;
|
* ability to scale, rotate and duplicate input object;
|
||||||
* customizable initial and final GCODE;
|
* customizable initial and final GCODE;
|
||||||
* support material;
|
* support material;
|
||||||
|
* cooling and fan control;
|
||||||
* use different speed for bottom layer and perimeters.
|
* use different speed for bottom layer and perimeters.
|
||||||
|
|
||||||
Experimental features include:
|
Experimental features include:
|
||||||
@ -50,7 +51,6 @@ Roadmap includes the following goals:
|
|||||||
* output some statistics;
|
* output some statistics;
|
||||||
* support material for internal perimeters;
|
* support material for internal perimeters;
|
||||||
* new and better GUI;
|
* new and better GUI;
|
||||||
* cool;
|
|
||||||
* more fill patterns.
|
* more fill patterns.
|
||||||
|
|
||||||
## Is it usable already? Any known limitation?
|
## Is it usable already? Any known limitation?
|
||||||
@ -91,6 +91,8 @@ The author is Alessandro Ranellucci (me).
|
|||||||
Output file name format; all config options enclosed in brackets
|
Output file name format; all config options enclosed in brackets
|
||||||
will be replaced by their values, as well as [input_filename_base]
|
will be replaced by their values, as well as [input_filename_base]
|
||||||
and [input_filename] (default: [input_filename_base].gcode)
|
and [input_filename] (default: [input_filename_base].gcode)
|
||||||
|
--post-process Generated G-code will be processed with the supplied script;
|
||||||
|
call this more than once to process through multiple scripts.
|
||||||
|
|
||||||
Printer options:
|
Printer options:
|
||||||
--nozzle-diameter Diameter of nozzle in mm (default: 0.5)
|
--nozzle-diameter Diameter of nozzle in mm (default: 0.5)
|
||||||
@ -161,6 +163,17 @@ The author is Alessandro Ranellucci (me).
|
|||||||
Only retract before travel moves of this length in mm (default: 2)
|
Only retract before travel moves of this length in mm (default: 2)
|
||||||
--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)
|
||||||
|
|
||||||
|
Cooling options:
|
||||||
|
--min-fan-speed Minimum fan speed (default: 35%)
|
||||||
|
--max-fan-speed Maximum fan speed (default: 100%)
|
||||||
|
--bridge-fan-speed Fan speed to use when bridging (default: 100%)
|
||||||
|
--fan-below-layer-time Enable fan if layer print time is below this approximate number
|
||||||
|
of seconds (default: 60)
|
||||||
|
--slowdown-below-layer-time Slow down if layer print time is below this approximate number
|
||||||
|
of seconds (default: 15)
|
||||||
|
--min-print-speed Minimum print speed speed (mm/s, default: 10)
|
||||||
|
--disable-fan-first-layers Disable fan for the first N layers (default: 1)
|
||||||
|
|
||||||
Skirt options:
|
Skirt options:
|
||||||
--skirts Number of skirts to draw (0+, default: 1)
|
--skirts Number of skirts to draw (0+, default: 1)
|
||||||
--skirt-distance Distance in mm between innermost skirt and object
|
--skirt-distance Distance in mm between innermost skirt and object
|
||||||
|
@ -114,6 +114,15 @@ our $retract_speed = 30; # mm/s
|
|||||||
our $retract_before_travel = 2; # mm
|
our $retract_before_travel = 2; # mm
|
||||||
our $retract_lift = 0; # mm
|
our $retract_lift = 0; # mm
|
||||||
|
|
||||||
|
# cooling options
|
||||||
|
our $min_fan_speed = 35;
|
||||||
|
our $max_fan_speed = 100;
|
||||||
|
our $bridge_fan_speed = 100;
|
||||||
|
our $fan_below_layer_time = 60;
|
||||||
|
our $slowdown_below_layer_time = 15;
|
||||||
|
our $min_print_speed = 10;
|
||||||
|
our $disable_fan_first_layers = 1;
|
||||||
|
|
||||||
# skirt options
|
# skirt options
|
||||||
our $skirts = 1;
|
our $skirts = 1;
|
||||||
our $skirt_distance = 6; # mm
|
our $skirt_distance = 6; # mm
|
||||||
|
@ -292,6 +292,43 @@ our $Options = {
|
|||||||
type => 'f',
|
type => 'f',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
# cooling options
|
||||||
|
'min_fan_speed' => {
|
||||||
|
label => 'Min fan speed (%)',
|
||||||
|
cli => 'min-fan-speed=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'max_fan_speed' => {
|
||||||
|
label => 'Max fan speed (%)',
|
||||||
|
cli => 'max-fan-speed=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'bridge_fan_speed' => {
|
||||||
|
label => 'Bridge fan speed (%)',
|
||||||
|
cli => 'bridge-fan-speed=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'fan_below_layer_time' => {
|
||||||
|
label => 'Enable fan if layer print time is below (approximate seconds)',
|
||||||
|
cli => 'fan-below-layer-time=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'slowdown_below_layer_time' => {
|
||||||
|
label => 'Slow down if layer print time is below (approximate seconds)',
|
||||||
|
cli => 'slowdown-below-layer-time=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'min_print_speed' => {
|
||||||
|
label => 'Min print speed (mm/s)',
|
||||||
|
cli => 'min-print-speed=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
'disable_fan_first_layers' => {
|
||||||
|
label => 'Disable fan for the first N layers',
|
||||||
|
cli => 'disable-fan-first-layers=i',
|
||||||
|
type => 'i',
|
||||||
|
},
|
||||||
|
|
||||||
# skirt options
|
# skirt options
|
||||||
'skirts' => {
|
'skirts' => {
|
||||||
label => 'Loops',
|
label => 'Loops',
|
||||||
|
@ -1,50 +1,36 @@
|
|||||||
package Slic3r::Extruder;
|
package Slic3r::Extruder;
|
||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use Slic3r::Geometry qw(scale);
|
use Slic3r::Geometry qw(scale unscale);
|
||||||
|
|
||||||
has 'layer' => (is => 'rw');
|
has 'layer' => (is => 'rw');
|
||||||
has 'shift_x' => (is => 'rw', default => sub {0} );
|
has 'shift_x' => (is => 'rw', default => sub {0} );
|
||||||
has 'shift_y' => (is => 'rw', default => sub {0} );
|
has 'shift_y' => (is => 'rw', default => sub {0} );
|
||||||
has 'z' => (is => 'rw', default => sub {0} );
|
has 'z' => (is => 'rw', default => sub {0} );
|
||||||
has 'print_feed_rate' => (is => 'rw');
|
has 'speed' => (is => 'rw');
|
||||||
|
|
||||||
has 'extrusion_distance' => (is => 'rw', default => sub {0} );
|
has 'extrusion_distance' => (is => 'rw', default => sub {0} );
|
||||||
|
has 'elapsed_time' => (is => 'rw', default => sub {0} ); # seconds
|
||||||
has 'total_extrusion_length' => (is => 'rw', default => sub {0} );
|
has 'total_extrusion_length' => (is => 'rw', default => sub {0} );
|
||||||
has 'retracted' => (is => 'rw', default => sub {1} ); # this spits out some plastic at start
|
has 'retracted' => (is => 'rw', default => sub {1} ); # this spits out some plastic at start
|
||||||
has 'lifted' => (is => 'rw', default => sub {0} );
|
has 'lifted' => (is => 'rw', default => sub {0} );
|
||||||
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
|
has 'last_pos' => (is => 'rw', default => sub { Slic3r::Point->new(0,0) } );
|
||||||
has 'last_f' => (is => 'rw', default => sub {0});
|
has 'last_speed' => (is => 'rw', default => sub {""});
|
||||||
|
has 'last_fan_speed' => (is => 'rw', default => sub {0});
|
||||||
has 'dec' => (is => 'ro', default => sub { 3 } );
|
has 'dec' => (is => 'ro', default => sub { 3 } );
|
||||||
|
|
||||||
# calculate speeds
|
# calculate speeds (mm/min)
|
||||||
has 'travel_speed' => (
|
has 'speeds' => (
|
||||||
is => 'ro',
|
is => 'ro',
|
||||||
default => sub { $Slic3r::travel_speed * 60 }, # mm/min
|
default => sub {{
|
||||||
);
|
travel => 60 * $Slic3r::travel_speed,
|
||||||
has 'perimeter_speed' => (
|
perimeter => 60 * $Slic3r::perimeter_speed,
|
||||||
is => 'ro',
|
small_perimeter => 60 * $Slic3r::small_perimeter_speed,
|
||||||
default => sub { $Slic3r::perimeter_speed * 60 }, # mm/min
|
infill => 60 * $Slic3r::infill_speed,
|
||||||
);
|
solid_infill => 60 * $Slic3r::solid_infill_speed,
|
||||||
has 'small_perimeter_speed' => (
|
bridge => 60 * $Slic3r::bridge_speed,
|
||||||
is => 'ro',
|
retract => 60 * $Slic3r::retract_speed,
|
||||||
default => sub { $Slic3r::small_perimeter_speed * 60 }, # mm/min
|
}},
|
||||||
);
|
|
||||||
has 'infill_speed' => (
|
|
||||||
is => 'ro',
|
|
||||||
default => sub { $Slic3r::infill_speed * 60 }, # mm/min
|
|
||||||
);
|
|
||||||
has 'solid_infill_speed' => (
|
|
||||||
is => 'ro',
|
|
||||||
default => sub { $Slic3r::solid_infill_speed * 60 }, # mm/min
|
|
||||||
);
|
|
||||||
has 'bridge_speed' => (
|
|
||||||
is => 'ro',
|
|
||||||
default => sub { $Slic3r::bridge_speed * 60 }, # mm/min
|
|
||||||
);
|
|
||||||
has 'retract_speed' => (
|
|
||||||
is => 'ro',
|
|
||||||
default => sub { $Slic3r::retract_speed * 60 }, # mm/min
|
|
||||||
);
|
);
|
||||||
|
|
||||||
use Slic3r::Geometry qw(points_coincide PI X Y);
|
use Slic3r::Geometry qw(points_coincide PI X Y);
|
||||||
@ -151,23 +137,32 @@ sub extrude_path {
|
|||||||
* (4 / (($Slic3r::filament_diameter ** 2) * PI));
|
* (4 / (($Slic3r::filament_diameter ** 2) * PI));
|
||||||
|
|
||||||
# extrude arc or line
|
# extrude arc or line
|
||||||
$self->print_feed_rate(
|
$self->speed(
|
||||||
$path->role =~ /^(perimeter|skirt|support-material)$/o ? $self->perimeter_speed
|
$path->role =~ /^(perimeter|skirt|support-material)$/o ? 'perimeter'
|
||||||
: $path->role eq 'small-perimeter' ? $self->small_perimeter_speed
|
: $path->role eq 'small-perimeter' ? 'small_perimeter'
|
||||||
: $path->role eq 'fill' ? $self->infill_speed
|
: $path->role eq 'fill' ? 'infill'
|
||||||
: $path->role eq 'solid-fill' ? $self->solid_infill_speed
|
: $path->role eq 'solid-fill' ? 'solid_infill'
|
||||||
: $path->role eq 'bridge' ? $self->bridge_speed
|
: $path->role eq 'bridge' ? 'bridge'
|
||||||
: die "Unknown role: " . $path->role
|
: die "Unknown role: " . $path->role
|
||||||
);
|
);
|
||||||
|
my $path_length = 0;
|
||||||
if ($path->isa('Slic3r::ExtrusionPath::Arc')) {
|
if ($path->isa('Slic3r::ExtrusionPath::Arc')) {
|
||||||
|
$path_length = $path->length;
|
||||||
$gcode .= $self->G2_G3($path->points->[-1], $path->orientation,
|
$gcode .= $self->G2_G3($path->points->[-1], $path->orientation,
|
||||||
$path->center, $e * $path->length, $description);
|
$path->center, $e * $path_length, $description);
|
||||||
} else {
|
} else {
|
||||||
foreach my $line ($path->lines) {
|
foreach my $line ($path->lines) {
|
||||||
$gcode .= $self->G1($line->b, undef, $e * $line->length, $description);
|
my $line_length = $line->length;
|
||||||
|
$path_length += $line_length;
|
||||||
|
$gcode .= $self->G1($line->b, undef, $e * $line_length, $description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO: optimize: avoid calculation if cooling is disabled
|
||||||
|
if (1) {
|
||||||
|
$self->elapsed_time($self->elapsed_time + (unscale($path_length) / $self->speeds->{$self->last_speed} * 60));
|
||||||
|
}
|
||||||
|
|
||||||
return $gcode;
|
return $gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +174,7 @@ sub retract {
|
|||||||
&& !$self->retracted;
|
&& !$self->retracted;
|
||||||
|
|
||||||
# prepare moves
|
# prepare moves
|
||||||
$self->print_feed_rate($self->retract_speed);
|
$self->speed('retract');
|
||||||
my $retract = [undef, undef, -$Slic3r::retract_length, "retract"];
|
my $retract = [undef, undef, -$Slic3r::retract_length, "retract"];
|
||||||
my $lift = ($Slic3r::retract_lift == 0 || defined $params{move_z})
|
my $lift = ($Slic3r::retract_lift == 0 || defined $params{move_z})
|
||||||
? undef
|
? undef
|
||||||
@ -229,7 +224,7 @@ sub unretract {
|
|||||||
$self->lifted(0);
|
$self->lifted(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->print_feed_rate($self->retract_speed);
|
$self->speed('retract');
|
||||||
$gcode .= $self->G0(undef, undef, ($Slic3r::retract_length + $Slic3r::retract_restart_extra),
|
$gcode .= $self->G0(undef, undef, ($Slic3r::retract_length + $Slic3r::retract_restart_extra),
|
||||||
"compensate retraction");
|
"compensate retraction");
|
||||||
|
|
||||||
@ -239,7 +234,7 @@ sub unretract {
|
|||||||
sub set_acceleration {
|
sub set_acceleration {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($acceleration) = @_;
|
my ($acceleration) = @_;
|
||||||
return unless $Slic3r::acceleration;
|
return "" unless $Slic3r::acceleration;
|
||||||
|
|
||||||
return sprintf "M201 E%s%s\n",
|
return sprintf "M201 E%s%s\n",
|
||||||
$acceleration, ($Slic3r::gcode_comments ? ' ; adjust acceleration' : '');
|
$acceleration, ($Slic3r::gcode_comments ? ' ; adjust acceleration' : '');
|
||||||
@ -248,21 +243,19 @@ sub set_acceleration {
|
|||||||
sub G0 {
|
sub G0 {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return $self->G1(@_) if !$Slic3r::g0;
|
return $self->G1(@_) if !$Slic3r::g0;
|
||||||
return "G0" . $self->G0_G1(@_);
|
return $self->_G0_G1("G0", @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub G1 {
|
sub G1 {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
return "G1" . $self->G0_G1(@_);
|
return $self->_G0_G1("G1", @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub G0_G1 {
|
sub _G0_G1 {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($point, $z, $e, $comment) = @_;
|
my ($gcode, $point, $z, $e, $comment) = @_;
|
||||||
my $dec = $self->dec;
|
my $dec = $self->dec;
|
||||||
|
|
||||||
my $gcode = "";
|
|
||||||
|
|
||||||
if ($point) {
|
if ($point) {
|
||||||
$gcode .= sprintf " X%.${dec}f Y%.${dec}f",
|
$gcode .= sprintf " X%.${dec}f Y%.${dec}f",
|
||||||
($point->x * $Slic3r::resolution) + $self->shift_x,
|
($point->x * $Slic3r::resolution) + $self->shift_x,
|
||||||
@ -308,13 +301,19 @@ sub _Gx {
|
|||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
# determine speed
|
# determine speed
|
||||||
my $speed = ($e ? $self->print_feed_rate : $self->travel_speed) * $speed_multiplier;
|
my $speed = ($e ? $self->speed : 'travel');
|
||||||
|
|
||||||
# output speed if it's different from last one used
|
# output speed if it's different from last one used
|
||||||
# (goal: reduce gcode size)
|
# (goal: reduce gcode size)
|
||||||
if ($speed != $self->last_f) {
|
my $append_bridge_off = 0;
|
||||||
$gcode .= sprintf " F%.${dec}f", $speed;
|
if ($speed ne $self->last_speed) {
|
||||||
$self->last_f($speed);
|
if ($speed eq 'bridge') {
|
||||||
|
$gcode = "_BRIDGE_FAN_START\n$gcode";
|
||||||
|
} elsif ($self->last_speed eq 'bridge') {
|
||||||
|
$append_bridge_off = 1;
|
||||||
|
}
|
||||||
|
$gcode .= sprintf " F%.${dec}f", $self->speeds->{$speed} * $speed_multiplier;
|
||||||
|
$self->last_speed($speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
# output extrusion distance
|
# output extrusion distance
|
||||||
@ -326,6 +325,9 @@ sub _Gx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$gcode .= sprintf " ; %s", $comment if $comment && $Slic3r::gcode_comments;
|
$gcode .= sprintf " ; %s", $comment if $comment && $Slic3r::gcode_comments;
|
||||||
|
if ($append_bridge_off) {
|
||||||
|
$gcode .= "\n_BRIDGE_FAN_END";
|
||||||
|
}
|
||||||
return "$gcode\n";
|
return "$gcode\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,4 +338,19 @@ sub set_tool {
|
|||||||
return sprintf "T%d%s\n", $tool, ($Slic3r::gcode_comments ? ' ; change tool' : '');
|
return sprintf "T%d%s\n", $tool, ($Slic3r::gcode_comments ? ' ; change tool' : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub set_fan {
|
||||||
|
my $self = shift;
|
||||||
|
my ($speed, $dont_save) = @_;
|
||||||
|
|
||||||
|
if ($self->last_fan_speed != $speed || $dont_save) {
|
||||||
|
$self->last_fan_speed($speed) if !$dont_save;
|
||||||
|
if ($speed == 0) {
|
||||||
|
return sprintf "M107%s\n", ($Slic3r::gcode_comments ? ' ; disable fan' : '');
|
||||||
|
} else {
|
||||||
|
return sprintf "M106 S%d%s\n", (255 * $speed / 100), ($Slic3r::gcode_comments ? ' ; enable fan' : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
@ -26,8 +26,9 @@ sub new {
|
|||||||
|
|
||||||
foreach my $opt_key (@{$p{options}}) {
|
foreach my $opt_key (@{$p{options}}) {
|
||||||
my $opt = $Slic3r::Config::Options->{$opt_key};
|
my $opt = $Slic3r::Config::Options->{$opt_key};
|
||||||
my $label = Wx::StaticText->new($parent, -1, "$opt->{label}:", Wx::wxDefaultPosition, [180,-1]);
|
my $label = Wx::StaticText->new($parent, -1, "$opt->{label}:", Wx::wxDefaultPosition,
|
||||||
$label->Wrap(180); # needed to avoid Linux/GTK bug
|
[$p{label_width} || 180, -1]);
|
||||||
|
$label->Wrap($p{label_width} || 180); # needed to avoid Linux/GTK bug
|
||||||
|
|
||||||
#set the bold font point size to the same size as all the other labels (for consistency)
|
#set the bold font point size to the same size as all the other labels (for consistency)
|
||||||
$bold_font->SetPointSize($label->GetFont()->GetPointSize());
|
$bold_font->SetPointSize($label->GetFont()->GetPointSize());
|
||||||
|
@ -47,6 +47,11 @@ sub new {
|
|||||||
title => 'Retraction',
|
title => 'Retraction',
|
||||||
options => [qw(retract_length retract_lift retract_speed retract_restart_extra retract_before_travel)],
|
options => [qw(retract_length retract_lift retract_speed retract_restart_extra retract_before_travel)],
|
||||||
},
|
},
|
||||||
|
cooling => {
|
||||||
|
title => 'Cooling',
|
||||||
|
options => [qw(min_fan_speed max_fan_speed bridge_fan_speed fan_below_layer_time slowdown_below_layer_time min_print_speed disable_fan_first_layers)],
|
||||||
|
label_width => 300,
|
||||||
|
},
|
||||||
skirt => {
|
skirt => {
|
||||||
title => 'Skirt',
|
title => 'Skirt',
|
||||||
options => [qw(skirts skirt_distance skirt_height)],
|
options => [qw(skirts skirt_distance skirt_height)],
|
||||||
@ -101,6 +106,7 @@ sub new {
|
|||||||
|
|
||||||
my @tabs = (
|
my @tabs = (
|
||||||
$make_tab->([qw(transform accuracy skirt)], [qw(print retract)]),
|
$make_tab->([qw(transform accuracy skirt)], [qw(print retract)]),
|
||||||
|
$make_tab->([qw(cooling)]),
|
||||||
$make_tab->([qw(printer filament)], [qw(print_speed speed)]),
|
$make_tab->([qw(printer filament)], [qw(print_speed speed)]),
|
||||||
$make_tab->([qw(gcode)]),
|
$make_tab->([qw(gcode)]),
|
||||||
$make_tab->([qw(notes)]),
|
$make_tab->([qw(notes)]),
|
||||||
@ -108,10 +114,11 @@ sub new {
|
|||||||
);
|
);
|
||||||
|
|
||||||
$tabpanel->AddPage($tabs[0], "Print Settings");
|
$tabpanel->AddPage($tabs[0], "Print Settings");
|
||||||
$tabpanel->AddPage($tabs[1], "Printer and Filament");
|
$tabpanel->AddPage($tabs[1], "Cooling");
|
||||||
$tabpanel->AddPage($tabs[2], "Start/End GCODE");
|
$tabpanel->AddPage($tabs[2], "Printer and Filament");
|
||||||
$tabpanel->AddPage($tabs[3], "Notes");
|
$tabpanel->AddPage($tabs[3], "Start/End GCODE");
|
||||||
$tabpanel->AddPage($tabs[4], "Advanced");
|
$tabpanel->AddPage($tabs[4], "Notes");
|
||||||
|
$tabpanel->AddPage($tabs[5], "Advanced");
|
||||||
|
|
||||||
my $buttons_sizer;
|
my $buttons_sizer;
|
||||||
{
|
{
|
||||||
|
@ -612,6 +612,8 @@ sub export_gcode {
|
|||||||
|
|
||||||
# set up our extruder object
|
# set up our extruder object
|
||||||
my $extruder = Slic3r::Extruder->new;
|
my $extruder = Slic3r::Extruder->new;
|
||||||
|
my $min_print_speed = 60 * $Slic3r::min_print_speed;
|
||||||
|
my $dec = $extruder->dec;
|
||||||
if ($Slic3r::support_material && $Slic3r::support_material_tool > 0) {
|
if ($Slic3r::support_material && $Slic3r::support_material_tool > 0) {
|
||||||
print $fh $extruder->set_tool(0);
|
print $fh $extruder->set_tool(0);
|
||||||
}
|
}
|
||||||
@ -621,36 +623,75 @@ sub export_gcode {
|
|||||||
# go to layer
|
# go to layer
|
||||||
print $fh $extruder->change_layer($layer);
|
print $fh $extruder->change_layer($layer);
|
||||||
|
|
||||||
|
my $layer_gcode = "";
|
||||||
|
$extruder->elapsed_time(0);
|
||||||
|
|
||||||
# extrude skirts
|
# extrude skirts
|
||||||
$extruder->shift_x($shift[X]);
|
$extruder->shift_x($shift[X]);
|
||||||
$extruder->shift_y($shift[Y]);
|
$extruder->shift_y($shift[Y]);
|
||||||
print $fh $extruder->set_acceleration($Slic3r::perimeter_acceleration);
|
$layer_gcode .= $extruder->set_acceleration($Slic3r::perimeter_acceleration);
|
||||||
print $fh $extruder->extrude_loop($_, 'skirt') for @{ $layer->skirts };
|
$layer_gcode .= $extruder->extrude_loop($_, 'skirt') for @{ $layer->skirts };
|
||||||
|
|
||||||
foreach my $copy (@{$self->copies}) {
|
foreach my $copy (@{$self->copies}) {
|
||||||
$extruder->shift_x($shift[X] + unscale $copy->[X]);
|
$extruder->shift_x($shift[X] + unscale $copy->[X]);
|
||||||
$extruder->shift_y($shift[Y] + unscale $copy->[Y]);
|
$extruder->shift_y($shift[Y] + unscale $copy->[Y]);
|
||||||
|
|
||||||
# extrude perimeters
|
# extrude perimeters
|
||||||
print $fh $extruder->extrude($_, 'perimeter') for @{ $layer->perimeters };
|
$layer_gcode .= $extruder->extrude($_, 'perimeter') for @{ $layer->perimeters };
|
||||||
|
|
||||||
# extrude fills
|
# extrude fills
|
||||||
print $fh $extruder->set_acceleration($Slic3r::infill_acceleration);
|
$layer_gcode .= $extruder->set_acceleration($Slic3r::infill_acceleration);
|
||||||
for my $fill (@{ $layer->fills }) {
|
for my $fill (@{ $layer->fills }) {
|
||||||
print $fh $extruder->extrude_path($_, 'fill')
|
$layer_gcode .= $extruder->extrude_path($_, 'fill')
|
||||||
for $fill->shortest_path($extruder->last_pos);
|
for $fill->shortest_path($extruder->last_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
# extrude support material
|
# extrude support material
|
||||||
if ($layer->support_fills) {
|
if ($layer->support_fills) {
|
||||||
print $fh $extruder->set_tool($Slic3r::support_material_tool)
|
$layer_gcode .= $extruder->set_tool($Slic3r::support_material_tool)
|
||||||
if $Slic3r::support_material_tool > 0;
|
if $Slic3r::support_material_tool > 0;
|
||||||
print $fh $extruder->extrude_path($_, 'support material')
|
$layer_gcode .= $extruder->extrude_path($_, 'support material')
|
||||||
for $layer->support_fills->shortest_path($extruder->last_pos);
|
for $layer->support_fills->shortest_path($extruder->last_pos);
|
||||||
print $fh $extruder->set_tool(0)
|
$layer_gcode .= $extruder->set_tool(0)
|
||||||
if $Slic3r::support_material_tool > 0;
|
if $Slic3r::support_material_tool > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
last if !$layer_gcode;
|
||||||
|
|
||||||
|
my $layer_time = $extruder->elapsed_time;
|
||||||
|
my $fan_speed = 0;
|
||||||
|
my $speed_factor = 1;
|
||||||
|
Slic3r::debugf "Layer %d estimated printing time: %d seconds\n", $layer->id, $layer_time;
|
||||||
|
if ($layer_time < $Slic3r::fan_below_layer_time) {
|
||||||
|
if ($layer_time < $Slic3r::slowdown_below_layer_time) {
|
||||||
|
$fan_speed = $Slic3r::max_fan_speed;
|
||||||
|
$speed_factor = $layer_time / $Slic3r::slowdown_below_layer_time;
|
||||||
|
} else {
|
||||||
|
$fan_speed = $Slic3r::max_fan_speed - ($Slic3r::max_fan_speed - $Slic3r::min_fan_speed)
|
||||||
|
* ($layer_time - $Slic3r::slowdown_below_layer_time)
|
||||||
|
/ ($Slic3r::fan_below_layer_time - $Slic3r::slowdown_below_layer_time); #/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;
|
||||||
|
|
||||||
|
if ($speed_factor < 1) {
|
||||||
|
$layer_gcode =~ s/^(?=.*? [XY])(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;
|
||||||
|
}
|
||||||
|
$fan_speed = 0 if $layer->id < $Slic3r::disable_fan_first_layers;
|
||||||
|
$layer_gcode = $extruder->set_fan($fan_speed) . $layer_gcode;
|
||||||
|
|
||||||
|
# bridge fan speed
|
||||||
|
if ($Slic3r::bridge_fan_speed == 0 || $layer->id < $Slic3r::disable_fan_first_layers) {
|
||||||
|
$layer_gcode =~ s/^_BRIDGE_FAN_(?:START|END)\n//gm;
|
||||||
|
} else {
|
||||||
|
$layer_gcode =~ s/^_BRIDGE_FAN_START\n/ $extruder->set_fan($Slic3r::bridge_fan_speed, 1) /gmex;
|
||||||
|
$layer_gcode =~ s/^_BRIDGE_FAN_END\n/ $extruder->set_fan($fan_speed, 1) /gmex;
|
||||||
|
}
|
||||||
|
|
||||||
|
print $fh $layer_gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
# save statistic data
|
# save statistic data
|
||||||
@ -658,6 +699,7 @@ sub export_gcode {
|
|||||||
|
|
||||||
# write end commands to file
|
# write end commands to file
|
||||||
print $fh $extruder->retract;
|
print $fh $extruder->retract;
|
||||||
|
print $fh $extruder->set_fan(0);
|
||||||
print $fh "M501 ; reset acceleration\n" if $Slic3r::acceleration;
|
print $fh "M501 ; reset acceleration\n" if $Slic3r::acceleration;
|
||||||
print $fh "$Slic3r::end_gcode\n";
|
print $fh "$Slic3r::end_gcode\n";
|
||||||
|
|
||||||
|
11
slic3r.pl
11
slic3r.pl
@ -181,6 +181,17 @@ Usage: slic3r.pl [ OPTIONS ] file.stl
|
|||||||
Only retract before travel moves of this length in mm (default: $Slic3r::retract_before_travel)
|
Only retract before travel moves of this length in mm (default: $Slic3r::retract_before_travel)
|
||||||
--retract-lift Lift Z by the given distance in mm when retracting (default: $Slic3r::retract_lift)
|
--retract-lift Lift Z by the given distance in mm when retracting (default: $Slic3r::retract_lift)
|
||||||
|
|
||||||
|
Cooling options:
|
||||||
|
--min-fan-speed Minimum fan speed (default: $Slic3r::min_fan_speed%)
|
||||||
|
--max-fan-speed Maximum fan speed (default: $Slic3r::max_fan_speed%)
|
||||||
|
--bridge-fan-speed Fan speed to use when bridging (default: $Slic3r::bridge_fan_speed%)
|
||||||
|
--fan-below-layer-time Enable fan if layer print time is below this approximate number
|
||||||
|
of seconds (default: $Slic3r::fan_below_layer_time)
|
||||||
|
--slowdown-below-layer-time Slow down if layer print time is below this approximate number
|
||||||
|
of seconds (default: $Slic3r::slowdown_below_layer_time)
|
||||||
|
--min-print-speed Minimum print speed speed (mm/s, default: $Slic3r::min_print_speed)
|
||||||
|
--disable-fan-first-layers Disable fan for the first N layers (default: $Slic3r::disable_fan_first_layers)
|
||||||
|
|
||||||
Skirt options:
|
Skirt options:
|
||||||
--skirts Number of skirts to draw (0+, default: $Slic3r::skirts)
|
--skirts Number of skirts to draw (0+, default: $Slic3r::skirts)
|
||||||
--skirt-distance Distance in mm between innermost skirt and object
|
--skirt-distance Distance in mm between innermost skirt and object
|
||||||
|
Loading…
Reference in New Issue
Block a user