From d7af75359f12e2b00b3b17c8dafb97e9a8697133 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Fri, 25 Oct 2024 11:13:31 +0800 Subject: [PATCH] ENH: save filament sequences in gcode result jira: NONE Signed-off-by: xun.zhang Change-Id: I79c2eb4002c72568d487df417c914ab0b8a14a67 (cherry picked from commit a289370b19e78693698db388d4057e25ba285d6b) --- src/libslic3r/GCode.cpp | 39 ++++++++++++++++++++++++-- src/libslic3r/GCode.hpp | 2 ++ src/libslic3r/GCode/GCodeProcessor.hpp | 11 ++++++++ src/libslic3r/Print.cpp | 2 +- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index fac3080bac..0cd3fdc22b 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -2155,7 +2155,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato print_object_instance_sequential_active = print_object_instances_ordering.begin(); for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) { tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); - { //save the flush statitics stored in tool ordering by object + { + // save the flush statitics stored in tool ordering by object print.m_statistics_by_extruder_count.stats_by_single_extruder += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::SingleExt); print.m_statistics_by_extruder_count.stats_by_multi_extruder_auto += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtAuto); print.m_statistics_by_extruder_count.stats_by_multi_extruder_manual += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtManual); @@ -2200,7 +2201,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Find tool ordering for all the objects at once, and the initial extruder ID. // If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it. tool_ordering = print.tool_ordering(); - { //save the flush statitics stored in tool ordering + { + //save the flush statitics stored in tool ordering print.m_statistics_by_extruder_count.stats_by_single_extruder = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::SingleExt); print.m_statistics_by_extruder_count.stats_by_multi_extruder_auto = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtAuto); print.m_statistics_by_extruder_count.stats_by_multi_extruder_manual = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtManual); @@ -2636,6 +2638,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // and export G-code into file. this->process_layers(print, tool_ordering, collect_layers_to_print(object), *print_object_instance_sequential_active - object.instances().data(), file, prime_extruder); + // save sorted filament sequences + const auto& layer_tools = tool_ordering.layer_tools(); + for (const auto& lt : layer_tools) + m_sorted_layer_filaments.emplace_back(lt.extruders); //BBS: close powerlost recovery { if (is_bbl_printers && m_second_layer_things_done) { @@ -2700,6 +2706,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // and export G-code into file. this->process_layers(print, tool_ordering, print_object_instances_ordering, layers_to_print, file); + // save sorted filament sequences + const auto& layer_tools = tool_ordering.layer_tools(); + for (const auto& lt : layer_tools) + m_sorted_layer_filaments.emplace_back(lt.extruders); + //BBS: close powerlost recovery { if (is_bbl_printers && m_second_layer_things_done) { @@ -2824,6 +2835,30 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato print.throw_if_canceled(); } + +void GCode::export_layer_filaments(GCodeProcessorResult* result) +{ + if (result == nullptr) + return; + result->layer_filaments.clear(); + for (size_t idx = 0; idx < m_sorted_layer_filaments.size(); ++idx) { + // now we do not need sorted data, so we sort the filaments in id order + auto& layer_filaments = m_sorted_layer_filaments[idx]; + std::sort(layer_filaments.begin(), layer_filaments.end()); + auto iter = result->layer_filaments.find(layer_filaments); + if (iter == result->layer_filaments.end()) { + result->layer_filaments[layer_filaments].emplace_back(idx, idx); + } + else { + // if layer id is sequential, expand the range + if (iter->second.back().second == idx - 1) + iter->second.back().second = idx; + else + iter->second.emplace_back(idx, idx); + } + } +} + //BBS void GCode::check_placeholder_parser_failed() { diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 849f657d7e..f0956e0b77 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -200,6 +200,7 @@ public: // throws std::runtime_exception on error, // throws CanceledException through print->throw_if_canceled(). void do_export(Print* print, const char* path, GCodeProcessorResult* result = nullptr, ThumbnailsGeneratorCallback thumbnail_cb = nullptr); + void export_layer_filaments(GCodeProcessorResult* result); //BBS: set offset for gcode writer void set_gcode_offset(double x, double y) { m_writer.set_xy_offset(x, y); m_processor.set_xy_offset(x, y);} @@ -608,6 +609,7 @@ private: int m_start_gcode_filament = -1; std::set m_initial_layer_extruders; + std::vector> m_sorted_layer_filaments; // BBS int get_bed_temperature(const int extruder_id, const bool is_first_layer, const BedType bed_type) const; diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 296989724f..0aca77b8ea 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -145,6 +145,15 @@ class Print; struct GCodeProcessorResult { + struct FilamentSequenceHash + { + uint64_t operator()(const std::vector& layer_filament) const { + uint64_t key = 0; + for (auto& f : layer_filament) + key |= (uint64_t(1) << f); + return key; + } + }; ConflictResultOpt conflict_result; GCodeCheckResult gcode_check_result; FilamentPrintableResult filament_printable_reuslt; @@ -241,6 +250,8 @@ class Print; std::vector warnings; int nozzle_hrc; std::vector nozzle_type; + // first key stores filaments, second keys stores the layer ranges(enclosed) that use the filaments + std::unordered_map, std::vector>,FilamentSequenceHash> layer_filaments; BedType bed_type = BedType::btCount; #if ENABLE_GCODE_VIEWER_STATISTICS int64_t time{ 0 }; diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index ddf07bed48..8c8dfb7c45 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2280,7 +2280,7 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor const Vec3d origin = this->get_plate_origin(); gcode.set_gcode_offset(origin(0), origin(1)); gcode.do_export(this, path.c_str(), result, thumbnail_cb); - + gcode.export_layer_filaments(result); //BBS result->conflict_result = m_conflict_result; return path.c_str();