diff --git a/src/libslic3r/FilamentGroup.cpp b/src/libslic3r/FilamentGroup.cpp index 675f64a11..6b932df3d 100644 --- a/src/libslic3r/FilamentGroup.cpp +++ b/src/libslic3r/FilamentGroup.cpp @@ -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& used_filaments,const FilamentGroupContext& ctx, std::vector& filament_map) + std::vector optimize_group_for_master_extruder(const std::vector& used_filaments,const FilamentGroupContext& ctx, std::vector& filament_map) { + std::vector ret = filament_map; std::unordered_map> 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 select_best_group_for_ams(const std::vector>& map_lists, const std::vector& used_filaments, const std::vector& used_filament_colors_, const std::vector>& ams_filament_colors_,const double color_threshold) { using namespace FlushPredict; - std::vectorused_filament_colors; + std::vectorused_filament_colors=used_filament_colors_; std::vector>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 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::max(); std::vectorbest_map; for (auto& map : map_lists) { @@ -169,7 +162,7 @@ namespace Slic3r std::vectorl_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(r_nodes.size(),l_nodes.size())); auto ams_map = mcmf.solve(); for (size_t idx = 0; idx < ams_map.size(); ++idx) { @@ -519,11 +512,11 @@ namespace Slic3r std::vectormachine_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::vectorextruder_filament_count(2, 0); @@ -665,12 +658,13 @@ namespace Slic3r auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); std::vector ret = calc_min_flush_group(cost); - - optimize_group_for_master_extruder(used_filaments, ctx, ret); // ignore the return value - std::vector> memoryed_maps = this->m_memoryed_groups; memoryed_maps.insert(memoryed_maps.begin(), ret); + std::vector 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 used_colors; for (const auto& f : used_filaments) used_colors.push_back(Color(ctx.model_info.filament_colors[f])); @@ -678,9 +672,9 @@ namespace Slic3r std::vector> 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) - ams_colors.back().push_back(info.color); + 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); diff --git a/src/libslic3r/FilamentGroup.hpp b/src/libslic3r/FilamentGroup.hpp index 8dc61e64c..da72d2b20 100644 --- a/src/libslic3r/FilamentGroup.hpp +++ b/src/libslic3r/FilamentGroup.hpp @@ -95,7 +95,7 @@ namespace Slic3r std::vector select_best_group_for_ams(const std::vector>& map_lists, const std::vector& used_filaments, const std::vector& used_filament_colors_, const std::vector>& ams_filament_colros_,const double color_delta_threshold = 20); - bool optimize_group_for_master_extruder(const std::vector& used_filaments, const FilamentGroupContext& ctx, std::vector& filament_map); + std::vector optimize_group_for_master_extruder(const std::vector& used_filaments, const FilamentGroupContext& ctx, const std::vector& filament_map); bool can_swap_groups(const int extruder_id_0, const std::set& group_0, const int extruder_id_1, const std::set& group_1, const FilamentGroupContext& ctx); diff --git a/src/libslic3r/FilamentGroupUtils.cpp b/src/libslic3r/FilamentGroupUtils.cpp index 3f2bb5c5f..e8077bb18 100644 --- a/src/libslic3r/FilamentGroupUtils.cpp +++ b/src/libslic3r/FilamentGroupUtils.cpp @@ -71,7 +71,7 @@ namespace FilamentGroupUtils } - std::vector> build_machine_filaments(const std::vector>& filament_configs) + static std::vector> build_full_machine_filaments(const std::vector>& filament_configs) { // defualt size set to 2 std::vector> 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("filament_colour"); color_ptr) @@ -90,7 +90,10 @@ namespace FilamentGroupUtils if (auto tray_ptr = item.option("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> build_machine_filaments(const std::vector>& filament_configs, const std::vector>& ams_counts, bool ignore_ext_filament) + { + std::vector> ret(2); + std::vector ams_size(2, 0); + std::vector> 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 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>& physical_unprintables, const std::vector>& geometric_unprintables, std::vector>& unprintable_limits) { unprintable_limits.clear(); diff --git a/src/libslic3r/FilamentGroupUtils.hpp b/src/libslic3r/FilamentGroupUtils.hpp index 533613ff2..76430957c 100644 --- a/src/libslic3r/FilamentGroupUtils.hpp +++ b/src/libslic3r/FilamentGroupUtils.hpp @@ -62,7 +62,7 @@ namespace Slic3r std::vector calc_max_group_size(const std::vector>& ams_counts,bool ignore_ext_filament); - std::vector> build_machine_filaments(const std::vector>& filament_configs); + std::vector> build_machine_filaments(const std::vector>& filament_configs, const std::vector>& ams_counts, bool ignore_ext_filament); bool collect_unprintable_limits(const std::vector>& physical_unprintables, const std::vector>& geometric_unprintables, std::vector>& unprintable_limits); diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 7ce9a966d..1948e5e7a 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -969,13 +969,15 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vectorret(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 extruder_ams_count_str = print_config.extruder_ams_count.values; auto extruder_ams_counts = get_extruder_ams_count(extruder_ams_count_str); - std::vector group_size = calc_max_group_size(extruder_ams_counts, false); + std::vector 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 filament_types = print_config.filament_type.values; std::vector filament_colours = print_config.filament_colour.values; @@ -985,12 +987,12 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vector> 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 ToolOrdering::get_recommended_filament_maps(const std::vector