mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			64 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			64 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| package Slic3r::GCode::VibrationLimit;
 | |
| use Moo;
 | |
| 
 | |
| extends 'Slic3r::GCode::Reader';
 | |
| 
 | |
| has 'config'    => (is => 'ro', required => 1);
 | |
| has '_min_time' => (is => 'lazy');
 | |
| has '_last_dir' => (is => 'ro', default => sub { [0,0] });
 | |
| has '_dir_time' => (is => 'ro', default => sub { [0,0] });
 | |
| 
 | |
| # inspired by http://hydraraptor.blogspot.it/2010/12/frequency-limit.html
 | |
| 
 | |
| use List::Util qw(max);
 | |
| use Slic3r::Geometry qw(X Y);
 | |
| 
 | |
| sub _build__min_time {
 | |
|     my ($self) = @_;
 | |
|     return 1 / ($self->config->vibration_limit * 60);  # in minutes
 | |
| }
 | |
| 
 | |
| sub process {
 | |
|     my $self = shift;
 | |
|     my ($gcode) = @_;
 | |
|     
 | |
|     my $new_gcode = "";
 | |
|     $self->parse($gcode, sub {
 | |
|         my ($reader, $cmd, $args, $info) = @_;
 | |
|         
 | |
|         if ($cmd eq 'G1' && $info->{dist_XY} > 0) {
 | |
|             my $point = Slic3r::Point->new($args->{X} // $reader->X, $args->{Y} // $reader->Y);
 | |
|             my @dir = (
 | |
|                 ($point->x <=> $reader->X),
 | |
|                 ($point->y <=> $reader->Y),   #$
 | |
|             );
 | |
|             my $time = $info->{dist_XY} / ($args->{F} // $reader->F);  # in minutes
 | |
|             if ($time > 0) {
 | |
|                 my @pause = ();
 | |
|                 foreach my $axis (X,Y) {
 | |
|                     if ($dir[$axis] != 0 && $self->_last_dir->[$axis] != $dir[$axis]) {
 | |
|                         if ($self->_last_dir->[$axis] != 0) {
 | |
|                             # this axis is changing direction: check whether we need to pause
 | |
|                             if ($self->_dir_time->[$axis] < $self->_min_time) {
 | |
|                                 push @pause, ($self->_min_time - $self->_dir_time->[$axis]);
 | |
|                             }
 | |
|                         }
 | |
|                         $self->_last_dir->[$axis] = $dir[$axis];
 | |
|                         $self->_dir_time->[$axis] = 0;
 | |
|                     }
 | |
|                     $self->_dir_time->[$axis] += $time;
 | |
|                 }
 | |
|                 
 | |
|                 if (@pause) {
 | |
|                     $new_gcode .= sprintf "G4 P%d\n", max(@pause) * 60 * 1000;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         $new_gcode .= $info->{raw} . "\n";
 | |
|     });
 | |
|     
 | |
|     return $new_gcode;
 | |
| }
 | |
| 
 | |
| 1;
 | 
