FIX: some filament group related bugs

1. Ignore machine filaments without enougn info

jira:NONE

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: I8973645555ae1d0986f90838797652258c4b57ac
This commit is contained in:
xun.zhang 2025-01-01 16:45:53 +08:00 committed by lane.wei
parent d78f7d6ca7
commit c75285002a
5 changed files with 66 additions and 37 deletions

View File

@ -84,12 +84,13 @@ namespace Slic3r
// only support extruder nums with 2, try to swap the master extruder id with the other extruder id
bool optimize_group_for_master_extruder(const std::vector<unsigned int>& used_filaments,const FilamentGroupContext& ctx, std::vector<int>& filament_map)
std::vector<int> optimize_group_for_master_extruder(const std::vector<unsigned int>& used_filaments,const FilamentGroupContext& ctx, std::vector<int>& filament_map)
{
std::vector<int> ret = filament_map;
std::unordered_map<int, std::set<int>> groups;
for (size_t idx = 0; idx < used_filaments.size(); ++idx) {
int filament_id = used_filaments[idx];
int group_id = filament_map[filament_id];
int group_id = ret[filament_id];
groups[group_id].insert(filament_id);
}
@ -99,12 +100,11 @@ namespace Slic3r
if (can_swap_groups(none_master_extruder_id, groups[none_master_extruder_id], ctx.machine_info.master_extruder_id, groups[ctx.machine_info.master_extruder_id], ctx)
&& groups[none_master_extruder_id].size()>groups[ctx.machine_info.master_extruder_id].size()) {
for (auto fid : groups[none_master_extruder_id])
filament_map[fid] = ctx.machine_info.master_extruder_id;
ret[fid] = ctx.machine_info.master_extruder_id;
for (auto fid : groups[ctx.machine_info.master_extruder_id])
filament_map[fid] = none_master_extruder_id;
return true;
ret[fid] = none_master_extruder_id;
}
return false;
return ret;
}
/**
@ -124,20 +124,13 @@ namespace Slic3r
std::vector<int> select_best_group_for_ams(const std::vector<std::vector<int>>& map_lists, const std::vector<unsigned int>& used_filaments, const std::vector<Color>& used_filament_colors_, const std::vector<std::vector<Color>>& ams_filament_colors_,const double color_threshold)
{
using namespace FlushPredict;
std::vector<Color>used_filament_colors;
std::vector<Color>used_filament_colors=used_filament_colors_;
std::vector<std::vector<Color>>ams_filament_colors(2);
for (auto& item : used_filament_colors_)
used_filament_colors.emplace_back(item);
for (size_t idx = 0; idx < std::min(ams_filament_colors.size(), ams_filament_colors_.size()); ++idx)
ams_filament_colors[idx] = ams_filament_colors_[idx];
const double ams_color_dist_threshold = used_filaments.size() * color_threshold;
for (size_t idx = 0; idx < ams_filament_colors_.size(); ++idx) {
std::vector<Color> tmp;
for (auto& item : ams_filament_colors_[idx])
tmp.emplace_back(item);
ams_filament_colors[idx] = std::move(tmp);
}
int best_cost = std::numeric_limits<int>::max();
std::vector<int>best_map;
for (auto& map : map_lists) {
@ -169,7 +162,7 @@ namespace Slic3r
std::vector<int>l_nodes(group_colors[i].size()), r_nodes(ams_filament_colors[i].size());
std::iota(l_nodes.begin(), l_nodes.end(), 0);
std::iota(r_nodes.begin(), r_nodes.end(), 0);
GeneralMinCostSolver mcmf(distance_matrix, l_nodes, r_nodes);
MatchModeGroupSolver mcmf(distance_matrix, l_nodes, r_nodes,std::vector<int>(r_nodes.size(),l_nodes.size()));
auto ams_map = mcmf.solve();
for (size_t idx = 0; idx < ams_map.size(); ++idx) {
@ -519,12 +512,12 @@ namespace Slic3r
std::vector<int>machine_filament_capacity(machine_filament_list.size());
for (size_t idx = 0; idx < machine_filament_capacity.size(); ++idx) {
if (machine_filament_list[idx].is_extended) {
// extend filaments can at most map one filaments
machine_filament_capacity[idx] = ctx.group_info.ignore_ext_filament ? 0 : 1;
machine_filament_capacity[idx] = 1; // extend filaments can at most map one filaments
}
else
else {
machine_filament_capacity[idx] = l_nodes.size(); // AMS filaments can map multiple filaments
}
}
std::vector<int>extruder_filament_count(2, 0);
@ -665,12 +658,13 @@ namespace Slic3r
auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments);
std::vector<int> ret = calc_min_flush_group(cost);
optimize_group_for_master_extruder(used_filaments, ctx, ret); // ignore the return value
std::vector<std::vector<int>> memoryed_maps = this->m_memoryed_groups;
memoryed_maps.insert(memoryed_maps.begin(), ret);
std::vector<int> optimized_ret = optimize_group_for_master_extruder(used_filaments, ctx, ret);
if (optimized_ret != ret)
memoryed_maps.insert(memoryed_maps.begin(), optimized_ret);
std::vector<Color> used_colors;
for (const auto& f : used_filaments)
used_colors.push_back(Color(ctx.model_info.filament_colors[f]));
@ -678,10 +672,10 @@ namespace Slic3r
std::vector<std::vector<Color>> ams_colors;
for (const auto& filament_info : ctx.machine_info.machine_filament_info) {
ams_colors.emplace_back();
for (const auto& info : filament_info)
if (!ctx.group_info.ignore_ext_filament || !info.is_extended)
for (const auto& info : filament_info) {
ams_colors.back().push_back(info.color);
}
}
ret = select_best_group_for_ams(memoryed_maps, used_filaments, used_colors, ams_colors);
return ret;

View File

@ -95,7 +95,7 @@ namespace Slic3r
std::vector<int> select_best_group_for_ams(const std::vector<std::vector<int>>& map_lists, const std::vector<unsigned int>& used_filaments, const std::vector<FilamentGroupUtils::Color>& used_filament_colors_, const std::vector<std::vector<FilamentGroupUtils::Color>>& ams_filament_colros_,const double color_delta_threshold = 20);
bool optimize_group_for_master_extruder(const std::vector<unsigned int>& used_filaments, const FilamentGroupContext& ctx, std::vector<int>& filament_map);
std::vector<int> optimize_group_for_master_extruder(const std::vector<unsigned int>& used_filaments, const FilamentGroupContext& ctx, const std::vector<int>& filament_map);
bool can_swap_groups(const int extruder_id_0, const std::set<int>& group_0, const int extruder_id_1, const std::set<int>& group_1, const FilamentGroupContext& ctx);

View File

@ -71,7 +71,7 @@ namespace FilamentGroupUtils
}
std::vector<std::vector<FilamentInfo>> build_machine_filaments(const std::vector<std::vector<DynamicPrintConfig>>& filament_configs)
static std::vector<std::vector<FilamentInfo>> build_full_machine_filaments(const std::vector<std::vector<DynamicPrintConfig>>& filament_configs)
{
// defualt size set to 2
std::vector<std::vector<FilamentInfo>> machine_filaments(2);
@ -79,8 +79,8 @@ namespace FilamentGroupUtils
auto& arr = filament_configs[idx];
for (auto& item : arr) {
FilamentInfo temp;
std::string type = "PLA";
std::string color = "#FFFFFF";
std::string type;
std::string color;
std::string tray_name;
if (auto color_ptr = item.option<ConfigOptionStrings>("filament_colour"); color_ptr)
@ -90,7 +90,10 @@ namespace FilamentGroupUtils
if (auto tray_ptr = item.option<ConfigOptionStrings>("tray_name"); tray_ptr)
tray_name = tray_ptr->get_at(0);
temp.color = color.empty() ? Color() : Color(color);
if (color.empty() || type.empty() || tray_name.empty())
continue;
temp.color = Color(color);
temp.type =type;
temp.extruder_id = idx;
temp.is_extended = tray_name == "Ext"; // hard-coded ext flag
@ -100,6 +103,36 @@ namespace FilamentGroupUtils
return machine_filaments;
}
std::vector<std::vector<FilamentInfo>> build_machine_filaments(const std::vector<std::vector<DynamicPrintConfig>>& filament_configs, const std::vector<std::map<int, int>>& ams_counts, bool ignore_ext_filament)
{
std::vector<std::vector<FilamentInfo>> ret(2);
std::vector<int> ams_size(2, 0);
std::vector<std::vector<FilamentInfo>> full_machine_filaments = build_full_machine_filaments(filament_configs);
assert(full_machine_filaments.size() == 2);
for (size_t idx = 0; idx < std::min(ams_counts.size(),ams_size.size()); ++idx) {
const auto& ams_count = ams_counts[idx];
for (auto iter = ams_count.begin(); iter != ams_count.end(); ++iter) {
ams_size[idx] += iter->first * iter->second;
}
}
assert(full_machine_filaments.size() == ams_size.size());
for (size_t idx = 0; idx < std::min(ams_size.size(), full_machine_filaments.size()); ++idx) {
std::vector<FilamentInfo> tmp;
bool accept_ext_filament = ams_size[idx] == 0 && !ignore_ext_filament;
for (size_t j = 0; j < full_machine_filaments[idx].size(); ++j) {
auto machine_filament = full_machine_filaments[idx][j];
if (!full_machine_filaments[idx][j].is_extended)
tmp.emplace_back(machine_filament);
else if (accept_ext_filament)
tmp.emplace_back(machine_filament);
}
ret[idx] = std::move(tmp);
}
return ret;
}
bool collect_unprintable_limits(const std::vector<std::set<int>>& physical_unprintables, const std::vector<std::set<int>>& geometric_unprintables, std::vector<std::set<int>>& unprintable_limits)
{
unprintable_limits.clear();

View File

@ -62,7 +62,7 @@ namespace Slic3r
std::vector<int> calc_max_group_size(const std::vector<std::map<int, int>>& ams_counts,bool ignore_ext_filament);
std::vector<std::vector<FilamentInfo>> build_machine_filaments(const std::vector<std::vector<DynamicPrintConfig>>& filament_configs);
std::vector<std::vector<FilamentInfo>> build_machine_filaments(const std::vector<std::vector<DynamicPrintConfig>>& filament_configs, const std::vector<std::map<int, int>>& ams_counts, bool ignore_ext_filament);
bool collect_unprintable_limits(const std::vector<std::set<int>>& physical_unprintables, const std::vector<std::set<int>>& geometric_unprintables, std::vector<std::set<int>>& unprintable_limits);

View File

@ -969,13 +969,15 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
};
std::vector<int>ret(filament_nums, 0);
bool ignore_ext_filament = false; // TODO: read from config
// if mutli_extruder, calc group,otherwise set to 0
if (extruder_nums == 2) {
std::vector<std::string> extruder_ams_count_str = print_config.extruder_ams_count.values;
auto extruder_ams_counts = get_extruder_ams_count(extruder_ams_count_str);
std::vector<int> group_size = calc_max_group_size(extruder_ams_counts, false);
std::vector<int> group_size = calc_max_group_size(extruder_ams_counts, ignore_ext_filament);
auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament);
auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info());
std::vector<std::string> filament_types = print_config.filament_type.values;
std::vector<std::string> filament_colours = print_config.filament_colour.values;
@ -985,12 +987,12 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode: FGMode::FlushMode;
std::vector<std::set<int>> ext_unprintable_filaments;
collect_unprintable_limits(physical_unprintables, geometric_unprintables, ext_unprintable_filaments); // TODO: throw exception if fail or set it to status
collect_unprintable_limits(physical_unprintables, geometric_unprintables, ext_unprintable_filaments);
FilamentGroupContext context;
{
context.model_info.flush_matrix = std::move(nozzle_flush_mtx);
context.model_info.unprintable_filaments = ext_unprintable_filaments; // TODO:
context.model_info.unprintable_filaments = ext_unprintable_filaments;
context.model_info.layer_filaments = layer_filaments;
context.model_info.filament_colors = filament_colours;
context.model_info.filament_types = filament_types;
@ -1003,7 +1005,7 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
context.group_info.max_gap_threshold = 0.01;
context.group_info.strategy = FGStrategy::BestCost;
context.group_info.mode = fg_mode;
context.group_info.ignore_ext_filament = false; // TODO:
context.group_info.ignore_ext_filament = ignore_ext_filament;
}