ENH: seperate statitics for auto for flush mode

1.Compare stats of AutoForFlush with other filament map modes
2.Refine the function signature of filament group

jira:NONE

Signed-off-by: xun.zhang <xun.zhang@bambulab.com>
Change-Id: Iec2aff069d8c44343df8b82f045c61354c7d1c2a
This commit is contained in:
xun.zhang 2024-12-23 19:50:56 +08:00 committed by lane.wei
parent d27304e5ef
commit 95e49986f3
6 changed files with 53 additions and 58 deletions

View File

@ -2297,8 +2297,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
{
// save the flush statitics stored in tool ordering by object
print.m_statistics_by_extruder_count.stats_by_single_extruder += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::SingleExt);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_auto += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtAuto);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_manual += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtManual);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_best += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtBest);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_curr += tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtCurr);
// save sorted filament sequences
const auto& layer_tools = tool_ordering.layer_tools();
for (const auto& lt : layer_tools)
@ -2379,8 +2379,8 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
{
//save the flush statitics stored in tool ordering
print.m_statistics_by_extruder_count.stats_by_single_extruder = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::SingleExt);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_auto = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtAuto);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_manual = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtManual);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_best = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtBest);
print.m_statistics_by_extruder_count.stats_by_multi_extruder_curr = tool_ordering.get_filament_change_stats(ToolOrdering::FilamentChangeMode::MultiExtCurr);
// save sorted filament sequences
const auto& layer_tools = tool_ordering.layer_tools();
for (const auto& lt : layer_tools)

View File

@ -1009,19 +1009,20 @@ float get_flush_volume(const std::vector<int> &filament_maps, const std::vector<
return flush_volume;
}
std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const PrintConfig* print_config, const Print* print, const std::vector<std::set<int>>&physical_unprintables,const std::vector<std::set<int>>&geometric_unprintables)
std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const Print* print, const FilamentMapMode mode,const std::vector<std::set<int>>&physical_unprintables,const std::vector<std::set<int>>&geometric_unprintables)
{
using namespace FilamentGroupUtils;
if (!print_config || layer_filaments.empty())
if (!print || layer_filaments.empty())
return std::vector<int>();
const unsigned int filament_nums = (unsigned int)(print_config->filament_colour.values.size() + EPSILON);
const auto& print_config = print->config();
const unsigned int filament_nums = (unsigned int)(print_config.filament_colour.values.size() + EPSILON);
// get flush matrix
std::vector<FlushMatrix> nozzle_flush_mtx;
size_t extruder_nums = print_config->nozzle_diameter.values.size();
size_t extruder_nums = print_config.nozzle_diameter.values.size();
for (size_t nozzle_id = 0; nozzle_id < extruder_nums; ++nozzle_id) {
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(print_config->flush_volumes_matrix.values, nozzle_id, extruder_nums)));
std::vector<float> flush_matrix(cast<float>(get_flush_volumes_matrix(print_config.flush_volumes_matrix.values, nozzle_id, extruder_nums)));
std::vector<std::vector<float>> wipe_volumes;
for (unsigned int i = 0; i < filament_nums; ++i)
wipe_volumes.push_back(std::vector<float>(flush_matrix.begin() + i * filament_nums, flush_matrix.begin() + (i + 1) * filament_nums));
@ -1029,14 +1030,7 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
nozzle_flush_mtx.emplace_back(wipe_volumes);
}
std::vector<LayerPrintSequence> other_layers_seqs;
const ConfigOptionInts* other_layers_print_sequence_op = print_config->option<ConfigOptionInts>("other_layers_print_sequence");
const ConfigOptionInt* other_layers_print_sequence_nums_op = print_config->option<ConfigOptionInt>("other_layers_print_sequence_nums");
if (other_layers_print_sequence_op && other_layers_print_sequence_nums_op) {
const std::vector<int>& print_sequence = other_layers_print_sequence_op->values;
int sequence_nums = other_layers_print_sequence_nums_op->value;
other_layers_seqs = get_other_layers_print_sequence(sequence_nums, print_sequence);
}
std::vector<LayerPrintSequence> other_layers_seqs = get_other_layers_print_sequence(print_config.other_layers_print_sequence_nums.value, print_config.other_layers_print_sequence.values);
// other_layers_seq: the layer_idx and extruder_idx are base on 1
auto get_custom_seq = [&other_layers_seqs](int layer_idx, std::vector<int>& out_seq) -> bool {
@ -1053,18 +1047,18 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
std::vector<int>ret(filament_nums, 0);
// 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;
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);
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;
std::vector<std::string> filament_types = print_config.filament_type.values;
std::vector<std::string> filament_colours = print_config.filament_colour.values;
// speacially handle tpu filaments
auto used_filaments = collect_sorted_used_filaments(layer_filaments);
auto tpu_filaments = get_filament_by_type(used_filaments, print_config, "TPU");
FGMode fg_mode = print_config->filament_map_mode.value == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode: FGMode::FlushMode;
auto tpu_filaments = get_filament_by_type(used_filaments, &print_config, "TPU");
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
@ -1079,7 +1073,7 @@ std::vector<int> ToolOrdering::get_recommended_filament_maps(const std::vector<s
context.machine_info.machine_filament_info = machine_filament_info;
context.machine_info.max_group_size = std::move(group_size);
context.machine_info.master_extruder_id = print_config->master_extruder_id.value - 1; // switch to 0 based idx
context.machine_info.master_extruder_id = print_config.master_extruder_id.value - 1; // switch to 0 based idx
context.group_info.total_filament_num = (int)(filament_nums);
context.group_info.max_gap_threshold = 0.01;
@ -1108,10 +1102,10 @@ FilamentChangeStats ToolOrdering::get_filament_change_stats(FilamentChangeMode m
{
case Slic3r::ToolOrdering::SingleExt:
return m_stats_by_single_extruder;
case Slic3r::ToolOrdering::MultiExtAuto:
return m_stats_by_multi_extruder_auto;
case Slic3r::ToolOrdering::MultiExtManual:
return m_stats_by_multi_extruder_manual;
case Slic3r::ToolOrdering::MultiExtBest:
return m_stats_by_multi_extruder_best;
case Slic3r::ToolOrdering::MultiExtCurr:
return m_stats_by_multi_extruder_curr;
default:
break;
}
@ -1166,7 +1160,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
print_config = &(m_print_object_ptr->print()->config());
}
filament_maps = ToolOrdering::get_recommended_filament_maps(layer_filaments, print_config, m_print, physical_unprintables, geometric_unprintables);
filament_maps = ToolOrdering::get_recommended_filament_maps(layer_filaments, m_print, map_mode, physical_unprintables, geometric_unprintables);
if (filament_maps.empty())
return;
@ -1235,10 +1229,11 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
auto curr_flush_info = calc_filament_change_info_by_toolorder(print_config, filament_maps, nozzle_flush_mtx, filament_sequences);
if (nozzle_nums <= 1)
m_stats_by_single_extruder = curr_flush_info;
else if (map_mode < fmmManual)
m_stats_by_multi_extruder_auto = curr_flush_info;
else if (map_mode == fmmManual)
m_stats_by_multi_extruder_manual = curr_flush_info;
else {
m_stats_by_multi_extruder_curr = curr_flush_info;
if (map_mode == fmmAutoForFlush)
m_stats_by_multi_extruder_best = curr_flush_info;
}
// in multi extruder mode,collect data with other mode
if (nozzle_nums > 1) {
@ -1258,11 +1253,11 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
);
m_stats_by_single_extruder = calc_filament_change_info_by_toolorder(print_config, maps_without_group, nozzle_flush_mtx, filament_sequences_one_extruder);
}
// if in manual mode,also calculate the info by auto mode
if (map_mode == fmmManual)
// if not in best for flush mode,also calculate the info by best for flush mode
if (map_mode != fmmAutoForFlush)
{
std::vector<std::vector<unsigned int>>filament_sequences_one_extruder;
std::vector<int>filament_maps_auto = get_recommended_filament_maps(layer_filaments, print_config, m_print, physical_unprintables, geometric_unprintables);
std::vector<int>filament_maps_auto = get_recommended_filament_maps(layer_filaments, m_print, fmmAutoForFlush, physical_unprintables, geometric_unprintables);
reorder_filaments_for_minimum_flush_volume(
filament_lists,
filament_maps_auto,
@ -1271,7 +1266,7 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
get_custom_seq,
&filament_sequences_one_extruder
);
m_stats_by_multi_extruder_auto = calc_filament_change_info_by_toolorder(print_config, filament_maps_auto, nozzle_flush_mtx, filament_sequences_one_extruder);
m_stats_by_multi_extruder_best = calc_filament_change_info_by_toolorder(print_config, filament_maps_auto, nozzle_flush_mtx, filament_sequences_one_extruder);
}
}

View File

@ -182,8 +182,8 @@ class ToolOrdering
public:
enum FilamentChangeMode {
SingleExt,
MultiExtAuto,
MultiExtManual
MultiExtBest,
MultiExtCurr
};
ToolOrdering() = default;
@ -204,8 +204,8 @@ public:
void clear() {
m_layer_tools.clear();
m_stats_by_single_extruder.clear();
m_stats_by_multi_extruder_auto.clear();
m_stats_by_multi_extruder_manual.clear();
m_stats_by_multi_extruder_best.clear();
m_stats_by_multi_extruder_curr.clear();
}
// Only valid for non-sequential print:
@ -240,7 +240,7 @@ public:
* called in dual extruder mode, the value in map will be 0 or 1
* 0 based group id
*/
static std::vector<int> get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const PrintConfig* print_config, const Print* print, const std::vector<std::set<int>>& physical_unprintables, const std::vector<std::set<int>>& geometric_unprintables);
static std::vector<int> get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const Print* print,const FilamentMapMode mode, const std::vector<std::set<int>>& physical_unprintables, const std::vector<std::set<int>>& geometric_unprintables);
static std::vector<std::set<int>> get_physical_unprintables(const std::vector<unsigned int>& layer_filaments, const PrintConfig* config);
static std::vector<std::set<int>> get_geometrical_unprintables(const std::vector<std::vector<int>>& unprintable_arrs, const PrintConfig* config);
@ -281,8 +281,8 @@ private:
bool m_sorted = false;
FilamentChangeStats m_stats_by_single_extruder;
FilamentChangeStats m_stats_by_multi_extruder_manual;
FilamentChangeStats m_stats_by_multi_extruder_auto;
FilamentChangeStats m_stats_by_multi_extruder_curr;
FilamentChangeStats m_stats_by_multi_extruder_best;
};
} // namespace SLic3r

View File

@ -1882,7 +1882,7 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
auto map_mode = get_filament_map_mode();
// get recommended filament map
if (map_mode < FilamentMapMode::fmmManual) {
filament_maps = ToolOrdering::get_recommended_filament_maps(all_filaments, &config(), this, physical_unprintables, geometric_unprintables);
filament_maps = ToolOrdering::get_recommended_filament_maps(all_filaments, this, map_mode, physical_unprintables, geometric_unprintables);
std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; });
update_filament_maps_to_config(filament_maps);
}

View File

@ -699,12 +699,12 @@ struct StatisticsByExtruderCount
{
// flush weight comes first,then comes filament change time
FilamentChangeStats stats_by_single_extruder;
FilamentChangeStats stats_by_multi_extruder_auto;
FilamentChangeStats stats_by_multi_extruder_manual;
FilamentChangeStats stats_by_multi_extruder_best;
FilamentChangeStats stats_by_multi_extruder_curr;
void clear() {
stats_by_single_extruder.clear();
stats_by_multi_extruder_auto.clear();
stats_by_multi_extruder_manual.clear();
stats_by_multi_extruder_best.clear();
stats_by_multi_extruder_curr.clear();
}
};

View File

@ -4668,8 +4668,8 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
auto is_auto = filament_map_mode < FilamentMapMode::fmmManual;
bool has_tips = true;
if (is_auto) {
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_auto.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_auto.filament_change_count;
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_curr.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_curr.filament_change_count;
if (!(saved_flush_weight > EPSILON || saved_filament_changed_time > 0)) has_tips = false;
}
// BBS AMS containers
@ -4744,16 +4744,16 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
}
return static_cast<int>(num);
};
if (filament_map_mode < fmmManual) {
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_auto.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_auto.filament_change_count;
if (filament_map_mode == fmmAutoForFlush) {
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_best.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_best.filament_change_count;
if (saved_flush_weight > EPSILON || saved_filament_changed_time > 0) {
imgui.text(_u8L("This arrangement would be optimal."));
imgui.text_wrapped(from_u8((boost::format(_u8L("Save %1%g filament and %2% changes than one-extruder printer.")) % number_format(saved_flush_weight) % saved_filament_changed_time).str()), parent_width);
}
} else if (filament_map_mode == fmmManual) {
float more_cost = stats_by_extruder.stats_by_multi_extruder_manual.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_auto.filament_flush_weight;
int more_time = stats_by_extruder.stats_by_multi_extruder_manual.filament_change_count - stats_by_extruder.stats_by_multi_extruder_auto.filament_change_count;
} else if (filament_map_mode != fmmAutoForFlush) {
float more_cost = stats_by_extruder.stats_by_multi_extruder_curr.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_best.filament_flush_weight;
int more_time = stats_by_extruder.stats_by_multi_extruder_curr.filament_change_count - stats_by_extruder.stats_by_multi_extruder_best.filament_change_count;
if (more_cost > EPSILON || more_time > 0) {
is_optimal_group = false;
@ -4763,8 +4763,8 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
imgui.text_wrapped(from_u8((boost::format(_u8L("Cost %1%g filament and %2% changes more than optimal arrangement.")) % number_format(more_cost) % more_time).str()), parent_width);
ImGui::PopStyleColor(1);
} else {
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_auto.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_auto.filament_change_count;
float saved_flush_weight = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_best.filament_flush_weight;
int saved_filament_changed_time = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_best.filament_change_count;
if (saved_flush_weight > EPSILON || saved_filament_changed_time > 0) {
imgui.text(_u8L("This arrangement would be optimal."));
imgui.text_wrapped(from_u8((boost::format(_u8L("Save %1%g filament and %2% changes than one-extruder printer.")) % number_format(saved_flush_weight) % saved_filament_changed_time).str()), parent_width);