diff --git a/lib/Slic3r/GUI/PresetEditor.pm b/lib/Slic3r/GUI/PresetEditor.pm index 52b8067ab8..dbeae55689 100644 --- a/lib/Slic3r/GUI/PresetEditor.pm +++ b/lib/Slic3r/GUI/PresetEditor.pm @@ -1166,7 +1166,7 @@ sub options { octoprint_host octoprint_apikey use_firmware_retraction pressure_advance vibration_limit use_volumetric_e - start_gcode end_gcode before_layer_gcode layer_gcode toolchange_gcode + start_gcode end_gcode before_layer_gcode layer_gcode toolchange_gcode between_objects_gcode notes nozzle_diameter extruder_offset retract_length retract_lift retract_speed retract_restart_extra retract_before_travel retract_layer_change wipe @@ -1368,6 +1368,15 @@ sub build { $option->height(150); $optgroup->append_single_option_line($option); } + { + my $optgroup = $page->new_optgroup('Between objects G-code (for sequential printing)', + label_width => 0, + ); + my $option = $optgroup->get_option('between_objects_gcode'); + $option->full_width(1); + $option->height(150); + $optgroup->append_single_option_line($option); + } } $self->{extruder_pages} = []; diff --git a/lib/Slic3r/Print/GCode.pm b/lib/Slic3r/Print/GCode.pm index c0e6237c7d..710125c5e9 100644 --- a/lib/Slic3r/Print/GCode.pm +++ b/lib/Slic3r/Print/GCode.pm @@ -146,12 +146,14 @@ sub export { } # set extruder(s) temperature before and after start G-code - $self->_print_first_layer_temperature(0); + $self->_print_first_layer_temperature(0) + if $self->config->start_gcode !~ /M(?:109|104)/i; printf $fh "%s\n", $gcodegen->placeholder_parser->process($self->config->start_gcode); foreach my $start_gcode (@{ $self->config->start_filament_gcode }) { # process filament gcode in order printf $fh "%s\n", $gcodegen->placeholder_parser->process($start_gcode); } - $self->_print_first_layer_temperature(1); + $self->_print_first_layer_temperature(1) + if $self->config->start_gcode !~ /M(?:109|104)/i; # set other general things print $fh $gcodegen->preamble; @@ -246,8 +248,12 @@ sub export { # is triggered, so machine has more time to reach such temperatures if ($layer->id == 0 && $finished_objects > 0) { printf $fh $gcodegen->writer->set_bed_temperature($self->config->first_layer_bed_temperature), - if $self->config->first_layer_bed_temperature && $self->config->has_heatbed; - $self->_print_first_layer_temperature(0); + if $self->config->first_layer_bed_temperature + && $self->config->has_heatbed + && $self->config->between_objects_gcode !~ /M(?:190|140)/i; + $self->_print_first_layer_temperature(0) + if $self->config->between_objects_gcode !~ /M(?:109|104)/i; + printf $fh "%s\n", $gcodegen->placeholder_parser->process($self->config->between_objects_gcode); } $self->process_layer($layer, [$copy]); } @@ -336,7 +342,6 @@ sub export { sub _print_first_layer_temperature { my ($self, $wait) = @_; - return if $self->config->start_gcode =~ /M(?:109|104)/i; for my $t (@{$self->print->extruders}) { my $temp = $self->config->get_at('first_layer_temperature', $t); $temp += $self->config->standby_temperature_delta if $self->config->ooze_prevention; diff --git a/t/custom_gcode.t b/t/custom_gcode.t index 653bb26aea..9b58344ef1 100644 --- a/t/custom_gcode.t +++ b/t/custom_gcode.t @@ -1,4 +1,4 @@ -use Test::More tests => 15; +use Test::More tests => 16; use strict; use warnings; @@ -132,4 +132,13 @@ use Slic3r::Test; 'layer_num grows continously'; # i.e. no duplicates or regressions } +{ + my $config = Slic3r::Config->new_from_defaults; + $config->set('complete_objects', 1); + $config->set('between_objects_gcode', '_MY_CUSTOM_GCODE_'); + my $print = Slic3r::Test::init_print('20mm_cube', config => $config, duplicate => 3); + my $gcode = Slic3r::Test::gcode($print); + is scalar(() = $gcode =~ /^_MY_CUSTOM_GCODE_/gm), 2, 'between_objects_gcode is applied correctly'; +} + __END__ diff --git a/xs/src/libslic3r/Print.cpp b/xs/src/libslic3r/Print.cpp index deb1d31358..46bd7fd0ed 100644 --- a/xs/src/libslic3r/Print.cpp +++ b/xs/src/libslic3r/Print.cpp @@ -179,6 +179,7 @@ Print::invalidate_state_by_config(const PrintConfigBase &config) } else if (opt_key == "avoid_crossing_perimeters" || opt_key == "bed_shape" || opt_key == "bed_temperature" + || opt_key == "between_objects_gcode" || opt_key == "bridge_acceleration" || opt_key == "bridge_fan_speed" || opt_key == "complete_objects" diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp index 914a8e7bf0..def3c42209 100644 --- a/xs/src/libslic3r/PrintConfig.cpp +++ b/xs/src/libslic3r/PrintConfig.cpp @@ -64,6 +64,15 @@ PrintConfigDef::PrintConfigDef() def->height = 50; def->default_value = new ConfigOptionString(""); + def = this->add("between_objects_gcode", coString); + def->label = "Between objects G-code"; + def->tooltip = "This code is inserted between objects when using sequential printing. By default extruder and bed temperature are reset using non-wait command; however if M104, M109, M140 or M190 are detected in this custom code, Slic3r will not add temperature commands. Note that you can use placeholder variables for all Slic3r settings, so you can put a \"M109 S[first_layer_temperature]\" command wherever you want."; + def->cli = "between-objects-gcode=s"; + def->multiline = true; + def->full_width = true; + def->height = 120; + def->default_value = new ConfigOptionString(""); + def = this->add("bottom_infill_pattern", external_fill_pattern); def->label = "Bottom"; def->full_label = "Bottom infill pattern"; diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp index 28d674fa7c..494e7754c5 100644 --- a/xs/src/libslic3r/PrintConfig.hpp +++ b/xs/src/libslic3r/PrintConfig.hpp @@ -292,6 +292,7 @@ class GCodeConfig : public virtual StaticPrintConfig { public: ConfigOptionString before_layer_gcode; + ConfigOptionString between_objects_gcode; ConfigOptionString end_gcode; ConfigOptionStrings end_filament_gcode; ConfigOptionString extrusion_axis; @@ -329,6 +330,7 @@ class GCodeConfig : public virtual StaticPrintConfig virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) { OPT_PTR(before_layer_gcode); + OPT_PTR(between_objects_gcode); OPT_PTR(end_gcode); OPT_PTR(end_filament_gcode); OPT_PTR(extrusion_axis);