mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 12:11:15 -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; | ||||
|  | @ -894,7 +894,7 @@ sub build { | |||
|     $self->init_config_options(qw( | ||||
|         bed_shape z_offset | ||||
|         gcode_flavor use_relative_e_distances | ||||
|         use_firmware_retraction vibration_limit | ||||
|         use_firmware_retraction pressure_advance vibration_limit | ||||
|         start_gcode end_gcode layer_gcode toolchange_gcode | ||||
|         nozzle_diameter extruder_offset | ||||
|         retract_length retract_lift retract_speed retract_restart_extra retract_before_travel retract_layer_change wipe | ||||
|  | @ -970,6 +970,7 @@ sub build { | |||
|         { | ||||
|             my $optgroup = $page->new_optgroup('Advanced'); | ||||
|             $optgroup->append_single_option_line('use_firmware_retraction'); | ||||
|             $optgroup->append_single_option_line('pressure_advance'); | ||||
|             $optgroup->append_single_option_line('vibration_limit'); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -667,7 +667,7 @@ sub write_gcode { | |||
|     } | ||||
|      | ||||
|     # write end commands to file | ||||
|     print $fh $gcodegen->retract; | ||||
|     print $fh $gcodegen->retract;   # TODO: process this retract through PressureRegulator in order to discharge fully | ||||
|     print $fh $gcodegen->writer->set_fan(0); | ||||
|     printf $fh "%s\n", $gcodegen->placeholder_parser->process($self->config->end_gcode); | ||||
|     print $fh $gcodegen->writer->update_progress($gcodegen->layer_count, $gcodegen->layer_count, 1);  # 100% | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci