SPE-1872: Actual speed profile - Further enhancements of imgui debug window

This commit is contained in:
enricoturri1966 2024-02-14 14:20:03 +01:00 committed by Lukas Matena
parent 07d2fb32fa
commit 07b653cb22
2 changed files with 44 additions and 25 deletions

View File

@ -334,7 +334,7 @@ void GCodeViewer::SequentialRangeCap::reset() {
#endif // !ENABLE_NEW_GCODE_VIEWER #endif // !ENABLE_NEW_GCODE_VIEWER
#if ENABLE_ET_SPE1872_DEBUG #if ENABLE_ET_SPE1872_DEBUG
int GCodeViewer::SequentialView::Marker::ActualSpeedImguiWidget::plot(const char* label, const std::array<float, 2>& frame_size) int GCodeViewer::SequentialView::ActualSpeedImguiWidget::plot(const char* label, const std::array<float, 2>& frame_size)
{ {
ImGuiWindow* window = ImGui::GetCurrentWindow(); ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems) if (window->SkipItems)
@ -366,14 +366,15 @@ int GCodeViewer::SequentialView::Marker::ActualSpeedImguiWidget::plot(const char
const ImVec2 offset(10.0f, 0.0f); const ImVec2 offset(10.0f, 0.0f);
const float size_y = y_range.second - y_range.first; const float size_y = y_range.second - y_range.first;
const float size_x = data.back().first - data.front().first; const float size_x = data.back().pos - data.front().pos;
if (size_x > 0.0f && values_count >= values_count_min) { if (size_x > 0.0f && values_count >= values_count_min) {
const float inv_scale_y = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; const float inv_scale_y = (size_y == 0.0f) ? 0.0f : 1.0f / size_y;
const float inv_scale_x = 1.0f / size_x; const float inv_scale_x = 1.0f / size_x;
const float x0 = data.front().first; const float x0 = data.front().pos;
const float y0 = y_range.first; const float y0 = y_range.first;
const ImU32 grid_color = ImGui::GetColorU32(ImVec4(0.5f, 0.5f, 0.5f, 0.5f)); const ImU32 grid_main_color = ImGui::GetColorU32(ImVec4(0.5f, 0.5f, 0.5f, 0.5f));
const ImU32 grid_secondary_color = ImGui::GetColorU32(ImVec4(0.0f, 0.0f, 0.5f, 0.5f));
// horizontal levels // horizontal levels
for (const auto& [level, color] : levels) { for (const auto& [level, color] : levels) {
@ -383,24 +384,24 @@ int GCodeViewer::SequentialView::Marker::ActualSpeedImguiWidget::plot(const char
ImLerp(inner_bb.Min, ImVec2(inner_bb.Min.x + offset.x, inner_bb.Max.y), ImVec2(0.9f, y)), ImGuiWrapper::to_ImU32(color), 3.0f); ImLerp(inner_bb.Min, ImVec2(inner_bb.Min.x + offset.x, inner_bb.Max.y), ImVec2(0.9f, y)), ImGuiWrapper::to_ImU32(color), 3.0f);
window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(0.0f, y)), window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(0.0f, y)),
ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, y)), grid_color); ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, y)), grid_main_color);
} }
// vertical positions // vertical positions
for (int n = 0; n < values_count - 1; ++n) { for (int n = 0; n < values_count - 1; ++n) {
const float x = ImSaturate((data[n].first - x0) * inv_scale_x); const float x = ImSaturate((data[n].pos - x0) * inv_scale_x);
window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 0.0f)), window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 0.0f)),
ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 1.0f)), grid_color); ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(x, 1.0f)), data[n].internal ? grid_secondary_color : grid_main_color);
} }
window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 0.0f)), window->DrawList->AddLine(ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 0.0f)),
ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 1.0f)), grid_color); ImLerp(inner_bb.Min + offset, inner_bb.Max, ImVec2(1.0f, 1.0f)), grid_main_color);
// profiile // profiile
const ImU32 col_base = ImGui::GetColorU32(ImVec4(0.8f, 0.8f, 0.8f, 1.0f)); const ImU32 col_base = ImGui::GetColorU32(ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
const ImU32 col_hovered = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered); const ImU32 col_hovered = ImGui::GetColorU32(ImGuiCol_PlotLinesHovered);
for (int n = 0; n < values_count - 1; ++n) { for (int n = 0; n < values_count - 1; ++n) {
const ImVec2 tp1(ImSaturate((data[n].first - x0) * inv_scale_x), 1.0f - ImSaturate((data[n].second - y0) * inv_scale_y)); const ImVec2 tp1(ImSaturate((data[n].pos - x0) * inv_scale_x), 1.0f - ImSaturate((data[n].speed - y0) * inv_scale_y));
const ImVec2 tp2(ImSaturate((data[n + 1].first - x0) * inv_scale_x), 1.0f - ImSaturate((data[n + 1].second - y0) * inv_scale_y)); const ImVec2 tp2(ImSaturate((data[n + 1].pos - x0) * inv_scale_x), 1.0f - ImSaturate((data[n + 1].speed - y0) * inv_scale_y));
// Tooltip on hover // Tooltip on hover
if (hovered && inner_bb.Contains(io.MousePos)) { if (hovered && inner_bb.Contains(io.MousePos)) {
const float t = ImClamp((io.MousePos.x - inner_bb.Min.x - offset.x) / (inner_bb.Max.x - inner_bb.Min.x - offset.x), 0.0f, 0.9999f); const float t = ImClamp((io.MousePos.x - inner_bb.Min.x - offset.x) / (inner_bb.Max.x - inner_bb.Min.x - offset.x), 0.0f, 0.9999f);
@ -670,30 +671,42 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode
ImGui::Separator(); ImGui::Separator();
const int hover_id = m_actual_speed_imgui_widget.plot("##ActualSpeedProfile", { -1.0f, 150.0f }); const int hover_id = m_actual_speed_imgui_widget.plot("##ActualSpeedProfile", { -1.0f, 150.0f });
if (table_shown) { if (table_shown) {
static float table_wnd_height = 0.0f;
const ImVec2 wnd_size = ImGui::GetWindowSize(); const ImVec2 wnd_size = ImGui::GetWindowSize();
imgui.set_next_window_pos(ImGui::GetWindowPos().x + wnd_size.x, static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 0.0f, 1.0f); imgui.set_next_window_pos(ImGui::GetWindowPos().x + wnd_size.x, static_cast<float>(cnv_size.get_height()), ImGuiCond_Always, 0.0f, 1.0f);
ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, wnd_size.y }); ImGui::SetNextWindowSizeConstraints({ 0.0f, 0.0f }, { -1.0f, wnd_size.y });
imgui.begin(std::string("ToolPositionTable"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | imgui.begin(std::string("ToolPositionTableWnd"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove); ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove);
if (ImGui::BeginTable("Table", 2, ImGuiTableFlags_Borders)) { if (ImGui::BeginTable("ToolPositionTable", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_ScrollY)) {
char buff[1024]; char buff[1024];
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("Position (mm)"); ImGui::TableSetupColumn("Position (mm)");
ImGui::TableSetupColumn("Speed (mm/s)"); ImGui::TableSetupColumn("Speed (mm/s)");
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
int counter = 0; int counter = 0;
for (const auto& [pos, speed] : m_actual_speed_imgui_widget.data) { for (const ActualSpeedImguiWidget::Item& item : m_actual_speed_imgui_widget.data) {
const bool highlight = hover_id >= 0 && (counter == hover_id || counter == hover_id + 1); const bool highlight = hover_id >= 0 && (counter == hover_id || counter == hover_id + 1);
if (highlight && counter == hover_id)
ImGui::SetScrollHereY();
ImGui::TableNextRow(); ImGui::TableNextRow();
const ImU32 row_bg_color = ImGui::GetColorU32(item.internal ? ImVec4(0.0f, 0.0f, 0.5f, 0.25f) : ImVec4(0.5f, 0.5f, 0.5f, 0.25f));
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, row_bg_color);
ImGui::TableSetColumnIndex(0); ImGui::TableSetColumnIndex(0);
sprintf(buff, "%.3f", pos); sprintf(buff, "%.3f", item.pos);
imgui.text_colored(highlight ? ImGuiWrapper::COL_ORANGE_LIGHT : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff); imgui.text_colored(highlight ? ImGuiWrapper::COL_ORANGE_LIGHT : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff);
ImGui::TableSetColumnIndex(1); ImGui::TableSetColumnIndex(1);
sprintf(buff, "%.1f", speed); sprintf(buff, "%.1f", item.speed);
imgui.text_colored(highlight ? ImGuiWrapper::COL_ORANGE_LIGHT : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff); imgui.text_colored(highlight ? ImGuiWrapper::COL_ORANGE_LIGHT : ImGuiWrapper::to_ImVec4(ColorRGBA::WHITE()), buff);
++counter; ++counter;
} }
ImGui::EndTable(); ImGui::EndTable();
} }
const float curr_table_wnd_height = ImGui::GetWindowHeight();
if (table_wnd_height != curr_table_wnd_height) {
table_wnd_height = curr_table_wnd_height;
// require extra frame to hide the table scroll bar (bug in imgui)
imgui.set_requires_extra_frame();
}
imgui.end(); imgui.end();
} }
} }
@ -1801,7 +1814,7 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in
const libvgcode::ColorRange& color_range = m_viewer.get_color_range(libvgcode::EViewType::ActualSpeed); const libvgcode::ColorRange& color_range = m_viewer.get_color_range(libvgcode::EViewType::ActualSpeed);
const std::array<float, 2>& interval = color_range.get_range(); const std::array<float, 2>& interval = color_range.get_range();
const size_t vertices_count = m_viewer.get_vertices_count(); const size_t vertices_count = m_viewer.get_vertices_count();
std::vector<std::pair<float, float>> actual_speed_data; std::vector<SequentialView::ActualSpeedImguiWidget::Item> actual_speed_data;
// collect vertices sharing the same gcode_id // collect vertices sharing the same gcode_id
const size_t curr_id = m_viewer.get_current_vertex_id(); const size_t curr_id = m_viewer.get_current_vertex_id();
size_t start_id = curr_id; size_t start_id = curr_id;
@ -1829,7 +1842,7 @@ void GCodeViewer::update_sequential_view_current(unsigned int first, unsigned in
(libvgcode::convert(v.position) - libvgcode::convert(m_viewer.get_vertex_at(i - 1).position)).norm() : 0.0f; (libvgcode::convert(v.position) - libvgcode::convert(m_viewer.get_vertex_at(i - 1).position)).norm() : 0.0f;
total_len += len; total_len += len;
if (i == start_id || len > EPSILON) if (i == start_id || len > EPSILON)
actual_speed_data.push_back(std::make_pair(total_len, v.actual_feedrate)); actual_speed_data.push_back({ total_len, v.actual_feedrate, v.times[0] == 0.0f });
} }
std::vector<std::pair<float, ColorRGBA>> levels; std::vector<std::pair<float, ColorRGBA>> levels;

View File

@ -700,18 +700,24 @@ class GCodeViewer
public: public:
struct SequentialView struct SequentialView
{ {
class Marker
{
#if ENABLE_ET_SPE1872_DEBUG #if ENABLE_ET_SPE1872_DEBUG
struct ActualSpeedImguiWidget struct ActualSpeedImguiWidget
{
std::pair<float, float> y_range = { 0.0f, 0.0f };
std::vector<std::pair<float, ColorRGBA>> levels;
struct Item
{ {
std::pair<float, float> y_range = { 0.0f, 0.0f }; float pos{ 0.0f };
std::vector<std::pair<float, ColorRGBA>> levels; float speed{ 0.0f };
std::vector<std::pair<float, float>> data; bool internal{ false };
int plot(const char* label, const std::array<float, 2>& frame_size = { 0.0f, 0.0f });
}; };
std::vector<Item> data;
int plot(const char* label, const std::array<float, 2>& frame_size = { 0.0f, 0.0f });
};
#endif // ENABLE_ET_SPE1872_DEBUG #endif // ENABLE_ET_SPE1872_DEBUG
class Marker
{
GLModel m_model; GLModel m_model;
Vec3f m_world_position; Vec3f m_world_position;
// For seams, the position of the marker is on the last endpoint of the toolpath containing it. // For seams, the position of the marker is on the last endpoint of the toolpath containing it.
@ -745,7 +751,7 @@ public:
void set_actual_speed_levels(const std::vector<std::pair<float, ColorRGBA>>& levels) { void set_actual_speed_levels(const std::vector<std::pair<float, ColorRGBA>>& levels) {
m_actual_speed_imgui_widget.levels = levels; m_actual_speed_imgui_widget.levels = levels;
} }
void set_actual_speed_data(const std::vector<std::pair<float, float>>& data) { void set_actual_speed_data(const std::vector<ActualSpeedImguiWidget::Item>& data) {
m_actual_speed_imgui_widget.data = data; m_actual_speed_imgui_widget.data = data;
} }
#endif // ENABLE_ET_SPE1872_DEBUG #endif // ENABLE_ET_SPE1872_DEBUG