From d7a8219a8f6e73e093fd89c9768ae1d010936034 Mon Sep 17 00:00:00 2001 From: "zhimin.zeng" Date: Fri, 30 Sep 2022 11:54:44 +0800 Subject: [PATCH] FIX: modify reorder extruders time Change-Id: Ib72faf039dee6a08770617c4c2f341079d7e02e9 (cherry picked from commit 5e9d479bd7d7ef54bcafe7181dcdd8c03adaae51) --- src/libslic3r/GCode/ToolOrdering.cpp | 72 ++++++++++++++++++++++++++++ src/libslic3r/GCode/ToolOrdering.hpp | 1 + src/libslic3r/Print.cpp | 50 ------------------- 3 files changed, 73 insertions(+), 50 deletions(-) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index c2925b566..24c1d7911 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -20,6 +20,50 @@ namespace Slic3r { const static bool g_wipe_into_objects = false; +void dfs_get_all_sorted_extruders(const std::vector> & wipe_volumes, + const std::vector & all_extruders, + std::vector & sorted_extruders, + float flush_volume, + std::map> &volumes_to_extruder_order) +{ + if (sorted_extruders.size() == all_extruders.size()) { + volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders)); + return; + } + + for (auto extruder_id : all_extruders) { + if (sorted_extruders.empty()) { + sorted_extruders.push_back(extruder_id); + dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order); + sorted_extruders.pop_back(); + } else { + auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id); + if (itor == sorted_extruders.end()) { + float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id]; + flush_volume += delta_flush_volume; + sorted_extruders.push_back(extruder_id); + dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order); + flush_volume -= delta_flush_volume; + sorted_extruders.pop_back(); + } + } + } +} + +std::vector get_extruders_order(const std::vector> &wipe_volumes, std::vector all_extruders, unsigned int start_extruder_id) +{ + if (all_extruders.size() > 1) { + std::vector sorted_extruders; + auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id); + if (iter != all_extruders.end()) { sorted_extruders.push_back(start_extruder_id); } + std::map> volumes_to_extruder_order; + dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order); + if (volumes_to_extruder_order.size() > 0) return volumes_to_extruder_order.begin()->second; + } + return all_extruders; +} + + // Returns true in case that extruder a comes before b (b does not have to be present). False otherwise. bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const { @@ -471,6 +515,9 @@ void ToolOrdering::reorder_extruders(unsigned int last_extruder_id) assert(extruder_id > 0); -- extruder_id; } + + // reorder the extruders for minimum flush volume + reorder_extruders_for_minimum_flush_volume(); } // BBS @@ -539,6 +586,9 @@ void ToolOrdering::reorder_extruders(std::vector tool_order_layer0 assert(extruder_id > 0); --extruder_id; } + + // reorder the extruders for minimum flush volume + reorder_extruders_for_minimum_flush_volume(); } void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height) @@ -670,6 +720,28 @@ void ToolOrdering::collect_extruder_statistics(bool prime_multi_material) } } +void ToolOrdering::reorder_extruders_for_minimum_flush_volume() +{ + if (!m_print_config_ptr || m_layer_tools.empty()) + return; + + // Get wiping matrix to get number of extruders and convert vector to vector: + std::vector flush_matrix(cast(m_print_config_ptr->flush_volumes_matrix.values)); + const unsigned int number_of_extruders = (unsigned int) (sqrt(flush_matrix.size()) + EPSILON); + // Extract purging volumes for each extruder pair: + std::vector> wipe_volumes; + for (unsigned int i = 0; i < number_of_extruders; ++i) + wipe_volumes.push_back(std::vector(flush_matrix.begin() + i * number_of_extruders, flush_matrix.begin() + (i + 1) * number_of_extruders)); + + unsigned int current_extruder_id = -1; + for (LayerTools& lt : m_layer_tools) { + if (lt.extruders.empty()) + continue; + lt.extruders = get_extruders_order(wipe_volumes, lt.extruders, current_extruder_id); + current_extruder_id = lt.extruders.back(); + } +} + // Layers are marked for infinite skirt aka draft shield. Not all the layers have to be printed. void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height) { diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index b6de13b26..34fdbf49c 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -194,6 +194,7 @@ private: void fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height); void mark_skirt_layers(const PrintConfig &config, coordf_t max_layer_height); void collect_extruder_statistics(bool prime_multi_material); + void reorder_extruders_for_minimum_flush_volume(); // BBS std::vector generate_first_layer_tool_order(const Print& print); diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 12aec6321..28ad6e6db 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -38,54 +38,6 @@ PrintRegion::PrintRegion(PrintRegionConfig &&config) : PrintRegion(std::move(con //BBS float Print::min_skirt_length = 0; -void dfs_get_all_sorted_extruders(const std::vector>& wipe_volumes, - const std::vector& all_extruders, - std::vector & sorted_extruders, - float flush_volume, - std::map> & volumes_to_extruder_order) -{ - if (sorted_extruders.size() == all_extruders.size()) { - volumes_to_extruder_order.insert(std::pair(flush_volume, sorted_extruders)); - return; - } - - for (auto extruder_id : all_extruders) { - if (sorted_extruders.empty()) { - sorted_extruders.push_back(extruder_id); - dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order); - sorted_extruders.pop_back(); - } else { - auto itor = std::find(sorted_extruders.begin(), sorted_extruders.end(), extruder_id); - if (itor == sorted_extruders.end()) { - float delta_flush_volume = wipe_volumes[sorted_extruders.back()][extruder_id]; - flush_volume += delta_flush_volume; - sorted_extruders.push_back(extruder_id); - dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, flush_volume, volumes_to_extruder_order); - flush_volume -= delta_flush_volume; - sorted_extruders.pop_back(); - } - } - } -} - -std::vector get_extruders_order(const std::vector> &wipe_volumes, - std::vector all_extruders, - unsigned int start_extruder_id) -{ - if (all_extruders.size() > 1) { - std::vector sorted_extruders; - auto iter = std::find(all_extruders.begin(), all_extruders.end(), start_extruder_id); - if (iter != all_extruders.end()) { - sorted_extruders.push_back(start_extruder_id); - } - std::map> volumes_to_extruder_order; - dfs_get_all_sorted_extruders(wipe_volumes, all_extruders, sorted_extruders, 0, volumes_to_extruder_order); - if(volumes_to_extruder_order.size() > 0) - return volumes_to_extruder_order.begin()->second; - } - return all_extruders; -} - void Print::clear() { std::scoped_lock lock(this->state_mutex()); @@ -1896,8 +1848,6 @@ void Print::_make_wipe_tower() bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front(); wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_extruder_id, current_extruder_id, false); - layer_tools.extruders = get_extruders_order(wipe_volumes, layer_tools.extruders, current_extruder_id); - for (const auto extruder_id : layer_tools.extruders) { // BBS: priming logic is removed, so no need to do toolchange for first extruder if (/*(first_layer && extruder_id == m_wipe_tower_data.tool_ordering.all_extruders().back()) || */extruder_id != current_extruder_id) {