mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-18 20:28:08 -06:00
New experimental feature for pressure management. Credits to @llluis for the original implementation. #1203 #1677 #2018
This commit is contained in:
parent
5a382f0200
commit
ff9b53260d
9 changed files with 108 additions and 2 deletions
|
@ -11,6 +11,7 @@ has 'origin' => (is => 'ro', default => sub { Slic3r::Poi
|
|||
has 'spiralvase' => (is => 'lazy');
|
||||
has 'vibration_limit' => (is => 'lazy');
|
||||
has 'arc_fitting' => (is => 'lazy');
|
||||
has 'pressure_regulator' => (is => 'lazy');
|
||||
has 'skirt_done' => (is => 'rw', default => sub { {} }); # print_z => 1
|
||||
has 'brim_done' => (is => 'rw');
|
||||
has 'second_layer_things_done' => (is => 'rw');
|
||||
|
@ -40,6 +41,14 @@ sub _build_arc_fitting {
|
|||
: undef;
|
||||
}
|
||||
|
||||
sub _build_pressure_regulator {
|
||||
my $self = shift;
|
||||
|
||||
return $self->print->config->pressure_advance > 0
|
||||
? Slic3r::GCode::PressureRegulator->new(config => $self->print->config)
|
||||
: undef;
|
||||
}
|
||||
|
||||
sub process_layer {
|
||||
my $self = shift;
|
||||
my ($layer, $object_copies) = @_;
|
||||
|
@ -197,6 +206,10 @@ sub process_layer {
|
|||
$gcode = $self->vibration_limit->process($gcode)
|
||||
if $self->print->config->vibration_limit != 0;
|
||||
|
||||
# apply pressure regulation if enabled
|
||||
$gcode = $self->pressure_regulator->process($gcode)
|
||||
if $self->print->config->pressure_advance > 0;
|
||||
|
||||
# apply arc fitting if enabled
|
||||
$gcode = $self->arc_fitting->process($gcode)
|
||||
if $self->print->config->gcode_arcs;
|
||||
|
|
78
lib/Slic3r/GCode/PressureRegulator.pm
Normal file
78
lib/Slic3r/GCode/PressureRegulator.pm
Normal file
|
@ -0,0 +1,78 @@
|
|||
package Slic3r::GCode::PressureRegulator;
|
||||
use Moo;
|
||||
|
||||
has 'config' => (is => 'ro', required => 1);
|
||||
has 'enable' => (is => 'rw', default => sub { 0 });
|
||||
has 'reader' => (is => 'ro', default => sub { Slic3r::GCode::Reader->new });
|
||||
has '_extrusion_axis' => (is => 'rw', default => sub { "E" });
|
||||
has '_tool' => (is => 'rw', default => sub { 0 });
|
||||
has '_advance' => (is => 'rw', default => sub { 0 }); # extra E injected
|
||||
|
||||
use Slic3r::Geometry qw(epsilon);
|
||||
|
||||
# Acknowledgements:
|
||||
# The advance algorithm was proposed by Matthew Roberts.
|
||||
# The initial work on this Slic3r feature was done by Luís Andrade (lluis)
|
||||
|
||||
sub BUILD {
|
||||
my ($self) = @_;
|
||||
|
||||
$self->reader->apply_print_config($self->config);
|
||||
$self->_extrusion_axis($self->config->get_extrusion_axis);
|
||||
}
|
||||
|
||||
sub process {
|
||||
my $self = shift;
|
||||
my ($gcode) = @_;
|
||||
|
||||
my $new_gcode = "";
|
||||
|
||||
$self->reader->parse($gcode, sub {
|
||||
my ($reader, $cmd, $args, $info) = @_;
|
||||
|
||||
if ($cmd =~ /^T(\d+)/) {
|
||||
$self->_tool($1);
|
||||
} elsif ($info->{extruding} && $info->{dist_XY} > 0) {
|
||||
# This is a print move.
|
||||
if (exists $args->{F}) {
|
||||
# We are setting a (potentially) new speed, so we calculate the new advance amount.
|
||||
|
||||
# First calculate relative flow rate (mm of filament over mm of travel)
|
||||
my $rel_flow_rate = $info->{dist_E} / $info->{dist_XY};
|
||||
|
||||
# Then calculate absolute flow rate (mm/sec of feedstock)
|
||||
my $flow_rate = $rel_flow_rate * $args->{F} / 60;
|
||||
|
||||
# And finally calculate advance by using the user-configured K factor.
|
||||
my $new_advance = $self->config->pressure_advance * ($flow_rate**2);
|
||||
|
||||
if (abs($new_advance - $self->_advance) > 1E-5) {
|
||||
my $new_E = ($self->config->use_relative_e_distances ? 0 : $reader->E) + ($new_advance - $self->_advance);
|
||||
$new_gcode .= sprintf "G1 %s%.5f F%.3f ; pressure advance\n",
|
||||
$self->_extrusion_axis, $new_E, $self->unretract_speed;
|
||||
$new_gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $reader->E
|
||||
if !$self->config->use_relative_e_distances;
|
||||
$self->_advance($new_advance);
|
||||
}
|
||||
}
|
||||
} elsif (($info->{retracting} || $cmd eq 'G10') && $self->_advance != 0) {
|
||||
# We need to bring pressure to zero when retracting.
|
||||
my $new_E = ($self->config->use_relative_e_distances ? 0 : $reader->E) - $self->_advance;
|
||||
$new_gcode .= sprintf "G1 %s%.5f F%.3f ; pressure discharge\n",
|
||||
$self->_extrusion_axis, $new_E, $args->{F} // $self->unretract_speed;
|
||||
$new_gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $reader->E
|
||||
if !$self->config->use_relative_e_distances;
|
||||
}
|
||||
|
||||
$new_gcode .= "$info->{raw}\n";
|
||||
});
|
||||
|
||||
return $new_gcode;
|
||||
}
|
||||
|
||||
sub unretract_speed {
|
||||
my ($self) = @_;
|
||||
return $self->config->get_at('retract_speed', $self->_tool) * 60;
|
||||
}
|
||||
|
||||
1;
|
Loading…
Add table
Add a link
Reference in a new issue