Bugfix: time estimates for cooling were computed for each object separately instead of the whole actual layer. #1071
This commit is contained in:
parent
a563801304
commit
b4be61b703
1
MANIFEST
1
MANIFEST
@ -24,6 +24,7 @@ lib/Slic3r/Format/AMF/Parser.pm
|
|||||||
lib/Slic3r/Format/OBJ.pm
|
lib/Slic3r/Format/OBJ.pm
|
||||||
lib/Slic3r/Format/STL.pm
|
lib/Slic3r/Format/STL.pm
|
||||||
lib/Slic3r/GCode.pm
|
lib/Slic3r/GCode.pm
|
||||||
|
lib/Slic3r/GCode/CoolingBuffer.pm
|
||||||
lib/Slic3r/GCode/MotionPlanner.pm
|
lib/Slic3r/GCode/MotionPlanner.pm
|
||||||
lib/Slic3r/Geometry.pm
|
lib/Slic3r/Geometry.pm
|
||||||
lib/Slic3r/Geometry/Clipper.pm
|
lib/Slic3r/Geometry/Clipper.pm
|
||||||
|
@ -45,6 +45,7 @@ use Slic3r::Format::AMF;
|
|||||||
use Slic3r::Format::OBJ;
|
use Slic3r::Format::OBJ;
|
||||||
use Slic3r::Format::STL;
|
use Slic3r::Format::STL;
|
||||||
use Slic3r::GCode;
|
use Slic3r::GCode;
|
||||||
|
use Slic3r::GCode::CoolingBuffer;
|
||||||
use Slic3r::GCode::MotionPlanner;
|
use Slic3r::GCode::MotionPlanner;
|
||||||
use Slic3r::Geometry qw(PI);
|
use Slic3r::Geometry qw(PI);
|
||||||
use Slic3r::Layer;
|
use Slic3r::Layer;
|
||||||
|
77
lib/Slic3r/GCode/CoolingBuffer.pm
Normal file
77
lib/Slic3r/GCode/CoolingBuffer.pm
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package Slic3r::GCode::CoolingBuffer;
|
||||||
|
use Moo;
|
||||||
|
|
||||||
|
has 'config' => (is => 'ro', required => 1);
|
||||||
|
has 'gcodegen' => (is => 'ro', required => 1);
|
||||||
|
has 'gcode' => (is => 'rw', default => sub {""});
|
||||||
|
has 'layer_id' => (is => 'rw');
|
||||||
|
has 'last_z' => (is => 'rw');
|
||||||
|
has 'min_print_speed' => (is => 'lazy');
|
||||||
|
|
||||||
|
sub _build_min_print_speed {
|
||||||
|
my $self = shift;
|
||||||
|
return 60 * $self->config->min_print_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub append {
|
||||||
|
my $self = shift;
|
||||||
|
my ($gcode, $layer) = @_;
|
||||||
|
|
||||||
|
my $return = "";
|
||||||
|
if (defined $self->last_z && $self->last_z != $layer->print_z) {
|
||||||
|
$return = $self->flush;
|
||||||
|
$self->gcodegen->elapsed_time(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
$self->layer_id($layer->id);
|
||||||
|
$self->last_z($layer->print_z);
|
||||||
|
$self->gcode($self->gcode . $gcode);
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub flush {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
my $gcode = $self->gcode;
|
||||||
|
$self->gcode("");
|
||||||
|
|
||||||
|
my $fan_speed = $self->config->fan_always_on ? $self->config->min_fan_speed : 0;
|
||||||
|
my $speed_factor = 1;
|
||||||
|
if ($self->config->cooling) {
|
||||||
|
my $layer_time = $self->gcodegen->elapsed_time;
|
||||||
|
Slic3r::debugf "Layer %d estimated printing time: %d seconds\n", $self->layer_id, $layer_time;
|
||||||
|
if ($layer_time < $self->config->slowdown_below_layer_time) {
|
||||||
|
$fan_speed = $self->config->max_fan_speed;
|
||||||
|
$speed_factor = $layer_time / $self->config->slowdown_below_layer_time;
|
||||||
|
} elsif ($layer_time < $self->config->fan_below_layer_time) {
|
||||||
|
$fan_speed = $self->config->max_fan_speed - ($self->config->max_fan_speed - $self->config->min_fan_speed)
|
||||||
|
* ($layer_time - $self->config->slowdown_below_layer_time)
|
||||||
|
/ ($self->config->fan_below_layer_time - $self->config->slowdown_below_layer_time); #/
|
||||||
|
}
|
||||||
|
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;
|
||||||
|
|
||||||
|
if ($speed_factor < 1) {
|
||||||
|
my $dec = $self->gcodegen->dec;
|
||||||
|
$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 < $self->min_print_speed ? $self->min_print_speed : $new_speed)
|
||||||
|
/gexm;
|
||||||
|
}
|
||||||
|
$fan_speed = 0 if $self->layer_id < $self->config->disable_fan_first_layers;
|
||||||
|
}
|
||||||
|
$gcode = $self->gcodegen->set_fan($fan_speed) . $gcode;
|
||||||
|
|
||||||
|
# bridge fan speed
|
||||||
|
if (!$self->config->cooling || $self->config->bridge_fan_speed == 0 || $self->layer_id < $self->config->disable_fan_first_layers) {
|
||||||
|
$gcode =~ s/^;_BRIDGE_FAN_(?:START|END)\n//gm;
|
||||||
|
} else {
|
||||||
|
$gcode =~ s/^;_BRIDGE_FAN_START\n/ $self->gcodegen->set_fan($self->config->bridge_fan_speed, 1) /gmex;
|
||||||
|
$gcode =~ s/^;_BRIDGE_FAN_END\n/ $self->gcodegen->set_fan($fan_speed, 1) /gmex;
|
||||||
|
}
|
||||||
|
$gcode =~ s/;_WIPE//g;
|
||||||
|
|
||||||
|
return $gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -716,8 +716,6 @@ sub write_gcode {
|
|||||||
multiple_extruders => (@{$self->extruders} > 1),
|
multiple_extruders => (@{$self->extruders} > 1),
|
||||||
layer_count => $self->layer_count,
|
layer_count => $self->layer_count,
|
||||||
);
|
);
|
||||||
my $min_print_speed = 60 * $Slic3r::Config->min_print_speed;
|
|
||||||
my $dec = $gcodegen->dec;
|
|
||||||
print $fh "G21 ; set units to millimeters\n";
|
print $fh "G21 ; set units to millimeters\n";
|
||||||
print $fh $gcodegen->set_fan(0, 1) if $Slic3r::Config->cooling && $Slic3r::Config->disable_fan_first_layers;
|
print $fh $gcodegen->set_fan(0, 1) if $Slic3r::Config->cooling && $Slic3r::Config->disable_fan_first_layers;
|
||||||
|
|
||||||
@ -801,7 +799,6 @@ sub write_gcode {
|
|||||||
|
|
||||||
# set new layer, but don't move Z as support material contact areas may need an intermediate one
|
# set new layer, but don't move Z as support material contact areas may need an intermediate one
|
||||||
$gcode .= $gcodegen->change_layer($layer);
|
$gcode .= $gcodegen->change_layer($layer);
|
||||||
$gcodegen->elapsed_time(0);
|
|
||||||
|
|
||||||
# prepare callback to call as soon as a Z command is generated
|
# prepare callback to call as soon as a Z command is generated
|
||||||
$gcodegen->move_z_callback(sub {
|
$gcodegen->move_z_callback(sub {
|
||||||
@ -943,42 +940,6 @@ sub write_gcode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if !$gcode;
|
|
||||||
|
|
||||||
my $fan_speed = $Slic3r::Config->fan_always_on ? $Slic3r::Config->min_fan_speed : 0;
|
|
||||||
my $speed_factor = 1;
|
|
||||||
if ($Slic3r::Config->cooling) {
|
|
||||||
my $layer_time = $gcodegen->elapsed_time;
|
|
||||||
Slic3r::debugf "Layer %d estimated printing time: %d seconds\n", $layer->id, $layer_time;
|
|
||||||
if ($layer_time < $Slic3r::Config->slowdown_below_layer_time) {
|
|
||||||
$fan_speed = $Slic3r::Config->max_fan_speed;
|
|
||||||
$speed_factor = $layer_time / $Slic3r::Config->slowdown_below_layer_time;
|
|
||||||
} elsif ($layer_time < $Slic3r::Config->fan_below_layer_time) {
|
|
||||||
$fan_speed = $Slic3r::Config->max_fan_speed - ($Slic3r::Config->max_fan_speed - $Slic3r::Config->min_fan_speed)
|
|
||||||
* ($layer_time - $Slic3r::Config->slowdown_below_layer_time)
|
|
||||||
/ ($Slic3r::Config->fan_below_layer_time - $Slic3r::Config->slowdown_below_layer_time); #/
|
|
||||||
}
|
|
||||||
Slic3r::debugf " fan = %d%%, speed = %d%%\n", $fan_speed, $speed_factor * 100;
|
|
||||||
|
|
||||||
if ($speed_factor < 1) {
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
$fan_speed = 0 if $layer->id < $Slic3r::Config->disable_fan_first_layers;
|
|
||||||
}
|
|
||||||
$gcode = $gcodegen->set_fan($fan_speed) . $gcode;
|
|
||||||
|
|
||||||
# bridge fan speed
|
|
||||||
if (!$Slic3r::Config->cooling || $Slic3r::Config->bridge_fan_speed == 0 || $layer->id < $Slic3r::Config->disable_fan_first_layers) {
|
|
||||||
$gcode =~ s/^;_BRIDGE_FAN_(?:START|END)\n//gm;
|
|
||||||
} else {
|
|
||||||
$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;
|
return $gcode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1001,6 +962,11 @@ sub write_gcode {
|
|||||||
print $fh $gcodegen->G0(Slic3r::Point->new(0,0), undef, 0, 'move to origin position for next object');
|
print $fh $gcodegen->G0(Slic3r::Point->new(0,0), undef, 0, 'move to origin position for next object');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $buffer = Slic3r::GCode::CoolingBuffer->new(
|
||||||
|
config => $Slic3r::Config,
|
||||||
|
gcodegen => $gcodegen,
|
||||||
|
);
|
||||||
|
|
||||||
for my $layer (@{$self->objects->[$obj_idx]->layers}) {
|
for my $layer (@{$self->objects->[$obj_idx]->layers}) {
|
||||||
# if we are printing the bottom layer of an object, and we have already finished
|
# if we are printing the bottom layer of an object, and we have already finished
|
||||||
# another one, set first layer temperatures. this happens before the Z move
|
# another one, set first layer temperatures. this happens before the Z move
|
||||||
@ -1010,15 +976,20 @@ sub write_gcode {
|
|||||||
if $Slic3r::Config->first_layer_bed_temperature;
|
if $Slic3r::Config->first_layer_bed_temperature;
|
||||||
$print_first_layer_temperature->();
|
$print_first_layer_temperature->();
|
||||||
}
|
}
|
||||||
print $fh $extrude_layer->($layer, [$copy]);
|
print $fh $buffer->append($extrude_layer->($layer, [$copy]), $layer);
|
||||||
}
|
}
|
||||||
|
print $fh $buffer->flush;
|
||||||
$finished_objects++;
|
$finished_objects++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print $fh $extrude_layer->($_, $_->object->copies)
|
my $buffer = Slic3r::GCode::CoolingBuffer->new(
|
||||||
for sort { $a->print_z <=> $b->print_z }
|
config => $Slic3r::Config,
|
||||||
map @{$_->layers}, @{$self->objects};
|
gcodegen => $gcodegen,
|
||||||
|
);
|
||||||
|
print $fh $buffer->append($extrude_layer->($_, $_->object->copies), $_)
|
||||||
|
for sort { $a->print_z <=> $b->print_z } map @{$_->layers}, @{$self->objects};
|
||||||
|
print $fh $buffer->flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
# save statistic data
|
# save statistic data
|
||||||
|
Loading…
Reference in New Issue
Block a user