ENH: show travel time in gcode viewer
Seperate travel time from extrusion role time and show it seperately. Signed-off-by: salt.wei <salt.wei@bambulab.com> Change-Id: Icf0aaf63c4d4ed7d1407037e5ae051d61938f973
This commit is contained in:
parent
db873eb99b
commit
170a24a43f
|
@ -208,6 +208,7 @@ void GCodeProcessor::TimeMachine::reset()
|
||||||
std::fill(moves_time.begin(), moves_time.end(), 0.0f);
|
std::fill(moves_time.begin(), moves_time.end(), 0.0f);
|
||||||
std::fill(roles_time.begin(), roles_time.end(), 0.0f);
|
std::fill(roles_time.begin(), roles_time.end(), 0.0f);
|
||||||
layers_time = std::vector<float>();
|
layers_time = std::vector<float>();
|
||||||
|
prepare_time = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time)
|
void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time)
|
||||||
|
@ -315,6 +316,8 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa
|
||||||
|
|
||||||
time += block_time;
|
time += block_time;
|
||||||
gcode_time.cache += block_time;
|
gcode_time.cache += block_time;
|
||||||
|
//BBS: don't calculate travel of start gcode into travel time
|
||||||
|
if (!block.flags.prepare_stage || block.move_type != EMoveType::Travel)
|
||||||
moves_time[static_cast<size_t>(block.move_type)] += block_time;
|
moves_time[static_cast<size_t>(block.move_type)] += block_time;
|
||||||
roles_time[static_cast<size_t>(block.role)] += block_time;
|
roles_time[static_cast<size_t>(block.role)] += block_time;
|
||||||
if (block.layer_id >= layers_time.size()) {
|
if (block.layer_id >= layers_time.size()) {
|
||||||
|
@ -325,6 +328,9 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layers_time[block.layer_id - 1] += block_time;
|
layers_time[block.layer_id - 1] += block_time;
|
||||||
|
//BBS
|
||||||
|
if (block.flags.prepare_stage)
|
||||||
|
prepare_time += block_time;
|
||||||
g1_times_cache.push_back({ block.g1_line_id, time });
|
g1_times_cache.push_back({ block.g1_line_id, time });
|
||||||
// update times for remaining time to printer stop placeholders
|
// update times for remaining time to printer stop placeholders
|
||||||
auto it_stop_time = std::lower_bound(stop_times.begin(), stop_times.end(), block.g1_line_id,
|
auto it_stop_time = std::lower_bound(stop_times.begin(), stop_times.end(), block.g1_line_id,
|
||||||
|
@ -458,7 +464,7 @@ void GCodeProcessor::TimeProcessor::post_process(const std::string& filename, st
|
||||||
// (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
|
// (mode == PrintEstimatedStatistics::ETimeMode::Normal) ? "normal" : "silent",
|
||||||
// get_time_dhms(machine.time).c_str());
|
// get_time_dhms(machine.time).c_str());
|
||||||
sprintf(buf, "; model printing time: %s; total estimated time: %s\n",
|
sprintf(buf, "; model printing time: %s; total estimated time: %s\n",
|
||||||
get_time_dhms(machine.time - machine.roles_time[ExtrusionRole::erCustom]).c_str(),
|
get_time_dhms(machine.time - machine.prepare_time).c_str(),
|
||||||
get_time_dhms(machine.time).c_str());
|
get_time_dhms(machine.time).c_str());
|
||||||
ret += buf;
|
ret += buf;
|
||||||
}
|
}
|
||||||
|
@ -1431,6 +1437,11 @@ float GCodeProcessor::get_time(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast<size_t>(mode)].time : 0.0f;
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast<size_t>(mode)].time : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GCodeProcessor::get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
|
{
|
||||||
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? m_time_processor.machines[static_cast<size_t>(mode)].prepare_time : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const
|
std::string GCodeProcessor::get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const
|
||||||
{
|
{
|
||||||
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast<size_t>(mode)].time)) : std::string("N/A");
|
return (mode < PrintEstimatedStatistics::ETimeMode::Count) ? short_time(get_time_dhms(m_time_processor.machines[static_cast<size_t>(mode)].time)) : std::string("N/A");
|
||||||
|
@ -2663,10 +2674,12 @@ void GCodeProcessor::process_G1(const GCodeReader::GCodeLine& line)
|
||||||
|
|
||||||
TimeBlock block;
|
TimeBlock block;
|
||||||
block.move_type = type;
|
block.move_type = type;
|
||||||
block.role = m_extrusion_role;
|
//BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode.
|
||||||
|
block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone;
|
||||||
block.distance = distance;
|
block.distance = distance;
|
||||||
block.g1_line_id = m_g1_line_id;
|
block.g1_line_id = m_g1_line_id;
|
||||||
block.layer_id = std::max<unsigned int>(1, m_layer_id);
|
block.layer_id = std::max<unsigned int>(1, m_layer_id);
|
||||||
|
block.flags.prepare_stage = m_processing_start_custom_gcode;
|
||||||
|
|
||||||
//BBS: limite the cruise according to centripetal acceleration
|
//BBS: limite the cruise according to centripetal acceleration
|
||||||
//Only need to handle when both prev and curr segment has movement in x-y plane
|
//Only need to handle when both prev and curr segment has movement in x-y plane
|
||||||
|
@ -3085,10 +3098,12 @@ void GCodeProcessor::process_G2_G3(const GCodeReader::GCodeLine& line)
|
||||||
|
|
||||||
TimeBlock block;
|
TimeBlock block;
|
||||||
block.move_type = type;
|
block.move_type = type;
|
||||||
block.role = m_extrusion_role;
|
//BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode.
|
||||||
|
block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone;
|
||||||
block.distance = delta_xyz;
|
block.distance = delta_xyz;
|
||||||
block.g1_line_id = m_g1_line_id;
|
block.g1_line_id = m_g1_line_id;
|
||||||
block.layer_id = std::max<unsigned int>(1, m_layer_id);
|
block.layer_id = std::max<unsigned int>(1, m_layer_id);
|
||||||
|
block.flags.prepare_stage = m_processing_start_custom_gcode;
|
||||||
|
|
||||||
// BBS: calculates block cruise feedrate
|
// BBS: calculates block cruise feedrate
|
||||||
// For arc move, we need to limite the cruise according to centripetal acceleration which is
|
// For arc move, we need to limite the cruise according to centripetal acceleration which is
|
||||||
|
@ -4015,6 +4030,7 @@ void GCodeProcessor::update_estimated_times_stats()
|
||||||
auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) {
|
auto update_mode = [this](PrintEstimatedStatistics::ETimeMode mode) {
|
||||||
PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast<size_t>(mode)];
|
PrintEstimatedStatistics::Mode& data = m_result.print_statistics.modes[static_cast<size_t>(mode)];
|
||||||
data.time = get_time(mode);
|
data.time = get_time(mode);
|
||||||
|
data.prepare_time = get_prepare_time(mode);
|
||||||
data.custom_gcode_times = get_custom_gcode_times(mode, true);
|
data.custom_gcode_times = get_custom_gcode_times(mode, true);
|
||||||
data.moves_times = get_moves_time(mode);
|
data.moves_times = get_moves_time(mode);
|
||||||
data.roles_times = get_roles_time(mode);
|
data.roles_times = get_roles_time(mode);
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace Slic3r {
|
||||||
struct Mode
|
struct Mode
|
||||||
{
|
{
|
||||||
float time;
|
float time;
|
||||||
|
float prepare_time;
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> custom_gcode_times;
|
||||||
std::vector<std::pair<EMoveType, float>> moves_times;
|
std::vector<std::pair<EMoveType, float>> moves_times;
|
||||||
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
std::vector<std::pair<ExtrusionRole, float>> roles_times;
|
||||||
|
@ -56,6 +57,7 @@ namespace Slic3r {
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
time = 0.0f;
|
time = 0.0f;
|
||||||
|
prepare_time = 0.0f;
|
||||||
custom_gcode_times.clear();
|
custom_gcode_times.clear();
|
||||||
moves_times.clear();
|
moves_times.clear();
|
||||||
roles_times.clear();
|
roles_times.clear();
|
||||||
|
@ -298,6 +300,7 @@ namespace Slic3r {
|
||||||
{
|
{
|
||||||
bool recalculate{ false };
|
bool recalculate{ false };
|
||||||
bool nominal_length{ false };
|
bool nominal_length{ false };
|
||||||
|
bool prepare_stage{ false };
|
||||||
};
|
};
|
||||||
|
|
||||||
EMoveType move_type{ EMoveType::Noop };
|
EMoveType move_type{ EMoveType::Noop };
|
||||||
|
@ -381,6 +384,8 @@ namespace Slic3r {
|
||||||
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
std::array<float, static_cast<size_t>(EMoveType::Count)> moves_time;
|
||||||
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
|
std::array<float, static_cast<size_t>(ExtrusionRole::erCount)> roles_time;
|
||||||
std::vector<float> layers_time;
|
std::vector<float> layers_time;
|
||||||
|
//BBS: prepare stage time before print model, including start gcode time and mostly same with start gcode time
|
||||||
|
float prepare_time;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
@ -681,6 +686,7 @@ namespace Slic3r {
|
||||||
void finalize(bool post_process);
|
void finalize(bool post_process);
|
||||||
|
|
||||||
float get_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
float get_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
|
float get_prepare_time(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
std::string get_time_dhm(PrintEstimatedStatistics::ETimeMode mode) const;
|
||||||
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
std::vector<std::pair<CustomGCode::Type, std::pair<float, float>>> get_custom_gcode_times(PrintEstimatedStatistics::ETimeMode mode, bool include_remaining) const;
|
||||||
|
|
||||||
|
|
|
@ -942,7 +942,6 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
||||||
// BBS for first layer inspection
|
// BBS for first layer inspection
|
||||||
view_type_items.push_back(EViewType::FilamentId);
|
view_type_items.push_back(EViewType::FilamentId);
|
||||||
|
|
||||||
options_items.push_back(EMoveType::Seam);
|
|
||||||
options_items.push_back(EMoveType::Travel);
|
options_items.push_back(EMoveType::Travel);
|
||||||
options_items.push_back(EMoveType::Retract);
|
options_items.push_back(EMoveType::Retract);
|
||||||
options_items.push_back(EMoveType::Unretract);
|
options_items.push_back(EMoveType::Unretract);
|
||||||
|
@ -950,6 +949,8 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode)
|
||||||
if (mode == ConfigOptionMode::comDevelop) {
|
if (mode == ConfigOptionMode::comDevelop) {
|
||||||
options_items.push_back(EMoveType::Tool_change);
|
options_items.push_back(EMoveType::Tool_change);
|
||||||
}
|
}
|
||||||
|
//BBS: seam is not real move and extrusion, put at last line
|
||||||
|
options_items.push_back(EMoveType::Seam);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> GCodeViewer::get_plater_extruder()
|
std::vector<int> GCodeViewer::get_plater_extruder()
|
||||||
|
@ -4365,6 +4366,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
return (it != time_mode.roles_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto move_time_and_percent = [time_mode](EMoveType move_type) {
|
||||||
|
auto it = std::find_if(time_mode.moves_times.begin(), time_mode.moves_times.end(), [move_type](const std::pair<EMoveType, float>& item) { return move_type == item.first; });
|
||||||
|
return (it != time_mode.moves_times.end()) ? std::make_pair(it->second, it->second / time_mode.time) : std::make_pair(0.0f, 0.0f);
|
||||||
|
};
|
||||||
|
|
||||||
auto used_filament_per_role = [this, imperial_units](ExtrusionRole role) {
|
auto used_filament_per_role = [this, imperial_units](ExtrusionRole role) {
|
||||||
auto it = m_print_statistics.used_filaments_per_role.find(role);
|
auto it = m_print_statistics.used_filaments_per_role.find(role);
|
||||||
if (it == m_print_statistics.used_filaments_per_role.end())
|
if (it == m_print_statistics.used_filaments_per_role.end())
|
||||||
|
@ -4438,7 +4444,9 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
std::vector<float> offsets;
|
std::vector<float> offsets;
|
||||||
std::vector<std::string> labels;
|
std::vector<std::string> labels;
|
||||||
std::vector<std::string> times;
|
std::vector<std::string> times;
|
||||||
|
std::string travel_time;
|
||||||
std::vector<std::string> percents;
|
std::vector<std::string> percents;
|
||||||
|
std::string travel_percent;
|
||||||
std::vector<double> model_used_filaments_m;
|
std::vector<double> model_used_filaments_m;
|
||||||
std::vector<double> model_used_filaments_g;
|
std::vector<double> model_used_filaments_g;
|
||||||
double total_model_used_filament_m = 0, total_model_used_filament_g = 0;
|
double total_model_used_filament_m = 0, total_model_used_filament_g = 0;
|
||||||
|
@ -4485,6 +4493,17 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BBS: get travel time and percent
|
||||||
|
{
|
||||||
|
auto [time, percent] = move_time_and_percent(EMoveType::Travel);
|
||||||
|
travel_time = (time > 0.0f) ? short_time(get_time_dhms(time)) : "";
|
||||||
|
if (percent == 0)
|
||||||
|
::sprintf(buffer, "0%%");
|
||||||
|
else
|
||||||
|
percent > 0.001 ? ::sprintf(buffer, "%.1f%%", percent * 100) : ::sprintf(buffer, "<0.1%%");
|
||||||
|
travel_percent = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("Percent"), percents}, {_u8L("Display"), {""}}}, icon_size);
|
offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("Percent"), percents}, {_u8L("Display"), {""}}}, icon_size);
|
||||||
append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("Percent"), offsets[2]}, {_u8L("Display"), offsets[3]}});
|
append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("Percent"), offsets[2]}, {_u8L("Display"), offsets[3]}});
|
||||||
break;
|
break;
|
||||||
|
@ -4573,7 +4592,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
};
|
};
|
||||||
const bool visible = m_buffers[buffer_id(type)].visible;
|
const bool visible = m_buffers[buffer_id(type)].visible;
|
||||||
if (type == EMoveType::Travel) {
|
if (type == EMoveType::Travel) {
|
||||||
//TODO display travel time
|
//BBS: only display travel time in FeatureType view
|
||||||
append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible);
|
append_option_item_with_type(type, Travel_Colors[0], _u8L("Travel"), visible);
|
||||||
}
|
}
|
||||||
else if (type == EMoveType::Seam)
|
else if (type == EMoveType::Seam)
|
||||||
|
@ -4613,7 +4632,23 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto item : options_items) {
|
for(auto item : options_items) {
|
||||||
|
if (item != EMoveType::Travel) {
|
||||||
append_option_item(item, offsets);
|
append_option_item(item, offsets);
|
||||||
|
} else {
|
||||||
|
//BBS: show travel time in FeatureType view
|
||||||
|
const bool visible = m_buffers[buffer_id(item)].visible;
|
||||||
|
std::vector<std::pair<std::string, float>> columns_offsets;
|
||||||
|
columns_offsets.push_back({ _u8L("Travel"), offsets[0] });
|
||||||
|
columns_offsets.push_back({ travel_time, offsets[1] });
|
||||||
|
columns_offsets.push_back({ travel_percent, offsets[2] });
|
||||||
|
append_item(EItemType::Rect, Travel_Colors[0], columns_offsets, true, visible, [this, item, visible]() {
|
||||||
|
m_buffers[buffer_id(item)].visible = !m_buffers[buffer_id(item)].visible;
|
||||||
|
// update buffers' render paths
|
||||||
|
refresh_render_paths(false, false);
|
||||||
|
update_moves_slider();
|
||||||
|
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5209,19 +5244,19 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
|
||||||
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<ExtrusionRole, float>& item) { return role == item.first; });
|
auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<ExtrusionRole, float>& item) { return role == item.first; });
|
||||||
return (it != time_mode.roles_times.end()) ? it->second : 0.0f;
|
return (it != time_mode.roles_times.end()) ? it->second : 0.0f;
|
||||||
};
|
};
|
||||||
//BBS: start gcode is prepeare time
|
//BBS: start gcode is mostly same with prepeare time
|
||||||
if (role_time(erCustom) != 0.0f) {
|
if (time_mode.prepare_time != 0.0f) {
|
||||||
ImGui::Dummy({ window_padding, window_padding });
|
ImGui::Dummy({ window_padding, window_padding });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
imgui.text(prepare_str + ":");
|
imgui.text(prepare_str + ":");
|
||||||
ImGui::SameLine(max_len);
|
ImGui::SameLine(max_len);
|
||||||
imgui.text(short_time(get_time_dhms(role_time(erCustom))));
|
imgui.text(short_time(get_time_dhms(time_mode.prepare_time)));
|
||||||
}
|
}
|
||||||
ImGui::Dummy({ window_padding, window_padding });
|
ImGui::Dummy({ window_padding, window_padding });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
imgui.text(print_str + ":");
|
imgui.text(print_str + ":");
|
||||||
ImGui::SameLine(max_len);
|
ImGui::SameLine(max_len);
|
||||||
imgui.text(short_time(get_time_dhms(time_mode.time - role_time(erCustom))));
|
imgui.text(short_time(get_time_dhms(time_mode.time - time_mode.prepare_time)));
|
||||||
ImGui::Dummy({ window_padding, window_padding });
|
ImGui::Dummy({ window_padding, window_padding });
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
imgui.text(total_str + ":");
|
imgui.text(total_str + ":");
|
||||||
|
|
Loading…
Reference in New Issue