ENH: add filament saved by multi extruder
1.Add filament flush,filament change count reduced by multi extruder NTOE: cases when printing by object haven't been handled jira:NONE Signed-off-by: xun.zhang <xun.zhang@bambulab.com> Change-Id: Iaaea5f8ffae2345df5a6f1dc605342d835974d48
This commit is contained in:
parent
3a55a3a1ee
commit
ad65cdb909
|
@ -447,6 +447,37 @@ static double calc_max_layer_height(const PrintConfig &config, double max_object
|
||||||
return std::max(max_layer_height, max_object_layer_height);
|
return std::max(max_layer_height, max_object_layer_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//calculate the flush weight (first value) and filament change count(second value)
|
||||||
|
static std::pair<int,int> calc_filament_change_info_by_toolorder(const PrintConfig* config,const std::vector<int>&filament_map,const std::vector<FlushMatrix>&flush_matrix,const std::vector<std::vector<unsigned int>>&layer_sequences)
|
||||||
|
{
|
||||||
|
std::map<int, int> flush_volume_per_filament;
|
||||||
|
|
||||||
|
std::vector<unsigned int>last_filament_per_extruder(2, -1);
|
||||||
|
|
||||||
|
int total_filament_change_count = 0;
|
||||||
|
int total_filament_flush_weight = 0;
|
||||||
|
for (const auto& ls : layer_sequences) {
|
||||||
|
for (const auto& item : ls) {
|
||||||
|
int extruder_id = filament_map[item];
|
||||||
|
int last_filament = last_filament_per_extruder[extruder_id];
|
||||||
|
if (last_filament != -1 && last_filament != item) {
|
||||||
|
int flush_volume = flush_matrix[extruder_id][last_filament][item];
|
||||||
|
flush_volume_per_filament[item] += flush_volume;
|
||||||
|
total_filament_change_count += 1;
|
||||||
|
}
|
||||||
|
last_filament_per_extruder[extruder_id] = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& fv : flush_volume_per_filament) {
|
||||||
|
int weight = config->filament_density.get_at(fv.first) * 0.001 * fv.second;
|
||||||
|
total_filament_flush_weight += weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { total_filament_flush_weight,total_filament_change_count };
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// For the use case when each object is printed separately
|
// For the use case when each object is printed separately
|
||||||
// (print->config().print_sequence == PrintSequence::ByObject is true).
|
// (print->config().print_sequence == PrintSequence::ByObject is true).
|
||||||
ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
|
ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
|
||||||
|
@ -1315,6 +1346,26 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
|
||||||
&filament_sequences
|
&filament_sequences
|
||||||
);
|
);
|
||||||
|
|
||||||
|
auto curr_flush_info = calc_filament_change_info_by_toolorder(print_config, filament_maps, nozzle_flush_mtx, filament_sequences);
|
||||||
|
m_curr_flush_info = curr_flush_info;
|
||||||
|
|
||||||
|
if (nozzle_nums > 1) {
|
||||||
|
std::vector<std::vector<unsigned int>>filament_sequences_one_extruder;
|
||||||
|
auto maps_without_group = filament_maps;
|
||||||
|
for (auto& item : maps_without_group)
|
||||||
|
item = 0;
|
||||||
|
reorder_filaments_for_minimum_flush_volume(
|
||||||
|
filament_lists,
|
||||||
|
maps_without_group,
|
||||||
|
layer_filaments,
|
||||||
|
nozzle_flush_mtx,
|
||||||
|
get_custom_seq,
|
||||||
|
&filament_sequences_one_extruder
|
||||||
|
);
|
||||||
|
auto one_extruder_flush_info = calc_filament_change_info_by_toolorder(print_config, maps_without_group, nozzle_flush_mtx, filament_sequences_one_extruder);
|
||||||
|
m_one_extruder_flush_info = one_extruder_flush_info;
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < filament_sequences.size(); ++i)
|
for (size_t i = 0; i < filament_sequences.size(); ++i)
|
||||||
m_layer_tools[i].extruders = std::move(filament_sequences[i]);
|
m_layer_tools[i].extruders = std::move(filament_sequences[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,6 +156,10 @@ private:
|
||||||
class ToolOrdering
|
class ToolOrdering
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum FlushCalcMode {
|
||||||
|
Normal=0,
|
||||||
|
OneExtruder
|
||||||
|
};
|
||||||
ToolOrdering() = default;
|
ToolOrdering() = default;
|
||||||
|
|
||||||
// For the use case when each object is printed separately
|
// For the use case when each object is printed separately
|
||||||
|
@ -166,8 +170,10 @@ public:
|
||||||
// (print->config().print_sequence == PrintSequence::ByObject is false).
|
// (print->config().print_sequence == PrintSequence::ByObject is false).
|
||||||
ToolOrdering(const Print& print, unsigned int first_extruder, bool prime_multi_material = false);
|
ToolOrdering(const Print& print, unsigned int first_extruder, bool prime_multi_material = false);
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
m_layer_tools.clear(); m_tool_order_cache.clear();
|
m_layer_tools.clear();
|
||||||
|
m_curr_flush_info = { 0,0 };
|
||||||
|
m_one_extruder_flush_info = { 0,0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only valid for non-sequential print:
|
// Only valid for non-sequential print:
|
||||||
|
@ -199,6 +205,9 @@ public:
|
||||||
|
|
||||||
static std::vector<int> get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const PrintConfig *print_config);
|
static std::vector<int> get_recommended_filament_maps(const std::vector<std::vector<unsigned int>>& layer_filaments, const PrintConfig *print_config);
|
||||||
|
|
||||||
|
// first val: flush weight second val: change count
|
||||||
|
std::pair<int, int> get_flush_info(int mode) const { return mode == FlushCalcMode::OneExtruder ? m_one_extruder_flush_info : m_curr_flush_info; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initialize_layers(std::vector<coordf_t> &zs);
|
void initialize_layers(std::vector<coordf_t> &zs);
|
||||||
void collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
|
void collect_extruders(const PrintObject &object, const std::vector<std::pair<double, unsigned int>> &per_layer_extruder_switches);
|
||||||
|
@ -221,10 +230,12 @@ private:
|
||||||
unsigned int m_last_printing_extruder = (unsigned int)-1;
|
unsigned int m_last_printing_extruder = (unsigned int)-1;
|
||||||
// All extruders, which extrude some material over m_layer_tools.
|
// All extruders, which extrude some material over m_layer_tools.
|
||||||
std::vector<unsigned int> m_all_printing_extruders;
|
std::vector<unsigned int> m_all_printing_extruders;
|
||||||
std::unordered_map<uint32_t, std::vector<uint8_t>> m_tool_order_cache;
|
|
||||||
const PrintConfig* m_print_config_ptr = nullptr;
|
const PrintConfig* m_print_config_ptr = nullptr;
|
||||||
const PrintObject* m_print_object_ptr = nullptr;
|
const PrintObject* m_print_object_ptr = nullptr;
|
||||||
Print* m_print;
|
Print* m_print;
|
||||||
|
|
||||||
|
std::pair<int, int> m_curr_flush_info{ 0,0 };
|
||||||
|
std::pair<int, int> m_one_extruder_flush_info{ 0,0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace SLic3r
|
} // namespace SLic3r
|
||||||
|
|
|
@ -1814,6 +1814,12 @@ void Print::process(std::unordered_map<std::string, long long>* slice_time, bool
|
||||||
m_tool_ordering = ToolOrdering(*this, -1, false);
|
m_tool_ordering = ToolOrdering(*this, -1, false);
|
||||||
if (m_tool_ordering.empty() || m_tool_ordering.last_extruder() == unsigned(-1))
|
if (m_tool_ordering.empty() || m_tool_ordering.last_extruder() == unsigned(-1))
|
||||||
throw Slic3r::SlicingError("The print is empty. The model is not printable with current print settings.");
|
throw Slic3r::SlicingError("The print is empty. The model is not printable with current print settings.");
|
||||||
|
|
||||||
|
std::pair<int, int> curr_info = m_tool_ordering.get_flush_info(ToolOrdering::FlushCalcMode::Normal);
|
||||||
|
std::pair<int, int> single_extruder_info = m_tool_ordering.get_flush_info(ToolOrdering::FlushCalcMode::OneExtruder);
|
||||||
|
|
||||||
|
this->m_statistics_by_extruder_count.filament_flush_weight = { curr_info.first,single_extruder_info.first };
|
||||||
|
this->m_statistics_by_extruder_count.filament_change_count = { curr_info.second,single_extruder_info.second };
|
||||||
}
|
}
|
||||||
this->set_done(psWipeTower);
|
this->set_done(psWipeTower);
|
||||||
}
|
}
|
||||||
|
@ -2407,6 +2413,12 @@ void Print::_make_wipe_tower()
|
||||||
// BBS: priming logic is removed, so don't consider it in tool ordering
|
// BBS: priming logic is removed, so don't consider it in tool ordering
|
||||||
m_wipe_tower_data.tool_ordering = ToolOrdering(*this, (unsigned int)-1, false);
|
m_wipe_tower_data.tool_ordering = ToolOrdering(*this, (unsigned int)-1, false);
|
||||||
|
|
||||||
|
std::pair<int, int> curr_info = m_wipe_tower_data.tool_ordering.get_flush_info(ToolOrdering::FlushCalcMode::Normal);
|
||||||
|
std::pair<int, int> single_extruder_info = m_wipe_tower_data.tool_ordering.get_flush_info(ToolOrdering::FlushCalcMode::OneExtruder);
|
||||||
|
|
||||||
|
this->m_statistics_by_extruder_count.filament_flush_weight = { curr_info.first,single_extruder_info.first };
|
||||||
|
this->m_statistics_by_extruder_count.filament_change_count = { curr_info.second,single_extruder_info.second };
|
||||||
|
|
||||||
if (!m_wipe_tower_data.tool_ordering.has_wipe_tower())
|
if (!m_wipe_tower_data.tool_ordering.has_wipe_tower())
|
||||||
// Don't generate any wipe tower.
|
// Don't generate any wipe tower.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -695,6 +695,17 @@ class ConstPrintRegionPtrsAdaptor : public ConstVectorOfPtrsAdaptor<PrintRegion>
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct StatisticsByExtruderCount
|
||||||
|
{
|
||||||
|
// multi extruder always comes first
|
||||||
|
std::vector<int> filament_flush_weight{ 0,0 };
|
||||||
|
std::vector<int> filament_change_count{ 0,0 };
|
||||||
|
void clear() {
|
||||||
|
filament_flush_weight.clear();
|
||||||
|
filament_change_count.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
enum FilamentTempType {
|
enum FilamentTempType {
|
||||||
HighTemp=0,
|
HighTemp=0,
|
||||||
LowTemp,
|
LowTemp,
|
||||||
|
@ -800,6 +811,9 @@ public:
|
||||||
const PrintStatistics& print_statistics() const { return m_print_statistics; }
|
const PrintStatistics& print_statistics() const { return m_print_statistics; }
|
||||||
PrintStatistics& print_statistics() { return m_print_statistics; }
|
PrintStatistics& print_statistics() { return m_print_statistics; }
|
||||||
|
|
||||||
|
const StatisticsByExtruderCount statistics_by_extruder() const { return m_statistics_by_extruder_count; }
|
||||||
|
StatisticsByExtruderCount& statistics_by_extruder() { return m_statistics_by_extruder_count; }
|
||||||
|
|
||||||
// Wipe tower support.
|
// Wipe tower support.
|
||||||
bool has_wipe_tower() const;
|
bool has_wipe_tower() const;
|
||||||
const WipeTowerData& wipe_tower_data(size_t filaments_cnt = 0) const;
|
const WipeTowerData& wipe_tower_data(size_t filaments_cnt = 0) const;
|
||||||
|
@ -915,6 +929,7 @@ private:
|
||||||
// Estimated print time, filament consumed.
|
// Estimated print time, filament consumed.
|
||||||
PrintStatistics m_print_statistics;
|
PrintStatistics m_print_statistics;
|
||||||
bool m_support_used {false};
|
bool m_support_used {false};
|
||||||
|
StatisticsByExtruderCount m_statistics_by_extruder_count;
|
||||||
|
|
||||||
//BBS: plate's origin
|
//BBS: plate's origin
|
||||||
Vec3d m_origin;
|
Vec3d m_origin;
|
||||||
|
|
|
@ -4633,6 +4633,7 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(window_padding * 3, 0));
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(window_padding * 3, 0));
|
||||||
ImGui::BeginChild("#AMS", ImVec2(0, AMS_container_height), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
|
ImGui::BeginChild("#AMS", ImVec2(0, AMS_container_height), false, ImGuiWindowFlags_AlwaysUseWindowPadding);
|
||||||
{
|
{
|
||||||
|
auto stats_by_extruder = wxGetApp().plater()->get_partplate_list().get_current_fff_print().statistics_by_extruder();
|
||||||
// BBS save time;
|
// BBS save time;
|
||||||
imgui.text(_u8L("Since you set 1 AMS"));
|
imgui.text(_u8L("Since you set 1 AMS"));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -4640,8 +4641,10 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding)
|
||||||
link_text(_u8L("(change)"));
|
link_text(_u8L("(change)"));
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
imgui.text(_u8L(",this arrangement would be optimal."));
|
imgui.text(_u8L(",this arrangement would be optimal."));
|
||||||
imgui.text(_u8L("It will save 738g filament and 23 minutes"));
|
int delta_filament_weight = stats_by_extruder.filament_flush_weight[1] - stats_by_extruder.filament_flush_weight[0];
|
||||||
|
int delta_filament_change = stats_by_extruder.filament_change_count[1] - stats_by_extruder.filament_change_count[0];
|
||||||
|
imgui.text(from_u8((boost::format(_u8L("Info by single extruder : %1%g filament and %2% filament changes")) % stats_by_extruder.filament_flush_weight[1] % stats_by_extruder.filament_change_count[1]).str()));
|
||||||
|
imgui.text(from_u8((boost::format(_u8L("Info by multi extruder : %1%g filament and %2% filament changes")) % stats_by_extruder.filament_flush_weight[0] % stats_by_extruder.filament_change_count[0]).str()));
|
||||||
float available_width = ImGui::GetContentRegionAvail().x;
|
float available_width = ImGui::GetContentRegionAvail().x;
|
||||||
float available_height = ImGui::GetContentRegionAvail().y;
|
float available_height = ImGui::GetContentRegionAvail().y;
|
||||||
float half_width = available_width * 0.5f;
|
float half_width = available_width * 0.5f;
|
||||||
|
|
Loading…
Reference in New Issue