GCodeViewer -> Added estimated printing times for extrusion roles
This commit is contained in:
parent
5d845c7a25
commit
b03ae392c5
4 changed files with 144 additions and 54 deletions
|
@ -163,6 +163,7 @@ void GCodeProcessor::TimeMachine::reset()
|
|||
gcode_time.reset();
|
||||
blocks = std::vector<TimeBlock>();
|
||||
std::fill(moves_time.begin(), moves_time.end(), 0.0f);
|
||||
std::fill(roles_time.begin(), roles_time.end(), 0.0f);
|
||||
}
|
||||
|
||||
void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time)
|
||||
|
@ -271,6 +272,7 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks)
|
|||
time += block_time;
|
||||
gcode_time.cache += block_time;
|
||||
moves_time[static_cast<size_t>(block.move_type)] += block_time;
|
||||
roles_time[static_cast<size_t>(block.role)] += block_time;
|
||||
|
||||
// if (block.g1_line_id >= 0)
|
||||
// m_g1_times.emplace_back(block.g1_line_id, time);
|
||||
|
@ -397,15 +399,18 @@ void GCodeProcessor::update_print_stats_estimated_times(PrintStatistics& print_s
|
|||
print_statistics.estimated_normal_print_time = get_time(GCodeProcessor::ETimeMode::Normal);
|
||||
print_statistics.estimated_normal_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Normal, true);
|
||||
print_statistics.estimated_normal_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Normal);
|
||||
print_statistics.estimated_normal_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Normal);
|
||||
if (m_time_processor.machines[static_cast<size_t>(GCodeProcessor::ETimeMode::Stealth)].enabled) {
|
||||
print_statistics.estimated_silent_print_time = get_time(GCodeProcessor::ETimeMode::Stealth);
|
||||
print_statistics.estimated_silent_custom_gcode_print_times = get_custom_gcode_times(GCodeProcessor::ETimeMode::Stealth, true);
|
||||
print_statistics.estimated_silent_moves_times = get_moves_time(GCodeProcessor::ETimeMode::Stealth);
|
||||
print_statistics.estimated_silent_roles_times = get_roles_time(GCodeProcessor::ETimeMode::Stealth);
|
||||
}
|
||||
else {
|
||||
print_statistics.estimated_silent_print_time = 0.0f;
|
||||
print_statistics.estimated_silent_custom_gcode_print_times.clear();
|
||||
print_statistics.estimated_silent_moves_times.clear();
|
||||
print_statistics.estimated_silent_roles_times.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,6 +452,19 @@ std::vector<std::pair<GCodeProcessor::EMoveType, float>> GCodeProcessor::get_mov
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::pair<ExtrusionRole, float>> GCodeProcessor::get_roles_time(ETimeMode mode) const
|
||||
{
|
||||
std::vector<std::pair<ExtrusionRole, float>> ret;
|
||||
if (mode < ETimeMode::Count) {
|
||||
for (size_t i = 0; i < m_time_processor.machines[static_cast<size_t>(mode)].roles_time.size(); ++i) {
|
||||
float time = m_time_processor.machines[static_cast<size_t>(mode)].roles_time[i];
|
||||
if (time > 0.0f)
|
||||
ret.push_back({ static_cast<ExtrusionRole>(i), time });
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void GCodeProcessor::process_gcode_line(const GCodeReader::GCodeLine& line)
|
||||
{
|
||||
/* std::cout << line.raw() << std::endl; */
|
||||
|
@ -735,6 +753,7 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
|||
|
||||
TimeBlock block;
|
||||
block.move_type = type;
|
||||
block.role = m_extrusion_role;
|
||||
block.distance = distance;
|
||||
|
||||
// calculates block cruise feedrate
|
||||
|
|
|
@ -101,6 +101,7 @@ namespace Slic3r {
|
|||
};
|
||||
|
||||
EMoveType move_type{ EMoveType::Noop };
|
||||
ExtrusionRole role{ erNone };
|
||||
float distance{ 0.0f }; // mm
|
||||
float acceleration{ 0.0f }; // mm/s^2
|
||||
float max_entry_speed{ 0.0f }; // mm/s
|
||||
|
@ -153,6 +154,7 @@ namespace Slic3r {
|
|||
CustomGCodeTime gcode_time;
|
||||
std::vector<TimeBlock> blocks;
|
||||
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
||||
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
|
||||
|
||||
void reset();
|
||||
|
||||
|
@ -265,6 +267,7 @@ namespace Slic3r {
|
|||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(ETimeMode mode, bool include_remaining) const;
|
||||
|
||||
std::vector<std::pair<EMoveType, float>> get_moves_time(ETimeMode mode) const;
|
||||
std::vector<std::pair<ExtrusionRole, float>> get_roles_time(ETimeMode mode) const;
|
||||
|
||||
private:
|
||||
void process_gcode_line(const GCodeReader::GCodeLine& line);
|
||||
|
|
|
@ -314,6 +314,8 @@ struct PrintStatistics
|
|||
std::vector<std::pair<CustomGCode::Type, std::pair<std::string, std::string>>> estimated_silent_custom_gcode_print_times_str;
|
||||
std::vector<std::pair<GCodeProcessor::EMoveType, float>> estimated_normal_moves_times;
|
||||
std::vector<std::pair<GCodeProcessor::EMoveType, float>> estimated_silent_moves_times;
|
||||
std::vector<std::pair<ExtrusionRole, float>> estimated_normal_roles_times;
|
||||
std::vector<std::pair<ExtrusionRole, float>> estimated_silent_roles_times;
|
||||
#else
|
||||
std::string estimated_normal_print_time;
|
||||
std::string estimated_silent_print_time;
|
||||
|
@ -366,6 +368,8 @@ struct PrintStatistics
|
|||
estimated_silent_custom_gcode_print_times.clear();
|
||||
estimated_normal_moves_times.clear();
|
||||
estimated_silent_moves_times.clear();
|
||||
estimated_normal_roles_times.clear();
|
||||
estimated_silent_roles_times.clear();
|
||||
}
|
||||
#endif //ENABLE_GCODE_VIEWER
|
||||
};
|
||||
|
|
|
@ -1724,6 +1724,8 @@ void GCodeViewer::render_time_estimate() const
|
|||
|
||||
using Times = std::pair<float, float>;
|
||||
using TimesList = std::vector<std::pair<CustomGCode::Type, Times>>;
|
||||
using Headers = std::vector<std::string>;
|
||||
using ColumnOffsets = std::array<float, 2>;
|
||||
|
||||
// helper structure containig the data needed to render the time items
|
||||
struct PartialTime
|
||||
|
@ -1743,17 +1745,14 @@ void GCodeViewer::render_time_estimate() const
|
|||
using PartialTimes = std::vector<PartialTime>;
|
||||
|
||||
auto append_mode = [this, &imgui](float total_time, const PartialTimes& items,
|
||||
const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time) {
|
||||
auto append_partial_times = [this, &imgui](const PartialTimes& items) {
|
||||
using Headers = std::vector<std::string>;
|
||||
const Headers headers = {
|
||||
_u8L("Event"),
|
||||
_u8L("Remaining"),
|
||||
_u8L("Duration")
|
||||
};
|
||||
using Offsets = std::array<float, 2>;
|
||||
const Headers& partial_times_headers,
|
||||
const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time,
|
||||
const Headers& moves_headers,
|
||||
const std::vector<std::pair<ExtrusionRole, float>>& roles_time,
|
||||
const Headers& roles_headers) {
|
||||
auto append_partial_times = [this, &imgui](const PartialTimes& items, const Headers& headers) {
|
||||
auto calc_offsets = [this, &headers](const PartialTimes& items) {
|
||||
Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x };
|
||||
ColumnOffsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x };
|
||||
for (const PartialTime& item : items) {
|
||||
std::string label;
|
||||
switch (item.type)
|
||||
|
@ -1772,7 +1771,7 @@ void GCodeViewer::render_time_estimate() const
|
|||
ret[1] += ret[0] + style.ItemSpacing.x;
|
||||
return ret;
|
||||
};
|
||||
auto append_color = [this, &imgui](const Color& color1, const Color& color2, Offsets& offsets, const Times& times) {
|
||||
auto append_color = [this, &imgui](const Color& color1, const Color& color2, ColumnOffsets& offsets, const Times& times) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(_u8L("Color change"));
|
||||
ImGui::PopStyleColor();
|
||||
|
@ -1801,7 +1800,7 @@ void GCodeViewer::render_time_estimate() const
|
|||
if (items.empty())
|
||||
return;
|
||||
|
||||
Offsets offsets = calc_offsets(items);
|
||||
ColumnOffsets offsets = calc_offsets(items);
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
|
@ -1845,42 +1844,25 @@ void GCodeViewer::render_time_estimate() const
|
|||
}
|
||||
};
|
||||
|
||||
auto append_move_times = [this, &imgui](float total_time, const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time) {
|
||||
using Headers = std::vector<std::string>;
|
||||
const Headers headers = {
|
||||
_u8L("Type"),
|
||||
_u8L("Time"),
|
||||
_u8L("Percentage")
|
||||
};
|
||||
auto move_type_label = [](GCodeProcessor::EMoveType type) {
|
||||
switch (type)
|
||||
{
|
||||
case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); }
|
||||
case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); }
|
||||
case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); }
|
||||
case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); }
|
||||
case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); }
|
||||
case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); }
|
||||
case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); }
|
||||
case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); }
|
||||
case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); }
|
||||
default: { return _u8L("Unknown"); }
|
||||
}
|
||||
};
|
||||
using Offsets = std::array<float, 2>;
|
||||
auto calc_offsets = [this, &headers, move_type_label](const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time) {
|
||||
Offsets ret = { ImGui::CalcTextSize(headers[0].c_str()).x, ImGui::CalcTextSize(headers[1].c_str()).x };
|
||||
for (const auto& [type, time] : moves_time) {
|
||||
ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x);
|
||||
ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x);
|
||||
}
|
||||
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
ret[0] += 2.0f * style.ItemSpacing.x;
|
||||
ret[1] += ret[0] + style.ItemSpacing.x;
|
||||
return ret;
|
||||
};
|
||||
auto move_type_label = [](GCodeProcessor::EMoveType type) {
|
||||
switch (type)
|
||||
{
|
||||
case GCodeProcessor::EMoveType::Noop: { return _u8L("Noop"); }
|
||||
case GCodeProcessor::EMoveType::Retract: { return _u8L("Retraction"); }
|
||||
case GCodeProcessor::EMoveType::Unretract: { return _u8L("Unretraction"); }
|
||||
case GCodeProcessor::EMoveType::Tool_change: { return _u8L("Tool change"); }
|
||||
case GCodeProcessor::EMoveType::Color_change: { return _u8L("Color change"); }
|
||||
case GCodeProcessor::EMoveType::Pause_Print: { return _u8L("Pause print"); }
|
||||
case GCodeProcessor::EMoveType::Custom_GCode: { return _u8L("Custom GCode"); }
|
||||
case GCodeProcessor::EMoveType::Travel: { return _u8L("Travel"); }
|
||||
case GCodeProcessor::EMoveType::Extrude: { return _u8L("Extrusion"); }
|
||||
default: { return _u8L("Unknown"); }
|
||||
}
|
||||
};
|
||||
|
||||
auto append_move_times = [this, &imgui, move_type_label](float total_time,
|
||||
const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time,
|
||||
const Headers& headers, const ColumnOffsets& offsets) {
|
||||
|
||||
if (moves_time.empty())
|
||||
return;
|
||||
|
@ -1888,8 +1870,6 @@ void GCodeViewer::render_time_estimate() const
|
|||
if (!ImGui::CollapsingHeader(_u8L("Moves Time").c_str()))
|
||||
return;
|
||||
|
||||
Offsets offsets = calc_offsets(moves_time);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(headers[0]);
|
||||
ImGui::SameLine(offsets[0]);
|
||||
|
@ -1899,7 +1879,10 @@ void GCodeViewer::render_time_estimate() const
|
|||
ImGui::PopStyleColor();
|
||||
ImGui::Separator();
|
||||
|
||||
for (const auto& [type, time] : moves_time) {
|
||||
std::vector<std::pair<GCodeProcessor::EMoveType, float>> sorted_moves_time(moves_time);
|
||||
std::sort(sorted_moves_time.begin(), sorted_moves_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; });
|
||||
|
||||
for (const auto& [type, time] : sorted_moves_time) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(move_type_label(type));
|
||||
ImGui::PopStyleColor();
|
||||
|
@ -1912,13 +1895,72 @@ void GCodeViewer::render_time_estimate() const
|
|||
}
|
||||
};
|
||||
|
||||
auto append_role_times = [this, &imgui](float total_time,
|
||||
const std::vector<std::pair<ExtrusionRole, float>>& roles_time,
|
||||
const Headers& headers, const ColumnOffsets& offsets) {
|
||||
|
||||
if (roles_time.empty())
|
||||
return;
|
||||
|
||||
if (!ImGui::CollapsingHeader(_u8L("Features Time").c_str()))
|
||||
return;
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(headers[0]);
|
||||
ImGui::SameLine(offsets[0]);
|
||||
imgui.text(headers[1]);
|
||||
ImGui::SameLine(offsets[1]);
|
||||
imgui.text(headers[2]);
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::Separator();
|
||||
|
||||
std::vector<std::pair<ExtrusionRole, float>> sorted_roles_time(roles_time);
|
||||
std::sort(sorted_roles_time.begin(), sorted_roles_time.end(), [](const auto& p1, const auto& p2) { return p2.second < p1.second; });
|
||||
|
||||
for (const auto& [role, time] : sorted_roles_time) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(_u8L(ExtrusionEntity::role_to_string(role)));
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SameLine(offsets[0]);
|
||||
imgui.text(short_time(get_time_dhms(time)));
|
||||
ImGui::SameLine(offsets[1]);
|
||||
char buf[64];
|
||||
::sprintf(buf, "%.2f%%", 100.0f * time / total_time);
|
||||
ImGui::TextUnformatted(buf);
|
||||
}
|
||||
};
|
||||
|
||||
auto calc_common_offsets = [move_type_label](
|
||||
const std::vector<std::pair<GCodeProcessor::EMoveType, float>>& moves_time, const Headers& moves_headers,
|
||||
const std::vector<std::pair<ExtrusionRole, float>>& roles_time, const Headers& roles_headers) {
|
||||
ColumnOffsets ret = { std::max(ImGui::CalcTextSize(moves_headers[0].c_str()).x, ImGui::CalcTextSize(roles_headers[0].c_str()).x),
|
||||
std::max(ImGui::CalcTextSize(moves_headers[1].c_str()).x, ImGui::CalcTextSize(roles_headers[1].c_str()).x) };
|
||||
|
||||
for (const auto& [type, time] : moves_time) {
|
||||
ret[0] = std::max(ret[0], ImGui::CalcTextSize(move_type_label(type).c_str()).x);
|
||||
ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x);
|
||||
}
|
||||
|
||||
for (const auto& [role, time] : roles_time) {
|
||||
ret[0] = std::max(ret[0], ImGui::CalcTextSize(_u8L(ExtrusionEntity::role_to_string(role)).c_str()).x);
|
||||
ret[1] = std::max(ret[1], ImGui::CalcTextSize(short_time(get_time_dhms(time)).c_str()).x);
|
||||
}
|
||||
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
ret[0] += 2.0f * style.ItemSpacing.x;
|
||||
ret[1] += ret[0] + style.ItemSpacing.x;
|
||||
return ret;
|
||||
};
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImGuiWrapper::COL_ORANGE_LIGHT);
|
||||
imgui.text(_u8L("Time") + ":");
|
||||
ImGui::PopStyleColor();
|
||||
ImGui::SameLine();
|
||||
imgui.text(short_time(get_time_dhms(total_time)));
|
||||
append_partial_times(items);
|
||||
append_move_times(total_time, moves_time);
|
||||
append_partial_times(items, partial_times_headers);
|
||||
ColumnOffsets common_offsets = calc_common_offsets(moves_time, moves_headers, roles_time, roles_headers);
|
||||
append_move_times(total_time, moves_time, moves_headers, common_offsets);
|
||||
append_role_times(total_time, roles_time, roles_headers, common_offsets);
|
||||
};
|
||||
|
||||
auto generate_partial_times = [this](const TimesList& times) {
|
||||
|
@ -1966,6 +2008,22 @@ void GCodeViewer::render_time_estimate() const
|
|||
return items;
|
||||
};
|
||||
|
||||
const Headers partial_times_headers = {
|
||||
_u8L("Event"),
|
||||
_u8L("Remaining"),
|
||||
_u8L("Duration")
|
||||
};
|
||||
const Headers moves_headers = {
|
||||
_u8L("Type"),
|
||||
_u8L("Time"),
|
||||
_u8L("Percentage")
|
||||
};
|
||||
const Headers roles_headers = {
|
||||
_u8L("Feature"),
|
||||
_u8L("Time"),
|
||||
_u8L("Percentage")
|
||||
};
|
||||
|
||||
Size cnv_size = wxGetApp().plater()->get_current_canvas3D()->get_canvas_size();
|
||||
imgui.set_next_window_pos(static_cast<float>(cnv_size.get_width()), static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 1.0f, 1.0f);
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, 0.0f), ImVec2(-1.0f, 0.5f * static_cast<float>(cnv_size.get_height())));
|
||||
|
@ -1980,13 +2038,19 @@ void GCodeViewer::render_time_estimate() const
|
|||
ImGui::BeginTabBar("mode_tabs");
|
||||
if (ps.estimated_normal_print_time > 0.0f) {
|
||||
if (ImGui::BeginTabItem(_u8L("Normal").c_str())) {
|
||||
append_mode(ps.estimated_normal_print_time, generate_partial_times(ps.estimated_normal_custom_gcode_print_times), ps.estimated_normal_moves_times);
|
||||
append_mode(ps.estimated_normal_print_time,
|
||||
generate_partial_times(ps.estimated_normal_custom_gcode_print_times), partial_times_headers,
|
||||
ps.estimated_normal_moves_times, moves_headers,
|
||||
ps.estimated_normal_roles_times, roles_headers);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
if (ps.estimated_silent_print_time > 0.0f) {
|
||||
if (ImGui::BeginTabItem(_u8L("Stealth").c_str())) {
|
||||
append_mode(ps.estimated_silent_print_time, generate_partial_times(ps.estimated_silent_custom_gcode_print_times), ps.estimated_silent_moves_times);
|
||||
append_mode(ps.estimated_silent_print_time,
|
||||
generate_partial_times(ps.estimated_silent_custom_gcode_print_times), partial_times_headers,
|
||||
ps.estimated_silent_moves_times, moves_headers,
|
||||
ps.estimated_silent_roles_times, roles_headers);
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue