123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- # Helper module to parse and interpret a G-code file,
- # invoking a callback for each move extracted from the G-code.
- # Currently used by the automatic tests only.
- package Slic3r::GCode::Reader;
- use Moo;
- has 'config' => (is => 'ro', default => sub { Slic3r::Config::GCode->new });
- has 'X' => (is => 'rw', default => sub {0});
- has 'Y' => (is => 'rw', default => sub {0});
- has 'Z' => (is => 'rw', default => sub {0});
- has 'E' => (is => 'rw', default => sub {0});
- has 'F' => (is => 'rw', default => sub {0});
- has '_extrusion_axis' => (is => 'rw', default => sub {"E"});
- our $Verbose = 0;
- my @AXES = qw(X Y Z E);
- sub apply_print_config {
- my ($self, $print_config) = @_;
-
- $self->config->apply_static($print_config);
- $self->_extrusion_axis($self->config->get_extrusion_axis);
- }
- sub clone {
- my $self = shift;
- return (ref $self)->new(
- map { $_ => $self->$_ } (@AXES, 'F', '_extrusion_axis', 'config'),
- );
- }
- sub parse {
- my $self = shift;
- my ($gcode, $cb) = @_;
-
- 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
- my %info = (comment => $1, raw => $raw_line);
-
- # parse command
- my ($command, @args) = split /\s+/, $line;
- $command //= '';
- my %args = map { /([A-Z])(.*)/; ($1 => $2) } @args;
-
- # convert extrusion axis
- if (exists $args{ $self->_extrusion_axis }) {
- $args{E} = $args{ $self->_extrusion_axis };
- }
-
- # check motion
- if ($command =~ /^G[01]$/) {
- foreach my $axis (@AXES) {
- if (exists $args{$axis}) {
- $self->$axis(0) if $axis eq 'E' && $self->config->use_relative_e_distances;
- $info{"dist_$axis"} = $args{$axis} - $self->$axis;
- $info{"new_$axis"} = $args{$axis};
- } else {
- $info{"dist_$axis"} = 0;
- $info{"new_$axis"} = $self->$axis;
- }
- }
- $info{dist_XY} = sqrt(($info{dist_X}**2) + ($info{dist_Y}**2));
- if (exists $args{E}) {
- if ($info{dist_E} > 0) {
- $info{extruding} = 1;
- } elsif ($info{dist_E} < 0) {
- $info{retracting} = 1
- }
- } else {
- $info{travel} = 1;
- }
- }
-
- # run callback
- $cb->($self, $command, \%args, \%info);
-
- # update coordinates
- if ($command =~ /^(?:G[01]|G92)$/) {
- for my $axis (@AXES, 'F') {
- $self->$axis($args{$axis}) if exists $args{$axis};
- }
- }
-
- # TODO: update temperatures
- }
- }
- 1;
|