From 8119bb2925a7a9c622c855b92c25baf55d7a1ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20=C5=A0ach?= Date: Thu, 29 Feb 2024 13:05:08 +0100 Subject: [PATCH] Implement cancel object for toolchanges. Toolchages (wipe tower/no wipe tower) are always kept and if there are any toolchanges, the objects are split at the begining of each instance, while the first travel is always part of the "next" instance. --- src/libslic3r/GCode.cpp | 28 +++++++++++++++++--- src/libslic3r/GCode/LabelObjects.cpp | 4 +++ src/libslic3r/GCode/LabelObjects.hpp | 2 ++ src/libslic3r/GCode/WipeTowerIntegration.cpp | 7 +++-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 3a5fbd5250..8534d37625 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2181,6 +2181,12 @@ LayerResult GCodeGenerator::process_layer( // Either printing all copies of all objects, or just a single copy of a single object. assert(single_object_instance_idx == size_t(-1) || layers.size() == 1); + const std::vector instances_to_print{sort_print_object_instances(layers, ordering, single_object_instance_idx)}; + const PrintInstance* first_instance{instances_to_print.empty() ? nullptr : &instances_to_print.front().print_object.instances()[instances_to_print.front().instance_id]}; + if (first_instance != nullptr) { + m_label_objects.update(*first_instance); + } + // First object, support and raft layer, if available. const Layer *object_layer = nullptr; const SupportLayer *support_layer = nullptr; @@ -2383,8 +2389,6 @@ LayerResult GCodeGenerator::process_layer( m_avoid_crossing_perimeters.disable_once(); } - std::vector instances_to_print = sort_print_object_instances(layers, ordering, single_object_instance_idx); - // We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature): bool is_anything_overridden = layer_tools.wiping_extrusions().is_anything_overridden(); if (is_anything_overridden) { @@ -2785,6 +2789,10 @@ std::string GCodeGenerator::change_layer( // Increment a progress bar indicator. gcode += m_writer.update_progress(++ m_layer_index, m_layer_count); + if (m_writer.multiple_extruders) { + gcode += m_label_objects.maybe_change_instance(); + } + if (!EXTRUDER_CONFIG(travel_ramping_lift) && EXTRUDER_CONFIG(retract_layer_change)) { gcode += this->retract_and_wipe(); } else if (EXTRUDER_CONFIG(travel_ramping_lift) && !vase_mode){ @@ -3123,7 +3131,17 @@ std::string GCodeGenerator::_extrude( std::string gcode; const std::string_view description_bridge = path_attr.role.is_bridge() ? " (bridge)"sv : ""sv; - const std::string instance_change_gcode{this->m_label_objects.maybe_change_instance()}; + const bool has_active_instance{m_label_objects.has_active_instance()}; + if (m_writer.multiple_extruders && has_active_instance) { + gcode += m_label_objects.maybe_change_instance(); + } + + std::string instance_change_gcode{this->m_label_objects.maybe_change_instance()}; + const std::string delayed_instance_change_gcode{instance_change_gcode}; + if (m_writer.multiple_extruders) { + instance_change_gcode = ""; + } + if (!m_current_layer_first_position) { const Vec3crd point = to_3d(path.front().point, scaled(this->m_last_layer_z)); gcode += this->travel_to_first_position(point, unscaled(point.z()), instance_change_gcode); @@ -3154,6 +3172,10 @@ std::string GCodeGenerator::_extrude( gcode += "FIRST_UNRETRACT" + this->unretract(); } + if (m_writer.multiple_extruders && !has_active_instance) { + gcode += delayed_instance_change_gcode; + } + if (!m_pending_pre_extrusion_gcode.empty()) { // There is G-Code that is due to be inserted before an extrusion starts. Insert it. gcode += m_pending_pre_extrusion_gcode; diff --git a/src/libslic3r/GCode/LabelObjects.cpp b/src/libslic3r/GCode/LabelObjects.cpp index caf461a0b0..dee3759417 100644 --- a/src/libslic3r/GCode/LabelObjects.cpp +++ b/src/libslic3r/GCode/LabelObjects.cpp @@ -143,6 +143,10 @@ std::string LabelObjects::maybe_change_instance() { return ""; } +bool LabelObjects::has_active_instance() { + return this->current_instance != nullptr; +} + std::string LabelObjects::all_objects_header() const { if (m_label_objects_style == LabelObjectsStyle::Disabled) diff --git a/src/libslic3r/GCode/LabelObjects.hpp b/src/libslic3r/GCode/LabelObjects.hpp index 0ef8acb104..a9461ec649 100644 --- a/src/libslic3r/GCode/LabelObjects.hpp +++ b/src/libslic3r/GCode/LabelObjects.hpp @@ -31,6 +31,8 @@ public: std::string maybe_change_instance(); + bool has_active_instance(); + private: struct LabelData { diff --git a/src/libslic3r/GCode/WipeTowerIntegration.cpp b/src/libslic3r/GCode/WipeTowerIntegration.cpp index 3d00a12eae..4172547712 100644 --- a/src/libslic3r/GCode/WipeTowerIntegration.cpp +++ b/src/libslic3r/GCode/WipeTowerIntegration.cpp @@ -58,23 +58,22 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip || will_go_down); // don't dig into the print if (should_travel_to_tower) { const Point xy_point = wipe_tower_point_to_object_point(gcodegen, start_pos); + gcode += gcodegen.m_label_objects.maybe_stop_instance(); gcode += gcodegen.retract_and_wipe(); gcodegen.m_avoid_crossing_perimeters.use_external_mp_once(); const std::string comment{"Travel to a Wipe Tower"}; if (gcodegen.m_current_layer_first_position) { if (gcodegen.last_position) { gcode += gcodegen.travel_to( - *gcodegen.last_position, xy_point, ExtrusionRole::Mixed, comment, - gcodegen.m_label_objects.maybe_stop_instance() + *gcodegen.last_position, xy_point, ExtrusionRole::Mixed, comment, "" ); } else { - gcode += gcodegen.m_label_objects.maybe_stop_instance(); gcode += gcodegen.writer().travel_to_xy(gcodegen.point_to_gcode(xy_point), comment); gcode += gcodegen.writer().get_travel_to_z_gcode(z, comment); } } else { const Vec3crd point = to_3d(xy_point, scaled(z)); - gcode += gcodegen.travel_to_first_position(point, current_z, gcodegen.m_label_objects.maybe_stop_instance()); + gcode += gcodegen.travel_to_first_position(point, current_z, ""); } gcode += gcodegen.unretract(); } else {