More incomplete work
This commit is contained in:
parent
72007c4f6a
commit
f3164594eb
2 changed files with 53 additions and 70 deletions
|
@ -1,7 +1,7 @@
|
||||||
package Slic3r::GCode;
|
package Slic3r::GCode;
|
||||||
use Moo;
|
use Moo;
|
||||||
|
|
||||||
use List::Util qw(first);
|
use List::Util qw(min 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,94 +477,77 @@ sub limit_frequency {
|
||||||
|
|
||||||
my $current_gcode = $gcode;
|
my $current_gcode = $gcode;
|
||||||
$gcode = '';
|
$gcode = '';
|
||||||
my ($X, $Y, $F);
|
my %last;
|
||||||
my @last_moves = ();
|
my $F;
|
||||||
my $longest_move;
|
|
||||||
my $buffer = '';
|
|
||||||
my $vibration_limit_min = $Slic3r::Config->vibration_limit * 60;
|
|
||||||
|
|
||||||
my $flush_buffer = sub {
|
my $min_time = 1 / ($Slic3r::Config->vibration_limit * 60);
|
||||||
my ($line) = @_;
|
my @buffer = ();
|
||||||
|
my %last_dir = ();
|
||||||
if (@last_moves >= 3) {
|
my %time = ();
|
||||||
$buffer =~ s/ F[0-9.]+//g;
|
my @axes = qw(X Y E);
|
||||||
my $new_speed = $vibration_limit_min * $longest_move;
|
|
||||||
$gcode .= "G1 F$new_speed ; limit vibrations\n";
|
|
||||||
$gcode .= $buffer;
|
|
||||||
$gcode .= "G1 F$F; restore previous speed\n";
|
|
||||||
} else {
|
|
||||||
$gcode .= $buffer;
|
|
||||||
}
|
|
||||||
$gcode .= "$line\n";
|
|
||||||
@last_moves = ();
|
|
||||||
$buffer = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
my $append_to_buffer = sub {
|
|
||||||
my ($line, $move, $freq) = @_;
|
|
||||||
|
|
||||||
###printf "move x = %s, y = %s\n", map $_ // '/', @$move[X,Y];
|
|
||||||
###printf " freq x = %s, y = %s\n", map $_ // '/', @$freq[X,Y];
|
|
||||||
|
|
||||||
$buffer .= "$line\n";
|
|
||||||
push @last_moves, [ map $freq->[$_] ? $_ : undef, @$move ];
|
|
||||||
for (grep defined $freq->[$_], X,Y) {
|
|
||||||
$longest_move = abs($move->[$_]) if $move->[$_] && (!defined $longest_move || abs($move->[$_]) > $longest_move);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach my $line (split /\n/, $current_gcode) {
|
foreach my $line (split /\n/, $current_gcode) {
|
||||||
if ($line =~ /^G[01] /) {
|
if ($line =~ /^G[01] /) {
|
||||||
my ($x, $y, $f);
|
my %cur;
|
||||||
$x = $1 if $line =~ /X([0-9.]+)/;
|
my $f;
|
||||||
$y = $1 if $line =~ /Y([0-9.]+)/;
|
for (@axes) {
|
||||||
|
$cur{$_} = $1 if $line =~ /$_([0-9.]+)/;
|
||||||
|
}
|
||||||
$f = $1 if $line =~ /F([0-9.]+)/;
|
$f = $1 if $line =~ /F([0-9.]+)/;
|
||||||
|
|
||||||
# calculate the move vector
|
# calculate the move vector
|
||||||
my @move = (
|
my %move = (
|
||||||
(defined $x && $X) ? ($x - $X) : 0,
|
map { $_ => (defined $cur{$_} && defined $last{$_}) ? ($cur{$_} - $last{$_}) : 0 } @axes
|
||||||
(defined $y && $Y) ? ($x - $Y) : 0,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
# calculate the frequency (how many times the move can happen in one minute) for each axis
|
# check move directions
|
||||||
# and only keep it for the axes exceeding the configured limit.
|
my %dir = (
|
||||||
# (undef = infinite)
|
map { $_ => ($move{$_}) ? ($move{$_} > 0 ? 1 : -1) : undef } @axes
|
||||||
my @freq = ();
|
);
|
||||||
for (X,Y) {
|
|
||||||
next if !$move[$_];
|
|
||||||
my $freq = ($f // $F) / abs($move[$_]);
|
|
||||||
$freq[$_] = $freq if $freq >= $vibration_limit_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
# does our move exceed the limit?
|
my @slowdown = ();
|
||||||
if (grep defined $_, @freq) {
|
foreach my $axis (@axes) {
|
||||||
# if so, do we have a buffer already?
|
# are we changing direction on this axis?
|
||||||
if (@last_moves) {
|
# (actually: are we going positive while last move was negative?)
|
||||||
# if we have a buffer, compare the direction (for each axis) with the previous one.
|
if (($last_dir{$axis} // 0) < 0 && ($dir{$axis} // 0) > 0) {
|
||||||
if (($move[X] // 0) * ($last_moves[-1][X] // 0) < 0 || ($move[Y] // 0) * ($last_moves[-1][Y] // 0) < 0 && ($f // $F) == $F) {
|
# changing direction on this axis!
|
||||||
# this move has opposite direction on at least one axis, and has also same speed:
|
if (defined $time{$axis} && $time{$axis} < $min_time) {
|
||||||
# we can add it to the buffer
|
# direction change was too fast! we need to slow down
|
||||||
$append_to_buffer->($line, \@move, \@freq);
|
push @slowdown, $time{$axis} / $min_time;
|
||||||
} else {
|
|
||||||
$flush_buffer->($line);
|
|
||||||
}
|
}
|
||||||
} else {
|
$time{$axis} = 0;
|
||||||
# if we have no buffer, store this move inside it
|
} elsif ($move{$axis}) {
|
||||||
$append_to_buffer->($line, \@move, \@freq);
|
# not changing direction on this axis
|
||||||
|
# then just calculate move time and sum it
|
||||||
|
$time{$axis} //= 0;
|
||||||
|
$time{$axis} += abs($move{$axis}) / ($f // $F);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (@slowdown) {
|
||||||
|
my $factor = min(@slowdown);
|
||||||
|
printf "SLOWDOWN! (slowdown = %d%%)\n", $factor * 100;
|
||||||
|
$gcode .= "; START SLOWDOWN ($factor)\n";
|
||||||
|
$gcode .= "$_\n" for @buffer;
|
||||||
|
@buffer = ();
|
||||||
|
$gcode .= "; END SLOWDOWN\n";
|
||||||
|
$gcode .= "$line\n";
|
||||||
} else {
|
} else {
|
||||||
# if the move does not exceed any limit, flush the buffer and output this line
|
push @buffer, $line;
|
||||||
$flush_buffer->($line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$X = $x if defined $x;
|
for (@axes) {
|
||||||
$Y = $y if defined $y;
|
$last{$_} = $cur{$_} if defined $cur{$_};
|
||||||
|
$last_dir{$_} = $dir{$_} if defined $dir{$_};
|
||||||
|
}
|
||||||
$F = $f if defined $f;
|
$F = $f if defined $f;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$gcode .= "$line\n";
|
push @buffer, $line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$gcode .= "$_\n" for @buffer;
|
||||||
|
|
||||||
return $gcode;
|
return $gcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use Moo;
|
||||||
|
|
||||||
use File::Basename qw(basename fileparse);
|
use File::Basename qw(basename fileparse);
|
||||||
use File::Spec;
|
use File::Spec;
|
||||||
use List::Util qw(min max first);
|
use List::Util qw(max first);
|
||||||
use Math::ConvexHull::MonotoneChain qw(convex_hull);
|
use Math::ConvexHull::MonotoneChain qw(convex_hull);
|
||||||
use Slic3r::ExtrusionPath ':roles';
|
use Slic3r::ExtrusionPath ':roles';
|
||||||
use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point);
|
use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN PI scale unscale move_points nearest_point);
|
||||||
|
|
Loading…
Reference in a new issue