Moved vibration limit to its own G-code filter

This commit is contained in:
Alessandro Ranellucci 2013-08-28 16:51:58 +02:00
parent 7fbacc5885
commit 36e5e1f933
18 changed files with 103 additions and 71 deletions

View file

@ -9,6 +9,7 @@ has 'gcodegen' => (is => 'ro', required => 1);
has 'shift' => (is => 'ro', required => 1);
has 'spiralvase' => (is => 'lazy');
has 'vibration_limit' => (is => 'lazy');
has 'skirt_done' => (is => 'rw', default => sub { {} }); # print_z => 1
has 'brim_done' => (is => 'rw');
has 'second_layer_things_done' => (is => 'rw');
@ -22,6 +23,14 @@ sub _build_spiralvase {
: undef;
}
sub _build_vibration_limit {
my $self = shift;
return $Slic3r::Config->vibration_limit
? Slic3r::GCode::VibrationLimit->new(config => $self->gcodegen->config)
: undef;
}
sub process_layer {
my $self = shift;
my ($layer, $object_copies) = @_;
@ -164,6 +173,10 @@ sub process_layer {
$gcode = $self->spiralvase->process_layer($gcode, $layer)
if $spiralvase;
# apply vibration limit if enabled
$gcode = $self->vibration_limit->process($gcode)
if $Slic3r::Config->vibration_limit != 0;
return $gcode;
}

View file

@ -1,7 +1,6 @@
package Slic3r::GCode::Reader;
use Moo;
has 'gcode' => (is => 'ro', required => 1);
has 'X' => (is => 'rw', default => sub {0});
has 'Y' => (is => 'rw', default => sub {0});
has 'Z' => (is => 'rw', default => sub {0});
@ -13,9 +12,9 @@ my @AXES = qw(X Y Z E);
sub parse {
my $self = shift;
my ($cb) = @_;
my ($gcode, $cb) = @_;
foreach my $raw_line (split /\R+/, $self->gcode) {
foreach my $raw_line (split /\R+/, $gcode) {
print "$raw_line\n" if $Verbose || $ENV{SLIC3R_TESTS_GCODE};
my $line = $raw_line;
$line =~ s/\s*;(.*)//; # strip comment
@ -50,12 +49,12 @@ sub parse {
}
# run callback
$cb->($self, $command, \%args, \%info);
#$cb->($self, $command, \%args, \%info);
# update coordinates
if ($command =~ /^(?:G[01]|G92)$/) {
for (@AXES, 'F') {
$self->$_($args{$_}) if exists $args{$_};
for my $axis (@AXES, 'F') {
$self->$axis($args{$axis}) if exists $args{$axis};
}
}

View file

@ -10,7 +10,7 @@ sub process_layer {
my ($gcode, $layer) = @_;
my $total_layer_length = 0;
Slic3r::GCode::Reader->new(gcode => $gcode)->parse(sub {
Slic3r::GCode::Reader->new->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
$total_layer_length += $info->{dist_XY}
if $cmd eq 'G1' && $info->{extruding};
@ -20,7 +20,7 @@ sub process_layer {
my $layer_height = $layer->height;
my $z = $layer->print_z + $self->config->z_offset - $layer_height;
my $newlayer = 0;
Slic3r::GCode::Reader->new(gcode => $gcode)->parse(sub {
Slic3r::GCode::Reader->new->parse($gcode, sub {
my ($reader, $cmd, $args, $info) = @_;
if ($cmd eq 'G1' && exists $args->{Z}) {

View file

@ -0,0 +1,64 @@
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;