diff --git a/src/libvgcode/include/Viewer.hpp b/src/libvgcode/include/Viewer.hpp index 5c2852c187..f83295e6c0 100644 --- a/src/libvgcode/include/Viewer.hpp +++ b/src/libvgcode/include/Viewer.hpp @@ -80,13 +80,16 @@ public: // Toggle the top layer only state. // void toggle_top_layer_only_view_range(); - // // Spiral vase mode // Whether or not the gcode was generated with spiral vase mode enabled. // See: GCodeInputData // bool is_spiral_vase_mode() const; + // + // Return the list of detected time modes. + // + std::vector get_time_modes() const; // // ************************************************************************ @@ -187,11 +190,22 @@ public: // const PathVertex& get_current_vertex() const; + // + // Return the index of vertex pointed by the max value of the view visible range + // + size_t get_current_vertex_id() const; + // // Return the vertex at the given index // const PathVertex& get_vertex_at(size_t id) const; + // + // Return the estimated time, in seconds, at the vertex with the given index + // using the current time mode. + // + float get_estimated_time_at(size_t id) const; + // // Return the color used to render the given vertex with the current settings. // diff --git a/src/libvgcode/src/Viewer.cpp b/src/libvgcode/src/Viewer.cpp index 267a2c4aab..f9ef48aa88 100644 --- a/src/libvgcode/src/Viewer.cpp +++ b/src/libvgcode/src/Viewer.cpp @@ -77,6 +77,11 @@ bool Viewer::is_spiral_vase_mode() const return m_impl->is_spiral_vase_mode(); } +std::vector Viewer::get_time_modes() const +{ + return m_impl->get_time_modes(); +} + const Interval& Viewer::get_layers_view_range() const { return m_impl->get_layers_view_range(); @@ -177,11 +182,21 @@ const PathVertex& Viewer::get_current_vertex() const return m_impl->get_current_vertex(); } +size_t Viewer::get_current_vertex_id() const +{ + return m_impl->get_current_vertex_id(); +} + const PathVertex& Viewer::get_vertex_at(size_t id) const { return m_impl->get_vertex_at(id); } +float Viewer::get_estimated_time_at(size_t id) const +{ + return m_impl->get_estimated_time_at(id); +} + Color Viewer::get_vertex_color(const PathVertex& vertex) const { return m_impl->get_vertex_color(vertex); diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index 043233329c..271b96dfea 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace libvgcode { @@ -798,6 +799,17 @@ void ViewerImpl::toggle_top_layer_only_view_range() m_settings.update_colors = true; } +std::vector ViewerImpl::get_time_modes() const +{ + std::vector ret; + for (size_t i = 0; i < TIME_MODES_COUNT; ++i) { + if (std::accumulate(m_vertices.begin(), m_vertices.end(), 0.0f, + [i](float a, const PathVertex& v) { return a + v.times[i]; }) > 0.0f) + ret.push_back(static_cast(i)); + } + return ret; +} + AABox ViewerImpl::get_bounding_box(EBBoxType type) const { assert(type < EBBoxType::COUNT); @@ -870,6 +882,12 @@ void ViewerImpl::set_view_visible_range(Interval::value_type min, Interval::valu m_settings.update_colors = true; } +float ViewerImpl::get_estimated_time_at(size_t id) const +{ + return std::accumulate(m_vertices.begin(), m_vertices.begin() + id + 1, 0.0f, + [this](float a, const PathVertex& v) { return a + v.times[static_cast(m_settings.time_mode)]; }); +} + Color ViewerImpl::get_vertex_color(const PathVertex& v) const { if (v.type == EMoveType::Noop) diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp index 4a339213c4..64e55ba30f 100644 --- a/src/libvgcode/src/ViewerImpl.hpp +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -85,6 +85,8 @@ public: bool is_spiral_vase_mode() const { return m_settings.spiral_vase_mode; } + std::vector get_time_modes() const; + size_t get_layers_count() const { return m_layers.count(); } float get_layer_z(size_t layer_id) const { return m_layers.get_layer_z(layer_id); } std::vector get_layers_zs() const { return m_layers.get_zs(); } @@ -108,10 +110,12 @@ public: void set_view_visible_range(Interval::value_type min, Interval::value_type max); size_t get_vertices_count() const { return m_vertices.size(); } - const PathVertex& get_current_vertex() const { return get_vertex_at(m_view_range.get_visible()[1]); } + const PathVertex& get_current_vertex() const { return get_vertex_at(get_current_vertex_id()); } + size_t get_current_vertex_id() const { return static_cast(m_view_range.get_visible()[1]); } const PathVertex& get_vertex_at(size_t id) const { return (id < m_vertices.size()) ? m_vertices[id] : DUMMY_PATH_VERTEX; } + float get_estimated_time_at(size_t id) const; Color get_vertex_color(const PathVertex& vertex) const; size_t get_enabled_segments_count() const { return m_enabled_segments_count; } diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index c196d924fe..43695e22c4 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -461,8 +461,11 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode imgui.text_colored(ImGuiWrapper::COL_ORANGE_LIGHT, _u8L("Position") + ":"); ImGui::SameLine(); libvgcode::PathVertex vertex = viewer->get_current_vertex(); - if (vertex.type == libvgcode::EMoveType::Seam) - vertex = viewer->get_vertex_at(viewer->get_view_visible_range()[1] - 1); + size_t vertex_id = viewer->get_current_vertex_id(); + if (vertex.type == libvgcode::EMoveType::Seam) { + vertex_id = static_cast(viewer->get_view_visible_range()[1]) - 1; + vertex = viewer->get_vertex_at(vertex_id); + } char buf[1024]; sprintf(buf, "X: %.3f, Y: %.3f, Z: %.3f", vertex.position[0], vertex.position[1], vertex.position[2]); @@ -487,65 +490,65 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode if (ImGui::BeginTable("Properties", 2)) { char buff[1024]; - append_table_row(_u8L("Type") + ":", [&imgui, &vertex]() { + append_table_row(_u8L("Type"), [&imgui, &vertex]() { std::string text = _u8L(to_string(vertex.type)); if (vertex.is_extrusion()) text += " (" + _u8L(to_string(vertex.role)) + ")"; imgui.text(text); }); - append_table_row(_u8L("Width") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Width") + " (" + _u8L("mm") + ")", [&imgui, &vertex, &buff]() { std::string text; if (vertex.is_extrusion()) { sprintf(buff, "%.3f", vertex.width); - text = std::string(buff) + " " + _u8L("mm"); + text = std::string(buff); } else text = _u8L("N/A"); imgui.text(text); }); - append_table_row(_u8L("Height") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Height") + " (" + _u8L("mm") + ")", [&imgui, &vertex, &buff]() { std::string text; if (vertex.is_extrusion()) { sprintf(buff, "%.3f", vertex.height); - text = std::string(buff) + " " + _u8L("mm"); + text = std::string(buff); } else text = _u8L("N/A"); imgui.text(text); }); - append_table_row(_u8L("Layer") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Layer"), [&imgui, &vertex, &buff]() { sprintf(buff, "%d", vertex.layer_id + 1); const std::string text = std::string(buff); imgui.text(text); }); - append_table_row(_u8L("Speed") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Speed") + " (" + _u8L("mm/s") + ")", [&imgui, &vertex, &buff]() { std::string text; if (vertex.is_extrusion()) { sprintf(buff, "%.1f", vertex.feedrate); - text = std::string(buff) + " " + _u8L("mm/s"); + text = std::string(buff); } else text = _u8L("N/A"); - imgui.text(text); + imgui.text(text); }); - append_table_row(_u8L("Fan speed") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Fan speed") + " (" + _u8L("%") + ")", [&imgui, &vertex, &buff]() { std::string text; if (vertex.is_extrusion()) { sprintf(buff, "%.0f", vertex.fan_speed); - text = std::string(buff) + " " + _u8L("%"); + text = std::string(buff); } else text = _u8L("N/A"); imgui.text(text); }); - append_table_row(_u8L("Temperature") + ":", [&imgui, &vertex, &buff]() { + append_table_row(_u8L("Temperature") + " (" + _u8L("°C") + ")", [&imgui, &vertex, &buff]() { sprintf(buff, "%.0f", vertex.temperature); - const std::string text = std::string(buff) + " " + _u8L("°C"); - imgui.text(text); + imgui.text(std::string(buff)); }); - append_table_row(_u8L("Time") + ":", [viewer, &imgui, &vertex, &buff]() { - sprintf(buff, "%.3f", vertex.times[static_cast(viewer->get_time_mode())]); - const std::string text = std::string(buff) + " " + _u8L("s"); + append_table_row(_u8L("Time"), [viewer, &imgui, &vertex, &buff, vertex_id]() { + const float estimated_time = viewer->get_estimated_time_at(vertex_id); + sprintf(buff, "%s (%.3fs)", get_time_dhms(estimated_time).c_str(), vertex.times[static_cast(viewer->get_time_mode())]); + const std::string text = std::string(buff); imgui.text(text); });