mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-12 01:07:57 -06:00
Changed handling of filament_gcode_start and filament_gcode_end custom
G-codes in case of single extruder multiple material setup: At the start of the print, the filament_gcode_start is executed for the active extruder only, and the filament_gcode_start / filament_gcode_end are then executed at each tool change. When the Prusa MM wipe tower is active, the tool changes are handled a bit differently: M900 K0 is emited before the wipe tower extrusions start, and the filament_gcode_start code is executed after the wipe tower extrusions are done. This rule effectively disables the linear advance over the wipe tower. Implements https://github.com/prusa3d/Slic3r/issues/568
This commit is contained in:
parent
8807d288d7
commit
3996535e5d
2 changed files with 73 additions and 18 deletions
|
@ -31,6 +31,13 @@
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
|
// Only add a newline in case the current G-code does not end with a newline.
|
||||||
|
static inline void check_add_eol(std::string &gcode)
|
||||||
|
{
|
||||||
|
if (! gcode.empty() && gcode.back() != '\n')
|
||||||
|
gcode += '\n';
|
||||||
|
}
|
||||||
|
|
||||||
// Plan a travel move while minimizing the number of perimeter crossings.
|
// Plan a travel move while minimizing the number of perimeter crossings.
|
||||||
// point is in unscaled coordinates, in the coordinate system of the current active object
|
// point is in unscaled coordinates, in the coordinate system of the current active object
|
||||||
// (set by gcodegen.set_origin()).
|
// (set by gcodegen.set_origin()).
|
||||||
|
@ -157,6 +164,8 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
||||||
{
|
{
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
|
// Disable linear advance for the wipe tower operations.
|
||||||
|
gcode += "M900 K0\n";
|
||||||
// Move over the wipe tower.
|
// Move over the wipe tower.
|
||||||
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
// Retract for a tool change, using the toolchange retract value and setting the priming extra length.
|
||||||
gcode += gcodegen.retract(true);
|
gcode += gcodegen.retract(true);
|
||||||
|
@ -171,8 +180,17 @@ std::string WipeTowerIntegration::append_tcr(GCode &gcodegen, const WipeTower::T
|
||||||
// Inform the G-code writer about the changes done behind its back.
|
// Inform the G-code writer about the changes done behind its back.
|
||||||
gcode += tcr.gcode;
|
gcode += tcr.gcode;
|
||||||
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
||||||
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id))
|
if (new_extruder_id >= 0 && gcodegen.writer().need_toolchange(new_extruder_id)) {
|
||||||
gcodegen.writer().toolchange(new_extruder_id);
|
gcodegen.writer().toolchange(new_extruder_id);
|
||||||
|
// Append the filament start G-code.
|
||||||
|
const std::string &start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(new_extruder_id);
|
||||||
|
if (! start_filament_gcode.empty()) {
|
||||||
|
// Process the start_filament_gcode for the active filament only.
|
||||||
|
gcodegen.placeholder_parser().set("current_extruder", new_extruder_id);
|
||||||
|
gcode += gcodegen.placeholder_parser().process(start_filament_gcode, new_extruder_id);
|
||||||
|
check_add_eol(gcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
// A phony move to the end position at the wipe tower.
|
// A phony move to the end position at the wipe tower.
|
||||||
gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
|
gcodegen.writer().travel_to_xy(Pointf(tcr.end_pos.x, tcr.end_pos.y));
|
||||||
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, tcr.end_pos));
|
||||||
|
@ -199,15 +217,25 @@ std::string WipeTowerIntegration::prime(GCode &gcodegen)
|
||||||
std::string gcode;
|
std::string gcode;
|
||||||
|
|
||||||
if (&m_priming != nullptr && ! m_priming.extrusions.empty()) {
|
if (&m_priming != nullptr && ! m_priming.extrusions.empty()) {
|
||||||
|
// Disable linear advance for the wipe tower operations.
|
||||||
|
gcode += "M900 K0\n";
|
||||||
// Let the tool change be executed by the wipe tower class.
|
// Let the tool change be executed by the wipe tower class.
|
||||||
// Inform the G-code writer about the changes done behind its back.
|
// Inform the G-code writer about the changes done behind its back.
|
||||||
gcode += m_priming.gcode;
|
gcode += m_priming.gcode;
|
||||||
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
// Let the m_writer know the current extruder_id, but ignore the generated G-code.
|
||||||
gcodegen.writer().toolchange(m_priming.extrusions.back().tool);
|
unsigned int current_extruder_id = m_priming.extrusions.back().tool;
|
||||||
|
gcodegen.writer().toolchange(current_extruder_id);
|
||||||
|
gcodegen.placeholder_parser().set("current_extruder", current_extruder_id);
|
||||||
// A phony move to the end position at the wipe tower.
|
// A phony move to the end position at the wipe tower.
|
||||||
gcodegen.writer().travel_to_xy(Pointf(m_priming.end_pos.x, m_priming.end_pos.y));
|
gcodegen.writer().travel_to_xy(Pointf(m_priming.end_pos.x, m_priming.end_pos.y));
|
||||||
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.end_pos));
|
gcodegen.set_last_pos(wipe_tower_point_to_object_point(gcodegen, m_priming.end_pos));
|
||||||
|
// Append the filament start G-code, so the linear advance value will be restored.
|
||||||
|
const std::string &start_filament_gcode = gcodegen.config().start_filament_gcode.get_at(current_extruder_id);
|
||||||
|
if (! start_filament_gcode.empty()) {
|
||||||
|
// Process the start_filament_gcode for the active filament only to restore the linear advance value.
|
||||||
|
gcode += gcodegen.placeholder_parser().process(start_filament_gcode, current_extruder_id);
|
||||||
|
check_add_eol(gcode);
|
||||||
|
}
|
||||||
// Prepare a future wipe.
|
// Prepare a future wipe.
|
||||||
gcodegen.m_wipe.path.points.clear();
|
gcodegen.m_wipe.path.points.clear();
|
||||||
// Start the wipe at the current position.
|
// Start the wipe at the current position.
|
||||||
|
@ -554,8 +582,10 @@ bool GCode::_do_export(Print &print, FILE *file)
|
||||||
// Write the custom start G-code
|
// Write the custom start G-code
|
||||||
writeln(file, start_gcode);
|
writeln(file, start_gcode);
|
||||||
// Process filament-specific gcode in extruder order.
|
// Process filament-specific gcode in extruder order.
|
||||||
|
if (! print.config.single_extruder_multi_material) {
|
||||||
for (const std::string &start_gcode : print.config.start_filament_gcode.values)
|
for (const std::string &start_gcode : print.config.start_filament_gcode.values)
|
||||||
writeln(file, m_placeholder_parser.process(start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front())));
|
writeln(file, m_placeholder_parser.process(start_gcode, (unsigned int)(&start_gcode - &print.config.start_filament_gcode.values.front())));
|
||||||
|
}
|
||||||
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
|
this->_print_first_layer_extruder_temperatures(file, print, start_gcode, initial_extruder_id, true);
|
||||||
|
|
||||||
// Set other general things.
|
// Set other general things.
|
||||||
|
@ -727,8 +757,13 @@ bool GCode::_do_export(Print &print, FILE *file)
|
||||||
write(file, this->retract());
|
write(file, this->retract());
|
||||||
write(file, m_writer.set_fan(false));
|
write(file, m_writer.set_fan(false));
|
||||||
// Process filament-specific gcode in extruder order.
|
// Process filament-specific gcode in extruder order.
|
||||||
|
if (print.config.single_extruder_multi_material) {
|
||||||
|
// Process the end_filament_gcode for the active filament only.
|
||||||
|
writeln(file, m_placeholder_parser.process(print.config.end_filament_gcode.get_at(m_writer.extruder()->id()), m_writer.extruder()->id()));
|
||||||
|
} else {
|
||||||
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
for (const std::string &end_gcode : print.config.end_filament_gcode.values)
|
||||||
writeln(file, m_placeholder_parser.process(end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front())));
|
writeln(file, m_placeholder_parser.process(end_gcode, (unsigned int)(&end_gcode - &print.config.end_filament_gcode.values.front())));
|
||||||
|
}
|
||||||
writeln(file, m_placeholder_parser.process(print.config.end_gcode, m_writer.extruder()->id()));
|
writeln(file, m_placeholder_parser.process(print.config.end_gcode, m_writer.extruder()->id()));
|
||||||
write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
write(file, m_writer.update_progress(m_layer_count, m_layer_count, true)); // 100%
|
||||||
write(file, m_writer.postamble());
|
write(file, m_writer.postamble());
|
||||||
|
@ -2162,13 +2197,14 @@ GCode::retract(bool toolchange)
|
||||||
|
|
||||||
std::string GCode::set_extruder(unsigned int extruder_id)
|
std::string GCode::set_extruder(unsigned int extruder_id)
|
||||||
{
|
{
|
||||||
m_placeholder_parser.set("current_extruder", extruder_id);
|
|
||||||
if (!m_writer.need_toolchange(extruder_id))
|
if (!m_writer.need_toolchange(extruder_id))
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
// if we are running a single-extruder setup, just set the extruder and return nothing
|
// if we are running a single-extruder setup, just set the extruder and return nothing
|
||||||
if (!m_writer.multiple_extruders)
|
if (!m_writer.multiple_extruders) {
|
||||||
|
m_placeholder_parser.set("current_extruder", extruder_id);
|
||||||
return m_writer.toolchange(extruder_id);
|
return m_writer.toolchange(extruder_id);
|
||||||
|
}
|
||||||
|
|
||||||
// prepend retraction on the current extruder
|
// prepend retraction on the current extruder
|
||||||
std::string gcode = this->retract(true);
|
std::string gcode = this->retract(true);
|
||||||
|
@ -2176,23 +2212,41 @@ std::string GCode::set_extruder(unsigned int extruder_id)
|
||||||
// Always reset the extrusion path, even if the tool change retract is set to zero.
|
// Always reset the extrusion path, even if the tool change retract is set to zero.
|
||||||
m_wipe.reset_path();
|
m_wipe.reset_path();
|
||||||
|
|
||||||
// append custom toolchange G-code
|
if (m_writer.extruder() != nullptr) {
|
||||||
if (m_writer.extruder() != nullptr && !m_config.toolchange_gcode.value.empty()) {
|
// Process the custom end_filament_gcode in case of single_extruder_multi_material.
|
||||||
|
unsigned int old_extruder_id = m_writer.extruder()->id();
|
||||||
|
const std::string &end_filament_gcode = m_config.end_filament_gcode.get_at(old_extruder_id);
|
||||||
|
if (m_config.single_extruder_multi_material && ! end_filament_gcode.empty()) {
|
||||||
|
gcode += m_placeholder_parser.process(end_filament_gcode, old_extruder_id);
|
||||||
|
check_add_eol(gcode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_placeholder_parser.set("current_extruder", extruder_id);
|
||||||
|
|
||||||
|
if (m_writer.extruder() != nullptr && ! m_config.toolchange_gcode.value.empty()) {
|
||||||
|
// Process the custom toolchange_gcode.
|
||||||
DynamicConfig config;
|
DynamicConfig config;
|
||||||
config.set_key_value("previous_extruder", new ConfigOptionInt((int)m_writer.extruder()->id()));
|
config.set_key_value("previous_extruder", new ConfigOptionInt((int)m_writer.extruder()->id()));
|
||||||
config.set_key_value("next_extruder", new ConfigOptionInt((int)extruder_id));
|
config.set_key_value("next_extruder", new ConfigOptionInt((int)extruder_id));
|
||||||
gcode += m_placeholder_parser.process(
|
gcode += m_placeholder_parser.process(m_config.toolchange_gcode.value, extruder_id, &config);
|
||||||
m_config.toolchange_gcode.value, extruder_id, &config)
|
check_add_eol(gcode);
|
||||||
+ '\n';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if ooze prevention is enabled, park current extruder in the nearest
|
// If ooze prevention is enabled, park current extruder in the nearest
|
||||||
// standby point and set it to the standby temperature
|
// standby point and set it to the standby temperature.
|
||||||
if (m_ooze_prevention.enable && m_writer.extruder() != nullptr)
|
if (m_ooze_prevention.enable && m_writer.extruder() != nullptr)
|
||||||
gcode += m_ooze_prevention.pre_toolchange(*this);
|
gcode += m_ooze_prevention.pre_toolchange(*this);
|
||||||
// append the toolchange command
|
// Append the toolchange command.
|
||||||
gcode += m_writer.toolchange(extruder_id);
|
gcode += m_writer.toolchange(extruder_id);
|
||||||
// set the new extruder to the operating temperature
|
// Append the filament start G-code for single_extruder_multi_material.
|
||||||
|
const std::string &start_filament_gcode = m_config.start_filament_gcode.get_at(extruder_id);
|
||||||
|
if (m_config.single_extruder_multi_material && ! start_filament_gcode.empty()) {
|
||||||
|
// Process the start_filament_gcode for the active filament only.
|
||||||
|
gcode += m_placeholder_parser.process(start_filament_gcode, extruder_id);
|
||||||
|
check_add_eol(gcode);
|
||||||
|
}
|
||||||
|
// Set the new extruder to the operating temperature.
|
||||||
if (m_ooze_prevention.enable)
|
if (m_ooze_prevention.enable)
|
||||||
gcode += m_ooze_prevention.post_toolchange(*this);
|
gcode += m_ooze_prevention.post_toolchange(*this);
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
const FullPrintConfig &config() const { return m_config; }
|
const FullPrintConfig &config() const { return m_config; }
|
||||||
const Layer* layer() const { return m_layer; }
|
const Layer* layer() const { return m_layer; }
|
||||||
GCodeWriter& writer() { return m_writer; }
|
GCodeWriter& writer() { return m_writer; }
|
||||||
|
PlaceholderParser& placeholder_parser() { return m_placeholder_parser; }
|
||||||
bool enable_cooling_markers() const { return m_enable_cooling_markers; }
|
bool enable_cooling_markers() const { return m_enable_cooling_markers; }
|
||||||
|
|
||||||
// For Perl bindings, to be used exclusively by unit tests.
|
// For Perl bindings, to be used exclusively by unit tests.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue