diff --git a/src/libslic3r/FilamentGroup.cpp b/src/libslic3r/FilamentGroup.cpp index 846b80996..cb1a8eac0 100644 --- a/src/libslic3r/FilamentGroup.cpp +++ b/src/libslic3r/FilamentGroup.cpp @@ -116,17 +116,15 @@ namespace Slic3r * * @param map_lists Group list with similar flush count * @param used_filaments Idx of used filaments - * @param used_filament_colors Colors of used filaments - * @param used_filament_types Filament types of used filaments + * @param used_filament_info Information of filaments used * @param machine_filament_info Information of filaments loaded in printer * @param color_threshold Threshold for considering colors to be similar * @return The group that best fits the filament distribution in AMS */ 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& used_filament_types, - const std::vector>& machine_filament_info, + const std::vector& used_filament_info, + const std::vector>& machine_filament_info_, const double color_threshold) { using namespace FlushPredict; @@ -135,16 +133,9 @@ namespace Slic3r const int fail_cost = 9999; - std::vector>ams_filament_colors(2); - std::vector> ams_filament_types(2); - - for (size_t idx = 0; idx < std::min(ams_filament_colors.size(), machine_filament_info.size()); ++idx) { - for (size_t j = 0; j < machine_filament_info[idx].size(); ++j) { - ams_filament_colors[idx].emplace_back(machine_filament_info[idx][j].color); - ams_filament_types[idx].emplace_back(machine_filament_info[idx][j].type); - } - } - + // these code is to make we machine filament info size is 2 + std::vector> machine_filament_info = machine_filament_info_; + machine_filament_info.resize(2); int best_cost = std::numeric_limits::max(); std::vectorbest_map; @@ -155,7 +146,7 @@ namespace Slic3r for (size_t i = 0; i < used_filaments.size(); ++i) { int target_group = map[used_filaments[i]] == 0 ? 0 : 1; - group_colors[target_group].emplace_back(used_filament_colors[i]); + group_colors[target_group].emplace_back(used_filament_info[i].color); group_filaments[target_group].emplace_back(i); } @@ -163,31 +154,32 @@ namespace Slic3r for (size_t i = 0; i < 2; ++i) { if (group_colors[i].empty()) continue; - if (ams_filament_colors.empty()) { + if (machine_filament_info[i].empty()) { group_cost += group_colors.size() * fail_cost; continue; } - std::vector>distance_matrix(group_colors[i].size(), std::vector(ams_filament_colors[i].size())); + std::vector>distance_matrix(group_colors[i].size(), std::vector(machine_filament_info[i].size())); // calculate color distance matrix for (size_t src = 0; src < group_colors[i].size(); ++src) { - for (size_t dst = 0; dst < ams_filament_colors[i].size(); ++dst) { + for (size_t dst = 0; dst < machine_filament_info[i].size(); ++dst) { distance_matrix[src][dst] = calc_color_distance( RGBColor(group_colors[i][src].r, group_colors[i][src].g, group_colors[i][src].b), - RGBColor(ams_filament_colors[i][dst].r, ams_filament_colors[i][dst].g, ams_filament_colors[i][dst].b) + RGBColor(machine_filament_info[i][dst].color.r, machine_filament_info[i][dst].color.g, machine_filament_info[i][dst].color.b) ); } } // get min cost by min cost max flow - std::vectorl_nodes(group_colors[i].size()), r_nodes(ams_filament_colors[i].size()); + std::vectorl_nodes(group_colors[i].size()), r_nodes(machine_filament_info[i].size()); std::iota(l_nodes.begin(), l_nodes.end(), 0); std::iota(r_nodes.begin(), r_nodes.end(), 0); std::unordered_map>unlink_limits; for (size_t from = 0; from < group_filaments[i].size(); ++from) { - for (size_t to = 0; to < ams_filament_types[i].size(); ++to) { - if (used_filament_types[group_filaments[i][from]] != ams_filament_types[i][to]) { + for (size_t to = 0; to < machine_filament_info[i].size(); ++to) { + if (used_filament_info[group_filaments[i][from]].type != machine_filament_info[i][to].type || + used_filament_info[group_filaments[i][from]].is_support != machine_filament_info[i][to].is_support) { unlink_limits[from].emplace_back(to); } } @@ -504,16 +496,12 @@ namespace Slic3r using namespace FlushPredict; auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); - std::vector used_colors; - std::vector used_types; + std::vector used_filament_list; + for (auto f : used_filaments) + used_filament_list.emplace_back(ctx.model_info.filament_info[f]); - for (auto& f : used_filaments) { - used_colors.emplace_back(Color(ctx.model_info.filament_colors[f])); - used_types.emplace_back(ctx.model_info.filament_types[f]); - } - - std::vector machine_filament_list; - std::map> machine_filament_set; + std::vector machine_filament_list; + std::map> machine_filament_set; for (size_t eid = 0; eid < ctx.machine_info.machine_filament_info.size();++eid) { for (auto& filament : ctx.machine_info.machine_filament_info[eid]) { machine_filament_set[filament].insert(machine_filament_list.size()); @@ -527,11 +515,11 @@ namespace Slic3r std::map unprintable_limit_indices; // key stores filament idx in used_filament, value stores unprintable extruder extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unprintable_limit_indices); - std::vector> color_dist_matrix(used_colors.size(), std::vector(machine_filament_list.size())); - for (size_t i = 0; i < used_colors.size(); ++i) { + std::vector> color_dist_matrix(used_filament_list.size(), std::vector(machine_filament_list.size())); + for (size_t i = 0; i < used_filament_list.size(); ++i) { for (size_t j = 0; j < machine_filament_list.size(); ++j) { color_dist_matrix[i][j] = calc_color_distance( - RGBColor(used_colors[i].r, used_colors[i].g, used_colors[i].b), + RGBColor(used_filament_list[i].color.r, used_filament_list[i].color.g, used_filament_list[i].color.b), RGBColor(machine_filament_list[j].color.r, machine_filament_list[j].color.g, machine_filament_list[j].color.b) ); } @@ -632,8 +620,9 @@ namespace Slic3r std::vector group(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); std::vector ungrouped_filaments; - auto unlink_limits_full = build_unlink_limits(l_nodes, r_nodes, [&used_types, &machine_filament_list, is_extruder_filament_compatible](int used_filament_idx, int machine_filament_idx) { - return used_types[used_filament_idx] == machine_filament_list[machine_filament_idx].type && + auto unlink_limits_full = build_unlink_limits(l_nodes, r_nodes, [&used_filament_list, &machine_filament_list, is_extruder_filament_compatible](int used_filament_idx, int machine_filament_idx) { + return used_filament_list[used_filament_idx].type == machine_filament_list[machine_filament_idx].type && + used_filament_list[used_filament_idx].is_support == machine_filament_list[machine_filament_idx].is_support && is_extruder_filament_compatible(used_filament_idx, machine_filament_list[machine_filament_idx].extruder_id); }); @@ -697,14 +686,12 @@ namespace Slic3r if (optimized_ret != ret) memoryed_maps.insert(memoryed_maps.begin(), optimized_ret); - std::vector used_colors; - std::vector used_types; - for (const auto& f : used_filaments) { - used_colors.push_back(Color(ctx.model_info.filament_colors[f])); - used_types.push_back(ctx.model_info.filament_types[f]); + std::vector used_filament_info; + for (auto f : used_filaments) { + used_filament_info.emplace_back(ctx.model_info.filament_info[f]); } - ret = select_best_group_for_ams(memoryed_maps, used_filaments, used_colors,used_types, ctx.machine_info.machine_filament_info); + ret = select_best_group_for_ams(memoryed_maps, used_filaments, used_filament_info, ctx.machine_info.machine_filament_info); return ret; } diff --git a/src/libslic3r/FilamentGroup.hpp b/src/libslic3r/FilamentGroup.hpp index 8a900265b..646e98c0c 100644 --- a/src/libslic3r/FilamentGroup.hpp +++ b/src/libslic3r/FilamentGroup.hpp @@ -72,8 +72,7 @@ namespace Slic3r struct ModelInfo { std::vector flush_matrix; std::vector> layer_filaments; - std::vector filament_colors; - std::vector filament_types; + std::vector filament_info; std::vector> unprintable_filaments; } model_info; @@ -87,7 +86,7 @@ namespace Slic3r struct MachineInfo { std::vector max_group_size; - std::vector> machine_filament_info; + std::vector> machine_filament_info; std::vector, int>> extruder_group_size; int master_extruder_id; } machine_info; @@ -95,9 +94,8 @@ 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& used_filament_types, - const std::vector>& machine_filament_info, + const std::vector& used_filament_info, + const std::vector>& machine_filament_info, const double color_delta_threshold = 20); std::vector optimize_group_for_master_extruder(const std::vector& used_filaments, const FilamentGroupContext& ctx, const std::vector& filament_map); diff --git a/src/libslic3r/FilamentGroupUtils.cpp b/src/libslic3r/FilamentGroupUtils.cpp index e8077bb18..309cd5e85 100644 --- a/src/libslic3r/FilamentGroupUtils.cpp +++ b/src/libslic3r/FilamentGroupUtils.cpp @@ -45,10 +45,11 @@ namespace FilamentGroupUtils return r != other.r || g != other.g || b != other.b || a != other.a; } - bool FilamentInfo::operator<(const FilamentInfo& other) const + bool MachineFilamentInfo::operator<(const MachineFilamentInfo& other) const { if (color != other.color) return color < other.color; - return type < other.type; + if (type != other.type) return type < other.type; + return is_support > build_full_machine_filaments(const std::vector>& filament_configs) + static std::vector> build_full_machine_filaments(const std::vector>& filament_configs) { + auto extract_filament_type = [](const std::string& s)->std::string { + std::regex r1(R"(^Sup.(\w+)$)"); + std::regex r2(R"(^(\w+)-S$)"); + + std::smatch m; + if (std::regex_match(s, m, r1)) + return m[1].str(); + if (std::regex_match(s, m, r2)) + return m[1].str(); + return s; + }; + + // change filament type to type format in preset // defualt size set to 2 - std::vector> machine_filaments(2); + std::vector> machine_filaments(2); for (size_t idx = 0; idx < filament_configs.size(); ++idx) { auto& arr = filament_configs[idx]; for (auto& item : arr) { - FilamentInfo temp; + MachineFilamentInfo temp; std::string type; std::string color; std::string tray_name; + bool is_support_filament = false; if (auto color_ptr = item.option("filament_colour"); color_ptr) color = color_ptr->get_at(0); - if (auto type_ptr = item.option("filament_type"); type_ptr) + if (auto type_ptr = item.option("filament_type"); type_ptr) { type = type_ptr->get_at(0); + type = extract_filament_type(type); + } if (auto tray_ptr = item.option("tray_name"); tray_ptr) tray_name = tray_ptr->get_at(0); + if (auto support_ptr = item.option("filament_is_support"); support_ptr) + is_support_filament = support_ptr->get_at(0); if (color.empty() || type.empty() || tray_name.empty()) continue; @@ -97,17 +116,18 @@ namespace FilamentGroupUtils temp.type =type; temp.extruder_id = idx; temp.is_extended = tray_name == "Ext"; // hard-coded ext flag + temp.is_support = is_support_filament; machine_filaments[idx].emplace_back(std::move(temp)); } } return machine_filaments; } - std::vector> build_machine_filaments(const std::vector>& filament_configs, const std::vector>& ams_counts, bool ignore_ext_filament) + 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> ret(2); std::vector ams_size(2, 0); - std::vector> full_machine_filaments = build_full_machine_filaments(filament_configs); + 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]; @@ -118,16 +138,22 @@ namespace FilamentGroupUtils 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; - + std::vector tmp; 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) + auto& machine_filament = full_machine_filaments[idx][j]; + if (!machine_filament.is_extended) tmp.emplace_back(machine_filament); } + + // if do not have valid ams filament, try to use ext filament + if (tmp.empty() && !ignore_ext_filament) { + for (size_t j = 0; j < full_machine_filaments[idx].size(); ++j) { + auto& machine_filament = full_machine_filaments[idx][j]; + if (machine_filament.is_extended) + tmp.emplace_back(machine_filament); + } + } + ret[idx] = std::move(tmp); } return ret; diff --git a/src/libslic3r/FilamentGroupUtils.hpp b/src/libslic3r/FilamentGroupUtils.hpp index 76430957c..b42de01a0 100644 --- a/src/libslic3r/FilamentGroupUtils.hpp +++ b/src/libslic3r/FilamentGroupUtils.hpp @@ -29,9 +29,13 @@ namespace Slic3r struct FilamentInfo { Color color; std::string type; + bool is_support; + }; + + struct MachineFilamentInfo: public FilamentInfo { int extruder_id; bool is_extended; - bool operator<(const FilamentInfo& other) const; + bool operator<(const MachineFilamentInfo& other) const; }; @@ -62,7 +66,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, const std::vector>& ams_counts, bool ignore_ext_filament); + 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 18fdd1f50..a9af4a01d 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -1007,6 +1007,7 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vector filament_types = print_config.filament_type.values; std::vector filament_colours = print_config.filament_colour.values; + std::vector filament_is_support = print_config.filament_is_support.values; // speacially handle tpu filaments auto used_filaments = collect_sorted_used_filaments(layer_filaments); @@ -1021,8 +1022,14 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vector PresetBundle::get_filament_by_filament_id(const std::string& filament_id) const +{ + if (filament_id.empty()) + return {}; + + // basic filament info should be same in the parent preset and child preset + // so just match the filament id is enough + + for (auto iter = filaments.begin(); iter != filaments.end(); ++iter) { + const Preset& filament_preset = *iter; + const auto& config = filament_preset.config; + if (filament_preset.filament_id == filament_id) { + FilamentBaseInfo info; + info.filament_id = filament_id; + info.is_system = filament_preset.is_system; + info.filament_name = filament_preset.alias; + if (config.has("filament_is_support")) + info.is_support = config.option("filament_is_support")->values[0]; + if (config.has("filament_type")) + info.filament_type = config.option("filament_type")->values[0]; + if (config.has("filament_vendor")) + info.vendor = config.option("filament_vendor")->values[0]; + if (config.has("nozzle_temperature_range_high")) + info.nozzle_temp_range_high = config.option("nozzle_temperature_range_high")->values[0]; + if (config.has("nozzle_temperature_range_low")) + info.nozzle_temp_range_low = config.option("nozzle_temperature_range_low")->values[0]; + return info; + } + } + return {}; +} + //BBS: load project embedded presets PresetsConfigSubstitutions PresetBundle::load_project_embedded_presets(std::vector project_presets, ForwardCompatibilitySubstitutionRule substitution_rule) { diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index 916c05310..8f945af70 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -47,6 +47,20 @@ struct MergeFilamentInfo { std::vector> merges; bool is_empty() { return merges.empty();} }; + + +struct FilamentBaseInfo +{ + std::string filament_name; + std::string filament_id; + std::string filament_type; + std::string vendor; + int nozzle_temp_range_low; + int nozzle_temp_range_high; + bool is_support; + bool is_system; +}; + // Bundle of Print + Filament + Printer presets. class PresetBundle { @@ -104,9 +118,12 @@ public: Preset* get_preset_differed_for_save(Preset& preset); int get_differed_values_to_update(Preset& preset, std::map& key_values); + //BBS: get vendor's current version Semver get_vendor_profile_version(std::string vendor_name); + std::optional get_filament_by_filament_id(const std::string& filament_id) const; + //BBS: project embedded preset logic PresetsConfigSubstitutions load_project_embedded_presets(std::vector project_presets, ForwardCompatibilitySubstitutionRule substitution_rule); std::vector get_current_project_embedded_presets(); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 509b38960..5823d1973 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -2800,8 +2800,9 @@ std::map Sidebar::build_filament_ams_list(MachineObject tray_config.set_key_value("tray_name", new ConfigOptionStrings{ name }); tray_config.set_key_value("filament_colour", new ConfigOptionStrings{into_u8(wxColour("#" + tray.color).GetAsString(wxC2S_HTML_SYNTAX))}); tray_config.set_key_value("filament_exist", new ConfigOptionBools{tray.is_exists}); - tray_config.set_key_value("filament_multi_colors", new ConfigOptionStrings{}); + auto info = wxGetApp().preset_bundle->get_filament_by_filament_id(tray.setting_id); + tray_config.set_key_value("filament_is_support", new ConfigOptionBools{ info ? info->is_support : false }); for (int i = 0; i < tray.cols.size(); ++i) { tray_config.opt("filament_multi_colors")->values.push_back(into_u8(wxColour("#" + tray.cols[i]).GetAsString(wxC2S_HTML_SYNTAX))); }