From a4b60756004bb1c2d9437b5d704a18adc570e0e9 Mon Sep 17 00:00:00 2001 From: Alessandro Ranellucci <aar@cpan.org> Date: Tue, 29 Apr 2014 17:06:31 +0200 Subject: [PATCH] Fixed regression and ambiguity about multiple-value placeholders like [first_layer_temperature_1]. Includes several unit tests covering regression. #1899 --- lib/Slic3r/GCode/PlaceholderParser.pm | 8 +++-- lib/Slic3r/GUI/SkeinPanel.pm | 11 +++++-- t/custom_gcode.t | 43 +++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 7 deletions(-) diff --git a/lib/Slic3r/GCode/PlaceholderParser.pm b/lib/Slic3r/GCode/PlaceholderParser.pm index 4b6011e48..e3dc30e8c 100644 --- a/lib/Slic3r/GCode/PlaceholderParser.pm +++ b/lib/Slic3r/GCode/PlaceholderParser.pm @@ -43,7 +43,8 @@ sub apply_config { foreach my $opt_key (@opt_keys) { my $value = $config->$opt_key; next unless ref($value) eq 'ARRAY'; - $m->{"${opt_key}_${_}"} = $value->[$_] for 0..$#$value; + $m->{"${opt_key}_" . ($_+1)} = $value->[$_] for 0..$#$value; + $m->{$opt_key} = $value->[0]; if ($Slic3r::Config::Options->{$opt_key}{type} eq 'point') { $m->{"${opt_key}_X"} = $value->[0]; $m->{"${opt_key}_Y"} = $value->[1]; @@ -70,7 +71,10 @@ sub process { } { my $regex = join '|', keys %{$self->_multiple}; - $string =~ s/\[($regex)\]/$self->_multiple->{$1}/eg; + $string =~ s/\[($regex)\]/$self->_multiple->{$1}/egx; + + # unhandled indices are populated using the first value, except _0 which is ignored for safety + $string =~ s/\[($regex)_[1-9]\d*\]/$self->_multiple->{$1}/egx; } return $string; diff --git a/lib/Slic3r/GUI/SkeinPanel.pm b/lib/Slic3r/GUI/SkeinPanel.pm index b130b4784..1b7f9487d 100644 --- a/lib/Slic3r/GUI/SkeinPanel.pm +++ b/lib/Slic3r/GUI/SkeinPanel.pm @@ -484,16 +484,21 @@ sub config { } else { # TODO: handle dirty presets. # perhaps plater shouldn't expose dirty presets at all in multi-extruder environments. + my $i = -1; foreach my $preset_idx ($self->{plater}->filament_presets) { + $i++; my $preset = $self->{options_tabs}{filament}->get_preset($preset_idx); my $config = $self->{options_tabs}{filament}->get_preset_config($preset); if (!$filament_config) { - $filament_config = $config; + $filament_config = $config->clone; next; } foreach my $opt_key (@{$config->get_keys}) { - next unless ref $filament_config->get($opt_key) eq 'ARRAY'; - push @{ $filament_config->get($opt_key) }, $config->get($opt_key)->[0]; + my $value = $filament_config->get($opt_key); + next unless ref $value eq 'ARRAY'; + $value->[$i] = $config->get($opt_key)->[0]; + use XXX; YYY $value if $opt_key eq 'first_layer_temperature'; + $filament_config->set($opt_key, $value); } } } diff --git a/t/custom_gcode.t b/t/custom_gcode.t index 6e678d690..e734886c0 100644 --- a/t/custom_gcode.t +++ b/t/custom_gcode.t @@ -1,4 +1,4 @@ -use Test::More tests => 6; +use Test::More tests => 14; use strict; use warnings; @@ -46,7 +46,7 @@ use Slic3r::Test; { my $parser = Slic3r::GCode::PlaceholderParser->new; $parser->apply_config(my $config = Slic3r::Config->new_from_defaults); - is $parser->process('[temperature_[foo]]', { foo => '0' }), + is $parser->process('[temperature_[foo]]', { foo => '1' }), $config->temperature->[0], "nested config options"; } @@ -67,4 +67,43 @@ use Slic3r::Test; ok $gcode =~ /HEIGHT:$h/, 'region config options are replaced in custom G-code'; } +{ + my $config = Slic3r::Config->new; + $config->set('extruder', 2); + $config->set('first_layer_temperature', [200,205]); + + { + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my $gcode = Slic3r::Test::gcode($print); + ok $gcode =~ /M104 S205 T1/, 'temperature set correctly for non-zero yet single extruder'; + ok $gcode !~ /M104 S\d+ T0/, 'unused extruder correctly ignored'; + } + + $config->set('infill_extruder', 1); + { + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my $gcode = Slic3r::Test::gcode($print); + ok $gcode =~ /M104 S200 T0/, 'temperature set correctly for first extruder'; + ok $gcode =~ /M104 S205 T1/, 'temperature set correctly for second extruder'; + } + + $config->set('start_gcode', qq! +;__temp0:[infill_extruder][first_layer_temperature_0]__ +;__temp1:[first_layer_temperature_1]__ +;__temp2:[first_layer_temperature_2]__ +;__temp3:[first_layer_temperature_3]__ + !); + { + my $print = Slic3r::Test::init_print('20mm_cube', config => $config); + my $gcode = Slic3r::Test::gcode($print); + # we use the [infill_extruder] placeholder to make sure this test doesn't + # catch a false positive caused by the unparsed start G-code option itself + # being embedded in the G-code + ok $gcode =~ /temp0:1\[/, 'temperature placeholder for _0 ignored'; + ok $gcode =~ /temp1:200/, 'temperature placeholder for first extruder correctly populated'; + ok $gcode =~ /temp2:205/, 'temperature placeholder for second extruder correctly populated'; + ok $gcode =~ /temp3:200/, 'tempearture placeholder for unused extruder populated with first value'; + } +} + __END__