mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			3.5 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| 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 '_last_print_F'     => (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, $flush) = @_;
 | |
|     
 | |
|     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.
 | |
|             my $F = $args->{F} // $reader->F;
 | |
|             if ($F != $self->_last_print_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 * $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);
 | |
|                 }
 | |
|                 
 | |
|                 $self->_last_print_F($F);
 | |
|             }
 | |
|         } elsif (($info->{retracting} || $cmd eq 'G10') && $self->_advance != 0) {
 | |
|             # We need to bring pressure to zero when retracting.
 | |
|             $new_gcode .= $self->_discharge($args->{F});
 | |
|         }
 | |
|         
 | |
|         $new_gcode .= "$info->{raw}\n";
 | |
|     });
 | |
|     
 | |
|     if ($flush) {
 | |
|         $new_gcode .= $self->_discharge;
 | |
|     }
 | |
|     
 | |
|     return $new_gcode;
 | |
| }
 | |
| 
 | |
| sub _discharge {
 | |
|     my ($self, $F) = @_;
 | |
|     
 | |
|     my $new_E = ($self->config->use_relative_e_distances ? 0 : $self->reader->E) - $self->_advance;
 | |
|     my $gcode = sprintf "G1 %s%.5f F%.3f ; pressure discharge\n",
 | |
|         $self->_extrusion_axis, $new_E, $F // $self->_unretract_speed;
 | |
|     $gcode .= sprintf "G92 %s%.5f ; restore E\n", $self->_extrusion_axis, $self->reader->E
 | |
|         if !$self->config->use_relative_e_distances;
 | |
|     $self->_advance(0);
 | |
|     
 | |
|     return $gcode;
 | |
| }
 | |
| 
 | |
| sub _unretract_speed {
 | |
|     my ($self) = @_;
 | |
|     return $self->config->get_at('retract_speed', $self->_tool) * 60;
 | |
| }
 | |
| 
 | |
| 1;
 | 
