diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0e36b6fb8..1d9f387d4 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1866,7 +1866,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); @@ -1917,7 +1918,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); @@ -2290,6 +2292,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // 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 (m_second_layer_things_done && print.is_BBL_Printer()) { @@ -2361,6 +2367,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 (m_second_layer_things_done && print.is_BBL_Printer()) { @@ -2460,6 +2471,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 89a74cafc..7410c46c9 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -178,6 +178,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);} @@ -551,6 +552,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 8af2e4fe5..8d6ec40b6 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -146,6 +146,15 @@ namespace Slic3r { 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; @@ -239,6 +248,8 @@ namespace Slic3r { //BBS std::vector warnings; 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 10953399d..1b492489f 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -2035,6 +2035,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();