diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 6a0ed586ca..7507c0d74e 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -576,7 +576,6 @@ GCodeGenerator::GCodeGenerator(const Print* print) : m_brim_done(false), m_second_layer_things_done(false), m_silent_time_estimator_enabled(false), - m_current_instance({nullptr, -1}), m_print(print) {} @@ -1248,7 +1247,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail m_enable_cooling_markers = false; // we're not filtering these moves through CoolingBuffer m_avoid_crossing_perimeters.use_external_mp_once(); file.write(this->retract_and_wipe()); - file.write(this->travel_to(*this->last_position, Point(0, 0), ExtrusionRole::None, "move to origin position for next object")); + file.write(this->travel_to(*this->last_position, Point(0, 0), ExtrusionRole::None, "move to origin position for next object", "")); m_enable_cooling_markers = true; // Disable motion planner when traveling to first object point. m_avoid_crossing_perimeters.disable_once(); @@ -1333,6 +1332,7 @@ void GCodeGenerator::_do_export(Print& print, GCodeOutputStream &file, Thumbnail // and export G-code into file. this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, smooth_path_cache_global, file); + file.write(m_label_objects.maybe_stop_instance()); if (m_wipe_tower) // Purge the extruder, pull out the active filament. file.write(m_wipe_tower->finalize(*this)); @@ -2518,12 +2518,11 @@ void GCodeGenerator::process_layer_single_object( m_avoid_crossing_perimeters.init_layer(*m_layer); // When starting a new object, use the external motion planner for the first travel move. const Point &offset = print_object.instances()[print_instance.instance_id].shift; - GCode::PrintObjectInstance next_instance = {&print_object, int(print_instance.instance_id)}; - if (m_current_instance != next_instance) + + const bool updated{m_label_objects.update(print_instance.print_object.instances()[print_instance.instance_id])}; + if (updated) m_avoid_crossing_perimeters.use_external_mp_once(); - m_current_instance = next_instance; this->set_origin(unscale(offset)); - gcode += m_label_objects.start_object(print_instance.print_object.instances()[print_instance.instance_id], GCode::LabelObjects::IncludeName::No); } }; @@ -2703,8 +2702,6 @@ void GCodeGenerator::process_layer_single_object( } } } - if (! first) - gcode += m_label_objects.stop_object(print_instance.print_object.instances()[print_instance.instance_id]); } void GCodeGenerator::apply_print_config(const PrintConfig &print_config) @@ -3069,7 +3066,7 @@ void GCodeGenerator::GCodeOutputStream::write_format(const char* format, ...) va_end(args); } -std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const double from_z) { +std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const double from_z, const std::string& gcode_to_insert) { std::string gcode; const Vec3d gcode_point = to_3d(this->point_to_gcode(point.head<2>()), unscaled(point.z())); @@ -3093,6 +3090,8 @@ std::string GCodeGenerator::travel_to_first_position(const Vec3crd& point, const this->last_position = point.head<2>(); this->writer().update_position(gcode_point); + gcode += gcode_to_insert; + std::string comment{"move to first layer point"}; gcode += this->writer().get_travel_to_xy_gcode(gcode_point.head<2>(), comment); gcode += this->writer().get_travel_to_z_gcode(gcode_point.z(), comment); @@ -3126,13 +3125,14 @@ std::string GCodeGenerator::_extrude( 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())); + gcode += this->travel_to_first_position(point, unscaled(point.z()), this->m_label_objects.maybe_change_instance()); } else { // go to first point of extrusion path if (!this->last_position) { const double z = this->m_last_layer_z; const std::string comment{"move to print after unknown position"}; gcode += this->retract_and_wipe(); + gcode += m_label_objects.maybe_change_instance(); gcode += this->m_writer.travel_to_xy(this->point_to_gcode(path.front().point), comment); gcode += this->m_writer.get_travel_to_z_gcode(z, comment); } else if ( this->last_position != path.front().point) { @@ -3140,7 +3140,7 @@ std::string GCodeGenerator::_extrude( comment += description; comment += description_bridge; comment += " point"; - const std::string travel_gcode{this->travel_to(*this->last_position, path.front().point, path_attr.role, comment)}; + const std::string travel_gcode{this->travel_to(*this->last_position, path.front().point, path_attr.role, comment, this->m_label_objects.maybe_change_instance())}; gcode += travel_gcode; } } @@ -3366,7 +3366,8 @@ std::string GCodeGenerator::_extrude( std::string GCodeGenerator::generate_travel_gcode( const Points3& travel, - const std::string& comment + const std::string& comment, + const std::string& insert_before_end ) { std::string gcode; @@ -3381,9 +3382,16 @@ std::string GCodeGenerator::generate_travel_gcode( gcode += this->m_writer.set_travel_acceleration(acceleration); Vec3d previous_point{this->point_to_gcode(travel.front())}; - for (const Vec3crd& point : travel) { + bool already_inserted{false}; + for (std::size_t i{0}; i < travel.size(); ++i) { + const Vec3crd& point{travel[i]}; const Vec3d gcode_point{this->point_to_gcode(point)}; + if (travel.size() - i <= 2 && !already_inserted) { + gcode += insert_before_end; + already_inserted = true; + } + gcode += this->m_writer.travel_to_xyz(previous_point, gcode_point, comment); this->last_position = point.head<2>(); previous_point = gcode_point; @@ -3479,7 +3487,11 @@ Polyline GCodeGenerator::generate_travel_xy_path( // This method accepts &point in print coordinates. std::string GCodeGenerator::travel_to( - const Point &start_point, const Point &end_point, ExtrusionRole role, const std::string &comment + const Point &start_point, + const Point &end_point, + ExtrusionRole role, + const std::string &comment, + const std::string &gcode_to_insert ) { // check whether a straight travel move would need retraction @@ -3537,7 +3549,7 @@ std::string GCodeGenerator::travel_to( ) ); - return wipe_retract_gcode + generate_travel_gcode(travel, comment); + return wipe_retract_gcode + generate_travel_gcode(travel, comment, gcode_to_insert); } std::string GCodeGenerator::retract_and_wipe(bool toolchange) @@ -3592,6 +3604,8 @@ std::string GCodeGenerator::set_extruder(unsigned int extruder_id, double print_ // prepend retraction on the current extruder std::string gcode = this->retract_and_wipe(true); + gcode += this->m_label_objects.maybe_stop_instance(); + // Always reset the extrusion path, even if the tool change retract is set to zero. m_wipe.reset_path(); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 7800103b9b..9a96bc72c0 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -319,7 +319,8 @@ private: std::string extrude_support(const ExtrusionEntityReferences &support_fills, const GCode::SmoothPathCache &smooth_path_cache); std::string generate_travel_gcode( const Points3& travel, - const std::string& comment + const std::string& comment, + const std::string& insert_before_end ); Polyline generate_travel_xy_path( const Point& start, @@ -331,10 +332,11 @@ private: const Point &start_point, const Point &end_point, ExtrusionRole role, - const std::string &comment + const std::string &comment, + const std::string &gcode_to_insert ); - std::string travel_to_first_position(const Vec3crd& point, const double from_z); + std::string travel_to_first_position(const Vec3crd& point, const double from_z, const std::string& gcode_to_insert); bool needs_retraction(const Polyline &travel, ExtrusionRole role = ExtrusionRole::None); @@ -444,9 +446,6 @@ private: bool m_second_layer_things_done; // G-code that is due to be written before the next extrusion std::string m_pending_pre_extrusion_gcode; - // Pointer to currently exporting PrintObject and instance index. - GCode::PrintObjectInstance m_current_instance; - bool m_silent_time_estimator_enabled; // Processor diff --git a/src/libslic3r/GCode/LabelObjects.cpp b/src/libslic3r/GCode/LabelObjects.cpp index aae9f09fb9..240e6860d8 100644 --- a/src/libslic3r/GCode/LabelObjects.cpp +++ b/src/libslic3r/GCode/LabelObjects.cpp @@ -111,7 +111,37 @@ void LabelObjects::init(const SpanOfConstPtrs& objects, LabelObject } } +bool LabelObjects::update(const PrintInstance &instance) { + if (this->last_operation_instance == &instance) { + return false; + } + this->last_operation_instance = &instance; + return true; +} +std::string LabelObjects::maybe_start_instance() { + if (current_instance == nullptr && last_operation_instance != nullptr) { + current_instance = last_operation_instance; + return this->start_object(*current_instance, LabelObjects::IncludeName::No); + } + return ""; +} + +std::string LabelObjects::maybe_stop_instance() { + if (current_instance != nullptr) { + const std::string result{this->stop_object(*current_instance)}; + current_instance = nullptr; + return result; + } + return ""; +} + +std::string LabelObjects::maybe_change_instance() { + if (last_operation_instance != current_instance) { + return this->maybe_stop_instance() + this->maybe_start_instance(); + } + return ""; +} std::string LabelObjects::all_objects_header() const { diff --git a/src/libslic3r/GCode/LabelObjects.hpp b/src/libslic3r/GCode/LabelObjects.hpp index 9002655afd..0ef8acb104 100644 --- a/src/libslic3r/GCode/LabelObjects.hpp +++ b/src/libslic3r/GCode/LabelObjects.hpp @@ -16,35 +16,46 @@ class Print; namespace GCode { - -class LabelObjects { +class LabelObjects +{ public: + void init(const SpanOfConstPtrs& objects, LabelObjectsStyle label_object_style, GCodeFlavor gcode_flavor); + std::string all_objects_header() const; + std::string all_objects_header_singleline_json() const; + + bool update(const PrintInstance &instance); + + std::string maybe_start_instance(); + + std::string maybe_stop_instance(); + + std::string maybe_change_instance(); + +private: + struct LabelData + { + const PrintInstance* pi; + std::string name; + std::string center; + std::string polygon; + int unique_id; + }; + enum class IncludeName { No, Yes }; - void init(const SpanOfConstPtrs& objects, LabelObjectsStyle label_object_style, GCodeFlavor gcode_flavor); - std::string all_objects_header() const; - std::string all_objects_header_singleline_json() const; + std::string start_object(const PrintInstance& print_instance, IncludeName include_name) const; std::string stop_object(const PrintInstance& print_instance) const; -private: - struct LabelData { - const PrintInstance* pi; - std::string name; - std::string center; - std::string polygon; - int unique_id; - }; + const PrintInstance* current_instance{nullptr}; + const PrintInstance* last_operation_instance{nullptr}; LabelObjectsStyle m_label_objects_style; GCodeFlavor m_flavor; std::vector m_label_data; - }; - - } // namespace GCode } // namespace Slic3r diff --git a/src/libslic3r/GCode/WipeTowerIntegration.cpp b/src/libslic3r/GCode/WipeTowerIntegration.cpp index 49d523be11..3d00a12eae 100644 --- a/src/libslic3r/GCode/WipeTowerIntegration.cpp +++ b/src/libslic3r/GCode/WipeTowerIntegration.cpp @@ -64,15 +64,17 @@ std::string WipeTowerIntegration::append_tcr(GCodeGenerator &gcodegen, const Wip if (gcodegen.m_current_layer_first_position) { if (gcodegen.last_position) { gcode += gcodegen.travel_to( - *gcodegen.last_position, xy_point, ExtrusionRole::Mixed, comment + *gcodegen.last_position, xy_point, ExtrusionRole::Mixed, comment, + gcodegen.m_label_objects.maybe_stop_instance() ); } 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); + gcode += gcodegen.travel_to_first_position(point, current_z, gcodegen.m_label_objects.maybe_stop_instance()); } gcode += gcodegen.unretract(); } else { @@ -268,7 +270,7 @@ std::string WipeTowerIntegration::finalize(GCodeGenerator &gcodegen) if (std::abs(gcodegen.writer().get_position().z() - m_final_purge.print_z) > EPSILON) gcode += gcodegen.generate_travel_gcode( {{gcodegen.last_position->x(), gcodegen.last_position->y(), scaled(m_final_purge.print_z)}}, - "move to safe place for purging" + "move to safe place for purging", "" ); gcode += append_tcr(gcodegen, m_final_purge, -1); return gcode;