mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-23 06:33:57 -06:00
Working implementation of frequency limit
This commit is contained in:
parent
f3164594eb
commit
008633f013
1 changed files with 35 additions and 36 deletions
|
@ -1,7 +1,7 @@
|
||||||
package Slic3r::GCode;
|
package Slic3r::GCode;
|
||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use List::Util qw(min first);
|
use List::Util qw(min max first);
|
||||||
use Slic3r::ExtrusionPath ':roles';
|
use Slic3r::ExtrusionPath ':roles';
|
||||||
use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y A B);
|
use Slic3r::Geometry qw(scale unscale scaled_epsilon points_coincide PI X Y A B);
|
||||||
|
|
||||||
|
@ -477,14 +477,15 @@ sub limit_frequency {
|
||||||
|
|
||||||
my $current_gcode = $gcode;
|
my $current_gcode = $gcode;
|
||||||
$gcode = '';
|
$gcode = '';
|
||||||
my %last;
|
|
||||||
my $F;
|
# the following code is inspired by Marlin frequency limit implementation
|
||||||
|
|
||||||
my $min_time = 1 / ($Slic3r::Config->vibration_limit * 60);
|
my $min_time = 1 / ($Slic3r::Config->vibration_limit * 60);
|
||||||
my @buffer = ();
|
my @axes = qw(X Y);
|
||||||
my %last_dir = ();
|
my %segment_time = (map { $_ => [0,0,0] } @axes);
|
||||||
my %time = ();
|
my %last = (map { $_ => 0 } @axes);
|
||||||
my @axes = qw(X Y E);
|
my %last_dir = (map { $_ => 0 } @axes);
|
||||||
|
my $F;
|
||||||
|
|
||||||
foreach my $line (split /\n/, $current_gcode) {
|
foreach my $line (split /\n/, $current_gcode) {
|
||||||
if ($line =~ /^G[01] /) {
|
if ($line =~ /^G[01] /) {
|
||||||
|
@ -502,52 +503,50 @@ sub limit_frequency {
|
||||||
|
|
||||||
# check move directions
|
# check move directions
|
||||||
my %dir = (
|
my %dir = (
|
||||||
map { $_ => ($move{$_}) ? ($move{$_} > 0 ? 1 : -1) : undef } @axes
|
map { $_ => ($move{$_}) ? ($move{$_} > 0 ? 1 : -1) : 0 } @axes
|
||||||
);
|
);
|
||||||
|
|
||||||
my @slowdown = ();
|
my $factor = 1;
|
||||||
foreach my $axis (@axes) {
|
my $segment_time = abs(max(values %move)) / ($f // $F);
|
||||||
# are we changing direction on this axis?
|
if ($segment_time > 0) {
|
||||||
# (actually: are we going positive while last move was negative?)
|
my %max_segment_time = ();
|
||||||
if (($last_dir{$axis} // 0) < 0 && ($dir{$axis} // 0) > 0) {
|
foreach my $axis (@axes) {
|
||||||
# changing direction on this axis!
|
# are we changing direction on this axis?
|
||||||
if (defined $time{$axis} && $time{$axis} < $min_time) {
|
if ($last_dir{$axis} == $dir{$axis}) {
|
||||||
# direction change was too fast! we need to slow down
|
$segment_time{$axis}[0] += $segment_time;
|
||||||
push @slowdown, $time{$axis} / $min_time;
|
} else {
|
||||||
|
@{ $segment_time{$axis} } = ($segment_time, @{ $segment_time{$axis} }[0,1]);
|
||||||
}
|
}
|
||||||
$time{$axis} = 0;
|
|
||||||
} elsif ($move{$axis}) {
|
$max_segment_time{$axis} = max($segment_time{$axis}[0], max($segment_time{$axis}[1], $segment_time{$axis}[2]));
|
||||||
# not changing direction on this axis
|
}
|
||||||
# then just calculate move time and sum it
|
|
||||||
$time{$axis} //= 0;
|
my $min_segment_time = min(values %max_segment_time);
|
||||||
$time{$axis} += abs($move{$axis}) / ($f // $F);
|
if ($min_segment_time < $min_time) {
|
||||||
|
$factor = $min_segment_time / $min_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (@slowdown) {
|
|
||||||
my $factor = min(@slowdown);
|
if ($factor == 1) {
|
||||||
printf "SLOWDOWN! (slowdown = %d%%)\n", $factor * 100;
|
|
||||||
$gcode .= "; START SLOWDOWN ($factor)\n";
|
|
||||||
$gcode .= "$_\n" for @buffer;
|
|
||||||
@buffer = ();
|
|
||||||
$gcode .= "; END SLOWDOWN\n";
|
|
||||||
$gcode .= "$line\n";
|
$gcode .= "$line\n";
|
||||||
} else {
|
} else {
|
||||||
push @buffer, $line;
|
$line =~ s/ F[0-9.]+//;
|
||||||
|
my $new_speed = sprintf '%.3f', ($f // $F) * $factor;
|
||||||
|
$line =~ s/^(G[01]) /$1 F$new_speed /;
|
||||||
|
$gcode .= "$line\nG1 F" . ($f // $F) . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (@axes) {
|
for (@axes) {
|
||||||
$last{$_} = $cur{$_} if defined $cur{$_};
|
$last{$_} = $cur{$_} if $cur{$_};
|
||||||
$last_dir{$_} = $dir{$_} if defined $dir{$_};
|
$last_dir{$_} = $dir{$_} if $dir{$_};
|
||||||
}
|
}
|
||||||
$F = $f if defined $f;
|
$F = $f if defined $f;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
push @buffer, $line;
|
$gcode .= "$line\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$gcode .= "$_\n" for @buffer;
|
|
||||||
|
|
||||||
return $gcode;
|
return $gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue