From 3167e34e609d0eecb481fd550e6550024b72bb67 Mon Sep 17 00:00:00 2001 From: "xun.zhang" Date: Thu, 18 Jul 2024 16:38:26 +0800 Subject: [PATCH] ENH: add greedy algorithm for filament reorder 1.When n becomes large,the original algorithm to get best filament sequence will cost too much time and memory.Use a greedy algorithm instead.Always select the next filament with fewest flush jira:NONE Signed-off-by: xun.zhang Change-Id: Iabc924e1bdb0a07af0a6ef0bbdd62e54ce54f052 --- src/libslic3r/GCode/ToolOrdering.cpp | 44 ++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 9fd7edf57..a025f4292 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -26,8 +26,46 @@ const static bool g_wipe_into_objects = false; +static std::vectorsolve_extruder_order_with_greedy(const std::vector>& wipe_volumes, + const std::vector curr_layer_extruders, + const std::optional&start_extruder_id, + float* min_cost) +{ + float cost = 0; + std::vector best_seq; + std::vectoris_visited(curr_layer_extruders.size(), false); + std::optionalprev_filament = start_extruder_id; + int idx = curr_layer_extruders.size(); + while (idx > 0) { + if (!prev_filament) { + auto iter = std::find_if(is_visited.begin(), is_visited.end(), [](auto item) {return item == 0; }); + assert(iter != is_visited.end()); + prev_filament = curr_layer_extruders[iter - is_visited.begin()]; + } + int target_idx = -1; + int target_cost = std::numeric_limits::max(); + for (size_t k = 0; k < is_visited.size(); ++k) { + if (!is_visited[k]) { + if (wipe_volumes[*prev_filament][curr_layer_extruders[k]] < target_cost) { + target_idx = k; + target_cost = wipe_volumes[*prev_filament][curr_layer_extruders[k]]; + } + } + } + assert(target_idx != -1); + cost += target_cost; + best_seq.emplace_back(curr_layer_extruders[target_idx]); + prev_filament = curr_layer_extruders[target_idx]; + is_visited[target_idx] = true; + idx -= 1; + } + if (min_cost) + *min_cost = cost; + return best_seq; +} + //solve the probleme by forcasting one layer -static std::vectorsolve_extruder_order_with_forcast(const std::vector>wipe_volumes, +static std::vectorsolve_extruder_order_with_forcast(const std::vector>& wipe_volumes, std::vector curr_layer_extruders, std::vector next_layer_extruders, const std::optional& start_extruder_id, @@ -162,8 +200,10 @@ std::vector get_extruders_order(const std::vector&filament_lists,