mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			95 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			95 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| use Test::More tests => 9;
 | ||
| use strict;
 | ||
| use warnings;
 | ||
| 
 | ||
| BEGIN {
 | ||
|     use FindBin;
 | ||
|     use lib "$FindBin::Bin/../lib";
 | ||
| }
 | ||
| 
 | ||
| use Slic3r;
 | ||
| use Slic3r::Geometry qw(epsilon);
 | ||
| use Slic3r::Test;
 | ||
| 
 | ||
| my $config = Slic3r::Config->new_from_defaults;
 | ||
| 
 | ||
| # tolerance, in minutes
 | ||
| # (our time estimation differs from the internal one because of decimals truncation)
 | ||
| my $epsilon = 0.002;
 | ||
| 
 | ||
| my $test = sub {
 | ||
|     my ($conf) = @_;
 | ||
|     $conf ||= $config;
 | ||
|     
 | ||
|     my $print = Slic3r::Test::init_print('2x20x10', config => $conf);
 | ||
|     
 | ||
|     my $min_time        = 1 / ($conf->vibration_limit * 60);  # minimum time between direction changes in minutes
 | ||
|     my %dir             = (X => 0, Y => 0);
 | ||
|     my %dir_time        = (X => 0, Y => 0);
 | ||
|     my %dir_sleep_time  = (X => 0, Y => 0);
 | ||
|     my $last_cmd_pause  = 0;
 | ||
|     Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub {
 | ||
|         my ($self, $cmd, $args, $info) = @_;
 | ||
|         
 | ||
|         if ($cmd !~ /^G[01]$/) {
 | ||
|             if ($cmd eq 'G4') {
 | ||
|                 $last_cmd_pause = (($args->{P} // 0) / 1000 + ($args->{S} // 0)) / 60;  # in minutes
 | ||
|                 $dir_sleep_time{$_} += $last_cmd_pause for qw(X Y);
 | ||
|                 $last_cmd_pause -= $epsilon;  # error builds up
 | ||
|             }
 | ||
|             return;
 | ||
|         }
 | ||
|         
 | ||
|         # Z moves are slow enough that we can consider any vibration interrupted
 | ||
|         if ($info->{dist_Z}) {
 | ||
|             $dir_time{$_} += 99999 for qw(X Y);
 | ||
|             $last_cmd_pause = 0;
 | ||
|             return;
 | ||
|         } elsif ($info->{dist_E} != 0 && $info->{dist_XY} == 0) {
 | ||
|             my $time = abs($info->{dist_E}) / ($args->{F} // $self->F);  # in minutes
 | ||
|             $dir_time{$_} += $time for qw(X Y);
 | ||
|             $last_cmd_pause = 0;
 | ||
|             return;
 | ||
|         }
 | ||
|         
 | ||
|         # compute move time (this assumes that the speed is XY-bound, which happens very likely)
 | ||
|         my $time = abs($info->{dist_XY}) / ($args->{F} // $self->F);  # in minutes
 | ||
|         
 | ||
|         my $one_axis_would_trigger_limit_without_pause = 0;
 | ||
|         foreach my $axis (qw(X Y)) {
 | ||
|             # are we changing direction on this axis?
 | ||
|             my $dir = $info->{"dist_$axis"} <=> ($args->{$axis} // $self->$axis);
 | ||
|             if ($dir != 0 && $dir{$axis} != $dir) {
 | ||
|                 # this move changes direction on this axis
 | ||
|                 if ($dir{$axis} != 0) {
 | ||
|                     if (($dir_time{$axis} + $dir_sleep_time{$axis}) < ($min_time - $epsilon)) {
 | ||
|                         fail 'vibration limit exceeded';
 | ||
|                     }
 | ||
|                     $one_axis_would_trigger_limit_without_pause = 1
 | ||
|                         if ($dir_time{$axis} - $last_cmd_pause) < $min_time;
 | ||
|                 }
 | ||
|                 $dir{$axis}             = $dir;
 | ||
|                 $dir_time{$axis}        = 0;
 | ||
|                 $dir_sleep_time{$axis}  = 0;
 | ||
|             }
 | ||
|             $dir_time{$axis} += $time;
 | ||
|         }
 | ||
|         fail 'no unnecessary pauses are added'
 | ||
|             if $last_cmd_pause > $epsilon && !$one_axis_would_trigger_limit_without_pause;
 | ||
|         
 | ||
|         $last_cmd_pause = 0;
 | ||
|     });
 | ||
|     
 | ||
|     1;
 | ||
| };
 | ||
| 
 | ||
| $config->set('gcode_comments', 1);
 | ||
| $config->set('perimeters', 1);
 | ||
| foreach my $frequency (5, 10, 15) {
 | ||
|     foreach my $gapfillspeed (20, 50, 100) {
 | ||
|         $config->set('vibration_limit', $frequency);
 | ||
|         ok $test->(), "vibrations limited to ${frequency}Hz (gap fill speed = ${gapfillspeed} mm/s)";
 | ||
|     }
 | ||
| }
 | ||
| 
 | ||
| __END__
 | 
