From 64853d5661970efb54c502b36d551a1bf1086efa Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci Date: Thu, 5 Jun 2014 16:24:47 +0200 Subject: [PATCH] Bugfix: M73 was exceeding 100% when multiple objects were printed together. #1912 --- lib/Slic3r/GCode.pm | 1 + lib/Slic3r/Print.pm | 14 +++++++++++-- t/gcode.t | 50 ++++++++++++++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/lib/Slic3r/GCode.pm b/lib/Slic3r/GCode.pm index f085a3a3..520ececc 100644 --- a/lib/Slic3r/GCode.pm +++ b/lib/Slic3r/GCode.pm @@ -82,6 +82,7 @@ sub change_layer { my $gcode = ""; if ($self->config->gcode_flavor =~ /^(?:makerware|sailfish)$/) { + # TODO: cap this to 99% and add an explicit M73 P100 in the end G-code $gcode .= sprintf "M73 P%s%s\n", int(99 * ($self->_layer_index / ($self->layer_count - 1))), ($self->config->gcode_comments ? ' ; update progress' : ''); diff --git a/lib/Slic3r/Print.pm b/lib/Slic3r/Print.pm index 0870091c..e36ce607 100644 --- a/lib/Slic3r/Print.pm +++ b/lib/Slic3r/Print.pm @@ -3,7 +3,7 @@ use Moo; use File::Basename qw(basename fileparse); use File::Spec; -use List::Util qw(min max first); +use List::Util qw(min max first sum); use Slic3r::ExtrusionPath ':roles'; use Slic3r::Flow ':roles'; use Slic3r::Geometry qw(X Y Z X1 Y1 X2 Y2 MIN MAX PI scale unscale move_points chained_path @@ -855,10 +855,20 @@ sub write_gcode { # prepare the helper object for replacing placeholders in custom G-code and output filename $self->placeholder_parser->update_timestamp; + # estimate the total number of layer changes + # TODO: only do this when M73 is enabled + my $layer_count; + if ($self->config->complete_objects) { + $layer_count = sum(map { $_->layer_count * @{$_->copies} } @{$self->objects}); + } else { + # if sequential printing is not enable, all copies of the same object share the same layer change command(s) + $layer_count = sum(map { $_->layer_count } @{$self->objects}); + } + # set up our helper object my $gcodegen = Slic3r::GCode->new( placeholder_parser => $self->placeholder_parser, - layer_count => $self->layer_count, + layer_count => $layer_count, ); $gcodegen->config->apply_print_config($self->config); $gcodegen->set_extruders($self->extruders, $self->config); diff --git a/t/gcode.t b/t/gcode.t index ce9a0f48..b4cd7aa9 100644 --- a/t/gcode.t +++ b/t/gcode.t @@ -1,4 +1,4 @@ -use Test::More tests => 9; +use Test::More tests => 11; use strict; use warnings; @@ -97,20 +97,42 @@ use Slic3r::Test; } { - my $config = Slic3r::Config->new_from_defaults; - $config->set('gcode_flavor', 'sailfish'); - $config->set('raft_layers', 3); - my $print = Slic3r::Test::init_print('20mm_cube', config => $config); - my @percent = (); - Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { - my ($self, $cmd, $args, $info) = @_; + my $test = sub { + my ($print, $comment) = @_; - if ($cmd eq 'M73') { - push @percent, $args->{P}; - } - }); - # the extruder heater is turned off when M73 P100 is reached - ok !(defined first { $_ > 100 } @percent), 'M73 is never given more than 100%'; + my @percent = (); + Slic3r::GCode::Reader->new->parse(Slic3r::Test::gcode($print), sub { + my ($self, $cmd, $args, $info) = @_; + + if ($cmd eq 'M73') { + push @percent, $args->{P}; + } + }); + # the extruder heater is turned off when M73 P100 is reached + ok !(defined first { $_ > 100 } @percent), "M73 is never given more than 100% ($comment)"; + }; + + { + my $config = Slic3r::Config->new_from_defaults; + $config->set('gcode_flavor', 'sailfish'); + $config->set('raft_layers', 3); + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + $test->($print, 'single object'); + } + + { + my $config = Slic3r::Config->new_from_defaults; + $config->set('gcode_flavor', 'sailfish'); + my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 2); + $test->($print, 'two copies of single object'); + } + + { + my $config = Slic3r::Config->new_from_defaults; + $config->set('gcode_flavor', 'sailfish'); + my $print = Slic3r::Test::init_print(['20mm_cube','20mm_cube'], config => $config); + $test->($print, 'two objects'); + } } __END__