New testing framework
This commit is contained in:
parent
8ae96a8868
commit
2abf2be781
2
MANIFEST
2
MANIFEST
@ -45,6 +45,7 @@ lib/Slic3r/Print/Region.pm
|
|||||||
lib/Slic3r/Print/Object.pm
|
lib/Slic3r/Print/Object.pm
|
||||||
lib/Slic3r/Surface.pm
|
lib/Slic3r/Surface.pm
|
||||||
lib/Slic3r/SVG.pm
|
lib/Slic3r/SVG.pm
|
||||||
|
lib/Slic3r/Test.pm
|
||||||
lib/Slic3r/TriangleMesh.pm
|
lib/Slic3r/TriangleMesh.pm
|
||||||
MANIFEST This list of files
|
MANIFEST This list of files
|
||||||
README.markdown
|
README.markdown
|
||||||
@ -58,6 +59,7 @@ t/dynamic.t
|
|||||||
t/fill.t
|
t/fill.t
|
||||||
t/geometry.t
|
t/geometry.t
|
||||||
t/polyclip.t
|
t/polyclip.t
|
||||||
|
t/retract.t
|
||||||
t/serialize.t
|
t/serialize.t
|
||||||
t/stl.t
|
t/stl.t
|
||||||
utils/amf-to-stl.pl
|
utils/amf-to-stl.pl
|
||||||
|
@ -434,9 +434,9 @@ sub export_gcode {
|
|||||||
$self->make_brim; # must come after make_skirt
|
$self->make_brim; # must come after make_skirt
|
||||||
|
|
||||||
# output everything to a G-code file
|
# output everything to a G-code file
|
||||||
my $output_file = $self->expanded_output_filepath($params{output_file});
|
my $output_file = $params{output_file} ? $self->expanded_output_filepath($params{output_file}) : '';
|
||||||
$status_cb->(90, "Exporting G-code to $output_file");
|
$status_cb->(90, "Exporting G-code to $output_file");
|
||||||
$self->write_gcode($output_file);
|
$self->write_gcode($params{output_fh} || $output_file);
|
||||||
|
|
||||||
# run post-processing scripts
|
# run post-processing scripts
|
||||||
if (@{$Slic3r::Config->post_process}) {
|
if (@{$Slic3r::Config->post_process}) {
|
||||||
@ -449,14 +449,16 @@ sub export_gcode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# output some statistics
|
# output some statistics
|
||||||
$self->processing_time(tv_interval($t0));
|
unless ($params{quiet}) {
|
||||||
printf "Done. Process took %d minutes and %.3f seconds\n",
|
$self->processing_time(tv_interval($t0));
|
||||||
int($self->processing_time/60),
|
printf "Done. Process took %d minutes and %.3f seconds\n",
|
||||||
$self->processing_time - int($self->processing_time/60)*60;
|
int($self->processing_time/60),
|
||||||
|
$self->processing_time - int($self->processing_time/60)*60;
|
||||||
# TODO: more statistics!
|
|
||||||
printf "Filament required: %.1fmm (%.1fcm3)\n",
|
# TODO: more statistics!
|
||||||
$self->total_extrusion_length, $self->total_extrusion_volume;
|
printf "Filament required: %.1fmm (%.1fcm3)\n",
|
||||||
|
$self->total_extrusion_length, $self->total_extrusion_volume;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub export_svg {
|
sub export_svg {
|
||||||
@ -643,9 +645,14 @@ sub write_gcode {
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my ($file) = @_;
|
my ($file) = @_;
|
||||||
|
|
||||||
# open output gcode file
|
# open output gcode file if we weren't supplied a file-handle
|
||||||
open my $fh, ">", $file
|
my $fh;
|
||||||
or die "Failed to open $file for writing\n";
|
if (ref $file eq 'IO::Scalar') {
|
||||||
|
$fh = $file;
|
||||||
|
} else {
|
||||||
|
open $fh, ">", $file
|
||||||
|
or die "Failed to open $file for writing\n";
|
||||||
|
}
|
||||||
|
|
||||||
# write some information
|
# write some information
|
||||||
my @lt = localtime;
|
my @lt = localtime;
|
||||||
|
112
lib/Slic3r/Test.pm
Normal file
112
lib/Slic3r/Test.pm
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
package Slic3r::Test;
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use IO::Scalar;
|
||||||
|
use Slic3r::Geometry qw(epsilon);
|
||||||
|
|
||||||
|
sub init_print {
|
||||||
|
my ($model_name, %params) = @_;
|
||||||
|
|
||||||
|
my $model = Slic3r::Model->new;
|
||||||
|
{
|
||||||
|
my ($vertices, $facets);
|
||||||
|
if ($model_name eq '20mm_cube') {
|
||||||
|
$vertices = [
|
||||||
|
[10,10,-10], [10,-10,-10], [-10,-10,-10], [-10,10,-10], [10,10,10], [-10,10,10], [-10,-10,10], [10,-10,10],
|
||||||
|
];
|
||||||
|
$facets = [
|
||||||
|
[0,1,2], [0,2,3], [4,5,6], [4,6,7], [0,4,7], [0,7,1], [1,7,6], [1,6,2], [2,6,5], [2,5,3], [4,0,3], [4,3,5],
|
||||||
|
],
|
||||||
|
}
|
||||||
|
$model->add_object(vertices => $vertices)->add_volume(facets => $facets);
|
||||||
|
}
|
||||||
|
|
||||||
|
my $config = Slic3r::Config->new_from_defaults;
|
||||||
|
$config->apply($params{config}) if $params{config};
|
||||||
|
|
||||||
|
my $print = Slic3r::Print->new(config => $config);
|
||||||
|
$print->add_model($model);
|
||||||
|
$print->validate;
|
||||||
|
|
||||||
|
return $print;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub gcode {
|
||||||
|
my ($print) = @_;
|
||||||
|
|
||||||
|
my $fh = IO::Scalar->new(\my $gcode);
|
||||||
|
$print->export_gcode(output_fh => $fh, quiet => 1);
|
||||||
|
$fh->close;
|
||||||
|
|
||||||
|
return $gcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub compare {
|
||||||
|
my ($a, $b) = @_;
|
||||||
|
return abs($a - $b) < epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
|
package Slic3r::Test::GCodeReader;
|
||||||
|
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});
|
||||||
|
has 'E' => (is => 'rw', default => sub {0});
|
||||||
|
has 'F' => (is => 'rw', default => sub {0});
|
||||||
|
|
||||||
|
our $Verbose = 0;
|
||||||
|
my @AXES = qw(X Y Z E F);
|
||||||
|
|
||||||
|
sub parse {
|
||||||
|
my $self = shift;
|
||||||
|
my ($cb) = @_;
|
||||||
|
|
||||||
|
foreach my $line (split /\n/, $self->gcode) {
|
||||||
|
$line =~ s/\s*;(.*)//; # strip comment
|
||||||
|
next if $line eq '';
|
||||||
|
my $comment = $1;
|
||||||
|
|
||||||
|
# parse command
|
||||||
|
my ($command, @args) = split /\s+/, $line;
|
||||||
|
my %args = map { /([A-Z])(.*)/; ($1 => $2) } @args;
|
||||||
|
my %info = ();
|
||||||
|
|
||||||
|
# check retraction
|
||||||
|
if ($command =~ /^G[01]$/) {
|
||||||
|
if (!exists $args{E}) {
|
||||||
|
$info{travel} = 1;
|
||||||
|
}
|
||||||
|
foreach my $axis (@AXES) {
|
||||||
|
if (!exists $args{$axis}) {
|
||||||
|
$info{"dist_$axis"} = 0;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
$info{"dist_$axis"} = $args{$axis} - $self->$axis;
|
||||||
|
}
|
||||||
|
$info{dist_XY} = Slic3r::Line->new([0,0], [@info{qw(dist_X dist_Y)}])->length;
|
||||||
|
if (exists $args{E}) {
|
||||||
|
($info{dist_E} > 0)
|
||||||
|
? ($info{extruding} = 1)
|
||||||
|
: ($info{retracting} = 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# run callback
|
||||||
|
printf "$line\n" if $Verbose;
|
||||||
|
$cb->($self, $command, \%args, \%info);
|
||||||
|
|
||||||
|
# update coordinates
|
||||||
|
if ($command =~ /^(?:G[01]|G92)$/) {
|
||||||
|
for (@AXES) {
|
||||||
|
$self->$_($args{$_}) if exists $args{$_};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# TODO: update temperatures
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
42
t/retraction.t
Normal file
42
t/retraction.t
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
use Test::More;
|
||||||
|
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(
|
||||||
|
retract_length => [1.5],
|
||||||
|
retract_before_travel => [3],
|
||||||
|
);
|
||||||
|
my $print = Slic3r::Test::init_print('20mm_cube', config => $config);
|
||||||
|
|
||||||
|
my $retracted = 1; # ignore the first travel move from home to first point
|
||||||
|
Slic3r::Test::GCodeReader->new(gcode => Slic3r::Test::gcode($print))->parse(sub {
|
||||||
|
my ($self, $cmd, $args, $info) = @_;
|
||||||
|
|
||||||
|
if ($info->{retracting}) {
|
||||||
|
ok Slic3r::Test::compare(-$info->{dist_E}, $config->retract_length->[0]),
|
||||||
|
'retracted by the right amount';
|
||||||
|
$retracted = 1;
|
||||||
|
}
|
||||||
|
if ($info->{extruding}) {
|
||||||
|
$retracted = 0;
|
||||||
|
}
|
||||||
|
if ($info->{travel} && $info->{dist_XY} >= $config->retract_before_travel->[0]) {
|
||||||
|
ok $retracted,
|
||||||
|
'retracted before long travel move';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
done_testing;
|
||||||
|
|
||||||
|
__END__
|
Loading…
Reference in New Issue
Block a user