mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-30 20:21:12 -06:00 
			
		
		
		
	Merge branch 'new-flow'
This commit is contained in:
		
						commit
						0aa3cc230f
					
				
					 4 changed files with 79 additions and 62 deletions
				
			
		|  | @ -725,8 +725,8 @@ sub validate { | |||
|     $Slic3r::support_material_flow = $Slic3r::extruders->[ $Slic3r::support_material_extruder-1 ] | ||||
|         ->make_flow(width => $Slic3r::support_material_extrusion_width || $Slic3r::extrusion_width); | ||||
|      | ||||
|     Slic3r::debugf "Default flow width = %s, spacing = %s, min_spacing = %s\n", | ||||
|         $Slic3r::flow->width, $Slic3r::flow->spacing, $Slic3r::flow->min_spacing; | ||||
|     Slic3r::debugf "Default flow width = %s (spacing = %s)\n", | ||||
|         $Slic3r::flow->width, $Slic3r::flow->spacing; | ||||
|      | ||||
|     # --perimeters | ||||
|     die "Invalid value for --perimeters\n" | ||||
|  |  | |||
|  | @ -3,21 +3,18 @@ use Moo; | |||
| 
 | ||||
| use Slic3r::Geometry qw(PI); | ||||
| 
 | ||||
| has 'nozzle_diameter'           => (is => 'rw', required => 1); | ||||
| has 'filament_diameter'         => (is => 'rw', required => 1); | ||||
| has 'extrusion_multiplier'      => (is => 'rw', required => 1); | ||||
| has 'temperature'               => (is => 'rw', required => 1); | ||||
| has 'nozzle_diameter'           => (is => 'ro', required => 1); | ||||
| has 'filament_diameter'         => (is => 'ro', required => 1); | ||||
| has 'extrusion_multiplier'      => (is => 'ro', required => 1); | ||||
| has 'temperature'               => (is => 'ro', required => 1); | ||||
| has 'first_layer_temperature'   => (is => 'rw', required => 1); | ||||
| 
 | ||||
| has 'e_per_mmc'             => (is => 'rw'); | ||||
| has 'e_per_mm3'                 => (is => 'lazy'); | ||||
| has '_mm3_per_mm_cache'         => (is => 'ro', default => sub {{}}); | ||||
| 
 | ||||
| sub BUILD { | ||||
| sub _build_e_per_mm3 { | ||||
|     my $self = shift; | ||||
|     $self->e_per_mmc( | ||||
|         $Slic3r::scaling_factor | ||||
|         * $self->extrusion_multiplier | ||||
|         * (4 / (($self->filament_diameter ** 2) * PI)) | ||||
|     ); | ||||
|     return $self->extrusion_multiplier * (4 / (($self->filament_diameter ** 2) * PI)); | ||||
| } | ||||
| 
 | ||||
| sub make_flow { | ||||
|  | @ -25,4 +22,26 @@ sub make_flow { | |||
|     return Slic3r::Flow->new(nozzle_diameter => $self->nozzle_diameter, @_); | ||||
| } | ||||
| 
 | ||||
| sub mm3_per_mm { | ||||
|     my $self = shift; | ||||
|     my ($s, $h) = @_; | ||||
|      | ||||
|     my $cache_key = "${s}_${h}"; | ||||
|     if (!exists $self->_mm3_per_mm_cache->{$cache_key}) { | ||||
|         my $w_threshold = $h + $self->nozzle_diameter; | ||||
|         my $s_threshold = $w_threshold - $Slic3r::overlap_factor * ($w_threshold - ($w_threshold - $h * (1 - PI/4))); | ||||
|          | ||||
|         if ($s >= $s_threshold) { | ||||
|             # rectangle with semicircles at the ends | ||||
|             my $w = $s + $Slic3r::overlap_factor * $h * (1 - PI/4); | ||||
|             $self->_mm3_per_mm_cache->{$cache_key} = $w * $h + ($h**2) / 4 * (PI - 4); | ||||
|         } else { | ||||
|             # rectangle with shrunk semicircles at the ends | ||||
|             my $w = ($s + $self->nozzle_diameter * $Slic3r::overlap_factor * (PI/4 - 1)) / (1 + $Slic3r::overlap_factor * (PI/4 - 1)); | ||||
|             $self->_mm3_per_mm_cache->{$cache_key} = $self->nozzle_diameter * $h * (1 - PI/4) + $h * $w * PI/4; | ||||
|         } | ||||
|     } | ||||
|     return $self->_mm3_per_mm_cache->{$cache_key}; | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
|  | @ -3,53 +3,56 @@ use Moo; | |||
| 
 | ||||
| use Slic3r::Geometry qw(PI); | ||||
| 
 | ||||
| has 'nozzle_diameter'   => (is => 'rw', required => 1); | ||||
| has 'layer_height'      => (is => 'rw', default => sub { $Slic3r::layer_height }); | ||||
| has 'nozzle_diameter'   => (is => 'ro', required => 1); | ||||
| has 'layer_height'      => (is => 'ro', default => sub { $Slic3r::layer_height }); | ||||
| 
 | ||||
| has 'width'             => (is => 'rw'); | ||||
| has 'min_spacing'       => (is => 'rw'); | ||||
| has 'spacing'           => (is => 'rw'); | ||||
| has 'width'             => (is => 'rwp', builder => 1); | ||||
| has 'spacing'           => (is => 'lazy'); | ||||
| 
 | ||||
| sub BUILD { | ||||
|     my $self = shift; | ||||
|      | ||||
|     my ($flow_width, $min_flow_spacing, $flow_spacing); | ||||
|     if ($self->width) { | ||||
|         $flow_width = $self->width =~ /^(\d+(?:\.\d+)?)%$/ | ||||
|             ? ($self->layer_height * $1 / 100) | ||||
|             : $self->width; | ||||
|     if ($self->width =~ /^(\d+(?:\.\d+)?)%$/) { | ||||
|         $self->_set_width($self->layer_height * $1 / 100); | ||||
|     } | ||||
|     $self->_set_width($self->_build_width) if $self->width == 0; # auto | ||||
| } | ||||
| 
 | ||||
| sub _build_width { | ||||
|     my $self = shift; | ||||
|      | ||||
|     # here we calculate a sane default by matching the flow speed (at the nozzle) and the feed rate | ||||
|     my $volume = ($self->nozzle_diameter**2) * PI/4; | ||||
|     my $shape_threshold = $self->nozzle_diameter * $self->layer_height + ($self->layer_height**2) * PI/4; | ||||
|     my $width; | ||||
|     if ($volume >= $shape_threshold) { | ||||
|         # rectangle with semicircles at the ends | ||||
|         $width = (($self->nozzle_diameter**2) * PI + ($self->layer_height**2) * (4 - PI)) / (4 * $self->layer_height); | ||||
|     } else { | ||||
|         # here we calculate a sane default by matching the flow speed (at the nozzle) | ||||
|         # and the feed rate | ||||
|         my $volume = ($self->nozzle_diameter**2) * PI/4; | ||||
|         my $shape_threshold = $self->nozzle_diameter * $self->layer_height | ||||
|             + ($self->layer_height**2) * PI/4; | ||||
|         if ($volume >= $shape_threshold) { | ||||
|             # rectangle with semicircles at the ends | ||||
|             $flow_width = (($self->nozzle_diameter**2) * PI + ($self->layer_height**2) * (4 - PI)) / (4 * $self->layer_height); | ||||
|         } else { | ||||
|             # rectangle with squished semicircles at the ends | ||||
|             $flow_width = $self->nozzle_diameter * ($self->nozzle_diameter/$self->layer_height - 4/PI + 1); | ||||
|         } | ||||
|          | ||||
|         my $min_flow_width = $self->nozzle_diameter * 1.05; | ||||
|         my $max_flow_width = $self->nozzle_diameter * 1.4; | ||||
|         $flow_width = $max_flow_width if $flow_width > $max_flow_width; | ||||
|         $flow_width = $min_flow_width if $flow_width < $min_flow_width; | ||||
|         # rectangle with squished semicircles at the ends | ||||
|         $width = $self->nozzle_diameter * ($self->nozzle_diameter/$self->layer_height - 4/PI + 1); | ||||
|     } | ||||
|      | ||||
|     if ($flow_width >= ($self->nozzle_diameter + $self->layer_height)) { | ||||
|     my $min = $self->nozzle_diameter * 1.05; | ||||
|     my $max = $self->nozzle_diameter * 1.4; | ||||
|     $width = $max if $width > $max; | ||||
|     $width = $min if $width < $min; | ||||
|      | ||||
|     return $width; | ||||
| } | ||||
| 
 | ||||
| sub _build_spacing { | ||||
|     my $self = shift; | ||||
|      | ||||
|     my $min_flow_spacing; | ||||
|     if ($self->width >= ($self->nozzle_diameter + $self->layer_height)) { | ||||
|         # rectangle with semicircles at the ends | ||||
|         $min_flow_spacing = $flow_width - $self->layer_height * (1 - PI/4); | ||||
|         $min_flow_spacing = $self->width - $self->layer_height * (1 - PI/4); | ||||
|     } else { | ||||
|         # rectangle with shrunk semicircles at the ends | ||||
|         $min_flow_spacing = $flow_width * (1 - PI/4) + $self->nozzle_diameter * PI/4; | ||||
|         $min_flow_spacing = $self->nozzle_diameter * (1 - PI/4) + $self->width * PI/4; | ||||
|     } | ||||
|     $flow_spacing = $flow_width - $Slic3r::overlap_factor * ($flow_width - $min_flow_spacing); | ||||
|      | ||||
|     $self->width($flow_width); | ||||
|     $self->min_spacing($min_flow_spacing); | ||||
|     $self->spacing($flow_spacing); | ||||
|     return $self->width - $Slic3r::overlap_factor * ($self->width - $min_flow_spacing); | ||||
| } | ||||
| 
 | ||||
| 1; | ||||
|  |  | |||
|  | @ -157,23 +157,18 @@ sub extrude_path { | |||
|     # compensate retraction | ||||
|     $gcode .= $self->unretract if $self->retracted; | ||||
|      | ||||
|     # calculate extrusion length per distance unit | ||||
|     my $s = $path->flow_spacing || ($self->layer ? $self->layer->flow->spacing : $Slic3r::flow->spacing); | ||||
|     my $h = $path->depth_layers * $self->layer->height; | ||||
|     my $w = ($s - ($self->layer ? $self->layer->flow->min_spacing : $Slic3r::flow->min_spacing) * $Slic3r::overlap_factor) / (1 - $Slic3r::overlap_factor); | ||||
|      | ||||
|     my $area; | ||||
|     my $area;  # mm^3 of extrudate per mm of tool movement  | ||||
|     if ($path->role == EXTR_ROLE_BRIDGE) { | ||||
|         my $s = $path->flow_spacing || $self->extruder->nozzle_diameter; | ||||
|         $area = ($s**2) * PI/4; | ||||
|     } elsif ($w >= ($self->extruder->nozzle_diameter + $h)) { | ||||
|         # rectangle with semicircles at the ends | ||||
|         $area = $w * $h + ($h**2) / 4 * (PI - 4); | ||||
|     } else { | ||||
|         # rectangle with shrunk semicircles at the ends | ||||
|         $area = $self->extruder->nozzle_diameter * $h * (1 - PI/4) + $h * $w * PI/4; | ||||
|         my $s = $path->flow_spacing || ($self->layer ? $self->layer->flow->spacing : $Slic3r::flow->spacing); | ||||
|         my $h = $path->depth_layers * $self->layer->height; | ||||
|         $area = $self->extruder->mm3_per_mm($s, $h); | ||||
|     } | ||||
|      | ||||
|     my $e = $self->extruder->e_per_mmc * $area; | ||||
|     # calculate extrusion length per distance unit | ||||
|     my $e = $self->extruder->e_per_mm3 * $area; | ||||
|      | ||||
|     # extrude arc or line | ||||
|     $self->speed( $role_speeds{$path->role} || die "Unknown role: " . $path->role ); | ||||
|  | @ -181,12 +176,12 @@ sub extrude_path { | |||
|     if ($path->isa('Slic3r::ExtrusionPath::Arc')) { | ||||
|         $path_length = $path->length; | ||||
|         $gcode .= $self->G2_G3($path->points->[-1], $path->orientation,  | ||||
|             $path->center, $e * $path_length, $description); | ||||
|             $path->center, $e * unscale $path_length, $description); | ||||
|     } else { | ||||
|         foreach my $line ($path->lines) { | ||||
|             my $line_length = $line->length; | ||||
|             $path_length += $line_length; | ||||
|             $gcode .= $self->G1($line->b, undef, $e * $line_length, $description); | ||||
|             $gcode .= $self->G1($line->b, undef, $e * unscale $line_length, $description); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Alessandro Ranellucci
						Alessandro Ranellucci