From 88ae637098220eeefec075894d4ad7d656e5f15e Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Fri, 19 Jan 2024 08:46:34 +0100 Subject: [PATCH] New gcode visualization library - Added print color changes detection --- src/libvgcode/CMakeLists.txt | 2 + src/libvgcode/include/ColorPrint.hpp | 23 +++++++ src/libvgcode/include/Viewer.hpp | 11 +++- src/libvgcode/src/ColorPrint.cpp | 8 +++ src/libvgcode/src/Viewer.cpp | 12 +++- src/libvgcode/src/ViewerImpl.cpp | 88 ++++++++++++++++++-------- src/libvgcode/src/ViewerImpl.hpp | 95 ++++++++++++++++------------ 7 files changed, 169 insertions(+), 70 deletions(-) create mode 100644 src/libvgcode/include/ColorPrint.hpp create mode 100644 src/libvgcode/src/ColorPrint.cpp diff --git a/src/libvgcode/CMakeLists.txt b/src/libvgcode/CMakeLists.txt index 03513f99b8..1aeca0ae02 100644 --- a/src/libvgcode/CMakeLists.txt +++ b/src/libvgcode/CMakeLists.txt @@ -3,6 +3,7 @@ project(libvgcode) add_library(libvgcode STATIC # API + include/ColorPrint.hpp include/ColorRange.hpp include/GCodeInputData.hpp include/PathVertex.hpp @@ -13,6 +14,7 @@ add_library(libvgcode STATIC src/Bitset.cpp src/CogMarker.hpp src/CogMarker.cpp + src/ColorPrint.cpp src/ColorRange.cpp src/ExtrusionRoles.hpp src/ExtrusionRoles.cpp diff --git a/src/libvgcode/include/ColorPrint.hpp b/src/libvgcode/include/ColorPrint.hpp new file mode 100644 index 0000000000..218a852252 --- /dev/null +++ b/src/libvgcode/include/ColorPrint.hpp @@ -0,0 +1,23 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#ifndef VGCODE_COLORPRINT_HPP +#define VGCODE_COLORPRINT_HPP + +#include "../include/Types.hpp" + +namespace libvgcode { + +struct ColorPrint +{ + uint8_t extruder_id{ 0 }; + uint8_t color_id{ 0 }; + uint32_t layer_id{ 0 }; +// float layer_z{ 0.0f }; + std::array times{ 0.0f, 0.0f }; +}; + +} // namespace libvgcode + +#endif // VGCODE_COLORPRINT_HPP \ No newline at end of file diff --git a/src/libvgcode/include/Viewer.hpp b/src/libvgcode/include/Viewer.hpp index 458309f8f9..17c2ab666e 100644 --- a/src/libvgcode/include/Viewer.hpp +++ b/src/libvgcode/include/Viewer.hpp @@ -15,6 +15,7 @@ class ViewerImpl; struct GCodeInputData; struct PathVertex; class ColorRange; +struct ColorPrint; class Viewer { @@ -265,7 +266,7 @@ public: // // Return the list of ids of the detected used extruders. // - const std::vector& get_used_extruders_ids() const; + std::vector get_used_extruders_ids() const; // // Return the list of detected time modes. // @@ -312,6 +313,14 @@ public: // const std::vector& get_options() const; // + // Return the count of detected color prints. + // + size_t get_color_prints_count(uint8_t extruder_id) const; + // + // Return the list of detected color prints. + // + std::vector get_color_prints(uint8_t extruder_id) const; + // // Return the estimated time for the given role and the current time mode. // float get_extrusion_role_time(EGCodeExtrusionRole role) const; diff --git a/src/libvgcode/src/ColorPrint.cpp b/src/libvgcode/src/ColorPrint.cpp new file mode 100644 index 0000000000..d6f40b9f52 --- /dev/null +++ b/src/libvgcode/src/ColorPrint.cpp @@ -0,0 +1,8 @@ +///|/ Copyright (c) Prusa Research 2023 Enrico Turri @enricoturri1966, Pavel Mikuš @Godrak +///|/ +///|/ libvgcode is released under the terms of the AGPLv3 or higher +///|/ +#include "../include/ColorPrint.hpp" + +namespace libvgcode { +} // namespace libvgcode diff --git a/src/libvgcode/src/Viewer.cpp b/src/libvgcode/src/Viewer.cpp index 903760dc63..3436355988 100644 --- a/src/libvgcode/src/Viewer.cpp +++ b/src/libvgcode/src/Viewer.cpp @@ -232,7 +232,7 @@ size_t Viewer::get_used_extruders_count() const return m_impl->get_used_extruders_count(); } -const std::vector& Viewer::get_used_extruders_ids() const +std::vector Viewer::get_used_extruders_ids() const { return m_impl->get_used_extruders_ids(); } @@ -292,6 +292,16 @@ const std::vector& Viewer::get_options() const return m_impl->get_options(); } +size_t Viewer::get_color_prints_count(uint8_t extruder_id) const +{ + return m_impl->get_color_prints_count(extruder_id); +} + +std::vector Viewer::get_color_prints(uint8_t extruder_id) const +{ + return m_impl->get_color_prints(extruder_id); +} + float Viewer::get_extrusion_role_time(EGCodeExtrusionRole role) const { return m_impl->get_extrusion_role_time(role); diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index ae63363de0..554ee137c7 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -280,11 +280,7 @@ static void delete_buffers(unsigned int& id) } } -// -// Palette used to render extrusion moves by extrusion roles -// EViewType: FeatureType -// -const std::map ViewerImpl::DEFAULT_EXTRUSION_ROLES_COLORS{ { +static const std::map DEFAULT_EXTRUSION_ROLES_COLORS{ { { EGCodeExtrusionRole::None, { 230, 179, 179 } }, { EGCodeExtrusionRole::Perimeter, { 255, 230, 77 } }, { EGCodeExtrusionRole::ExternalPerimeter, { 255, 125, 56 } }, @@ -302,11 +298,7 @@ const std::map ViewerImpl::DEFAULT_EXTRUSION_ROLES_C { EGCodeExtrusionRole::Custom, { 94, 209, 148 } } } }; -// -// Palette used to render options -// EViewType: FeatureType -// -const std::map ViewerImpl::DEFAULT_OPTIONS_COLORS{ { +static const std::map DEFAULT_OPTIONS_COLORS{ { { EOptionType::Travels, { 56, 72, 155 } }, { EOptionType::Wipes, { 255, 255, 0 } }, { EOptionType::Retractions, { 205, 34, 214 } }, @@ -318,6 +310,12 @@ const std::map ViewerImpl::DEFAULT_OPTIONS_COLORS{ { { EOptionType::CustomGCodes, { 226, 210, 67 } } } }; +ViewerImpl::ViewerImpl() +{ + reset_default_extrusion_roles_colors(); + reset_default_options_colors(); +} + void ViewerImpl::init(const std::string& opengl_context_version) { if (m_initialized) @@ -447,8 +445,8 @@ void ViewerImpl::reset() m_view_range.reset(); m_extrusion_roles.reset(); m_options.clear(); + m_used_extruders.clear(); m_travels_time = { 0.0f, 0.0f }; - m_used_extruders_ids.clear(); m_vertices.clear(); m_valid_lines_bitset.clear(); #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS @@ -486,25 +484,33 @@ void ViewerImpl::load(GCodeInputData&& gcode_data) m_vertices = std::move(gcode_data.vertices); m_settings.spiral_vase_mode = gcode_data.spiral_vase_mode; - m_used_extruders_ids.reserve(m_vertices.size()); - + std::array times{ 0.0f, 0.0f }; for (size_t i = 0; i < m_vertices.size(); ++i) { const PathVertex& v = m_vertices[i]; + m_layers.update(v, static_cast(i)); - if (v.type == EMoveType::Travel) { - for (size_t j = 0; j < TIME_MODES_COUNT; ++j) { + + for (size_t j = 0; j < TIME_MODES_COUNT; ++j) { + times[j] += v.times[j]; + if (v.type == EMoveType::Travel) m_travels_time[j] += v.times[j]; - } } - else - m_extrusion_roles.add(v.role, v.times); const EOptionType option_type = move_type_to_option(v.type); if (option_type != EOptionType::COUNT) m_options.emplace_back(option_type); - if (v.type == EMoveType::Extrude) - m_used_extruders_ids.emplace_back(v.extruder_id); + if (v.type == EMoveType::Extrude) { + m_extrusion_roles.add(v.role, v.times); + + auto estruder_it = m_used_extruders.find(v.extruder_id); + if (estruder_it == m_used_extruders.end()) + estruder_it = m_used_extruders.insert({ v.extruder_id, std::vector() }).first; + if (estruder_it->second.empty() || estruder_it->second.back().color_id != v.color_id) { + const ColorPrint cp = { v.extruder_id, v.color_id, v.layer_id, times }; + estruder_it->second.emplace_back(cp); + } + } if (i > 0) { #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS @@ -528,10 +534,6 @@ void ViewerImpl::load(GCodeInputData&& gcode_data) m_options.erase(std::unique(m_options.begin(), m_options.end()), m_options.end()); m_options.shrink_to_fit(); - std::sort(m_used_extruders_ids.begin(), m_used_extruders_ids.end()); - m_used_extruders_ids.erase(std::unique(m_used_extruders_ids.begin(), m_used_extruders_ids.end()), m_used_extruders_ids.end()); - m_used_extruders_ids.shrink_to_fit(); - // reset segments visibility bitset m_valid_lines_bitset = BitSet<>(m_vertices.size()); m_valid_lines_bitset.setAll(); @@ -720,11 +722,11 @@ static float encode_color(const Color& color) { void ViewerImpl::update_colors() { if (m_colors_buf_id == 0) - return; + return; - if (!m_used_extruders_ids.empty()) { + if (!m_used_extruders.empty()) { // ensure that the number of defined tool colors matches the max id of the used extruders - const size_t max_used_extruder_id = 1 + static_cast(m_used_extruders_ids.back()); + const size_t max_used_extruder_id = 1 + static_cast(m_used_extruders.rbegin()->first); const size_t tool_colors_size = m_tool_colors.size(); if (m_tool_colors.size() < max_used_extruder_id) { for (size_t i = 0; i < max_used_extruder_id - tool_colors_size; ++i) { @@ -825,6 +827,28 @@ std::vector ViewerImpl::get_time_modes() const return ret; } +std::vector ViewerImpl::get_used_extruders_ids() const +{ + std::vector ret; + ret.reserve(m_used_extruders.size()); + for (const auto& [id, colors] : m_used_extruders) { + ret.emplace_back(id); + } + return ret; +} + +size_t ViewerImpl::get_color_prints_count(uint8_t extruder_id) const +{ + const auto it = m_used_extruders.find(extruder_id); + return (it == m_used_extruders.end()) ? 0 : it->second.size(); +} + +std::vector ViewerImpl::get_color_prints(uint8_t extruder_id) const +{ + const auto it = m_used_extruders.find(extruder_id); + return (it == m_used_extruders.end()) ? std::vector() : it->second; +} + AABox ViewerImpl::get_bounding_box(EBBoxType type) const { assert(type < EBBoxType::COUNT); @@ -988,6 +1012,11 @@ void ViewerImpl::set_extrusion_role_color(EGCodeExtrusionRole role, const Color& } } +void ViewerImpl::reset_default_extrusion_roles_colors() +{ + m_extrusion_roles_colors = DEFAULT_EXTRUSION_ROLES_COLORS; +} + const Color& ViewerImpl::get_option_color(EOptionType type) const { const auto it = m_options_colors.find(type); @@ -1003,6 +1032,11 @@ void ViewerImpl::set_option_color(EOptionType type, const Color& color) } } +void ViewerImpl::reset_default_options_colors() +{ + m_options_colors = DEFAULT_OPTIONS_COLORS; +} + const ColorRange& ViewerImpl::get_color_range(EViewType type) const { switch (type) diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp index 318cb75b0b..24c81e93ba 100644 --- a/src/libvgcode/src/ViewerImpl.hpp +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -14,6 +14,7 @@ #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS #include "../include/PathVertex.hpp" #include "../include/ColorRange.hpp" +#include "../include/ColorPrint.hpp" #include "Bitset.hpp" #include "ViewRange.hpp" #include "Layers.hpp" @@ -28,7 +29,7 @@ struct GCodeInputData; class ViewerImpl { public: - ViewerImpl() = default; + ViewerImpl(); ~ViewerImpl() { shutdown(); } ViewerImpl(const ViewerImpl& other) = delete; ViewerImpl(ViewerImpl&& other) = delete; @@ -92,8 +93,11 @@ public: size_t get_layer_id_at(float z) const { return m_layers.get_layer_id_at(z); } - size_t get_used_extruders_count() const { return m_used_extruders_ids.size(); } - const std::vector& get_used_extruders_ids() const { return m_used_extruders_ids; } + size_t get_used_extruders_count() const { return m_used_extruders.size(); } + std::vector get_used_extruders_ids() const; + + size_t get_color_prints_count(uint8_t extruder_id) const; + std::vector get_color_prints(uint8_t extruder_id) const; AABox get_bounding_box(EBBoxType type) const; @@ -141,11 +145,11 @@ public: const Color& get_extrusion_role_color(EGCodeExtrusionRole role) const; void set_extrusion_role_color(EGCodeExtrusionRole role, const Color& color); - void reset_default_extrusion_roles_colors() { m_extrusion_roles_colors = DEFAULT_EXTRUSION_ROLES_COLORS; } + void reset_default_extrusion_roles_colors(); const Color& get_option_color(EOptionType type) const; void set_option_color(EOptionType type, const Color& color); - void reset_default_options_colors() { m_options_colors = DEFAULT_OPTIONS_COLORS; } + void reset_default_options_colors(); const ColorRange& get_color_range(EViewType type) const; void set_color_range_palette(EViewType type, const Palette& palette); @@ -181,62 +185,88 @@ public: #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS private: + // + // Settings used to render the toolpaths + // Settings m_settings; + // + // Detected layers + // Layers m_layers; - ViewRange m_view_range; + // + // Detected extrusion roles + // ExtrusionRoles m_extrusion_roles; + // + // Detected options + // std::vector m_options; + // + // Detected used extruders ids + // + std::map> m_used_extruders; + // + // Vertices ranges for visualization + // + ViewRange m_view_range; + // + // Detected travel moves times + // std::array m_travels_time{ 0.0f, 0.0f }; - std::vector m_used_extruders_ids; + // + // Radius of cylinders used to render travel moves segments + // float m_travels_radius{ DEFAULT_TRAVELS_RADIUS_MM }; + // + // Radius of cylinders used to render wipe moves segments + // float m_wipes_radius{ DEFAULT_WIPES_RADIUS_MM }; + // + // Palette used to render extrusion roles + // + std::map m_extrusion_roles_colors; + // + // Palette used to render options + // + std::map m_options_colors; bool m_initialized{ false }; bool m_loading{ false }; - std::map m_extrusion_roles_colors{ DEFAULT_EXTRUSION_ROLES_COLORS }; - std::map m_options_colors{ DEFAULT_OPTIONS_COLORS }; - // // The OpenGL element used to represent all toolpath segments // SegmentTemplate m_segment_template; - // // The OpenGL element used to represent all option markers // OptionTemplate m_option_template; - #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS // // The OpenGL element used to represent the center of gravity // CogMarker m_cog_marker; float m_cog_marker_scale_factor{ 1.0f }; - // // The OpenGL element used to represent the tool nozzle // ToolMarker m_tool_marker; float m_tool_marker_scale_factor{ 1.0f }; #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS - // // cpu buffer to store vertices // std::vector m_vertices; Range m_enabled_segments_range; Range m_enabled_options_range; - // - // Member variables used for toolpaths visibiliity + // Variables used for toolpaths visibiliity // BitSet<> m_valid_lines_bitset; size_t m_enabled_segments_count{ 0 }; size_t m_enabled_options_count{ 0 }; - // - // Member variables used for toolpaths coloring + // Variables used for toolpaths coloring // ColorRange m_height_range; ColorRange m_width_range; @@ -248,9 +278,8 @@ private: ColorRange(EColorRangeType::Linear), ColorRange(EColorRangeType::Logarithmic) }; Palette m_tool_colors; - // - // OpenGL shader ids + // OpenGL shaders ids // unsigned int m_segments_shader_id{ 0 }; unsigned int m_options_shader_id{ 0 }; @@ -258,7 +287,6 @@ private: unsigned int m_cog_marker_shader_id{ 0 }; unsigned int m_tool_marker_shader_id{ 0 }; #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS - // // Cache for OpenGL uniforms id for segments shader // @@ -269,7 +297,6 @@ private: int m_uni_segments_height_width_angle_tex_id{ -1 }; int m_uni_segments_colors_tex_id{ -1 }; int m_uni_segments_segment_index_tex_id{ -1 }; - // // Cache for OpenGL uniforms id for options shader // @@ -279,7 +306,6 @@ private: int m_uni_options_height_width_angle_tex_id{ -1 }; int m_uni_options_colors_tex_id{ -1 }; int m_uni_options_segment_index_tex_id{ -1 }; - #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS // // Cache for OpenGL uniforms id for cog marker shader @@ -288,7 +314,6 @@ private: int m_uni_cog_marker_scale_factor{ -1 }; int m_uni_cog_marker_view_matrix{ -1 }; int m_uni_cog_marker_projection_matrix{ -1 }; - // // Cache for OpenGL uniforms id for tool marker shader // @@ -298,29 +323,28 @@ private: int m_uni_tool_marker_projection_matrix{ -1 }; int m_uni_tool_marker_color_base{ -1 }; #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS - // - // gpu buffers to store positions + // OpenGL buffers to store positions // unsigned int m_positions_buf_id{ 0 }; unsigned int m_positions_tex_id{ 0 }; // - // gpu buffers to store heights, widths and angles + // OpenGL buffers to store heights, widths and angles // unsigned int m_heights_widths_angles_buf_id{ 0 }; unsigned int m_heights_widths_angles_tex_id{ 0 }; // - // gpu buffers to store colors + // OpenGL buffers to store colors // unsigned int m_colors_buf_id{ 0 }; unsigned int m_colors_tex_id{ 0 }; // - // gpu buffers to store enabled segments + // OpenGL buffers to store enabled segments // unsigned int m_enabled_segments_buf_id{ 0 }; unsigned int m_enabled_segments_tex_id{ 0 }; // - // gpu buffers to store enabled options + // OpenGL buffers to store enabled options // unsigned int m_enabled_options_buf_id{ 0 }; unsigned int m_enabled_options_tex_id{ 0 }; @@ -334,17 +358,6 @@ private: void render_cog_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); void render_tool_marker(const Mat4x4& view_matrix, const Mat4x4& projection_matrix); #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS - - // - // Palette used to render extrusion moves by extrusion roles - // EViewType: FeatureType - // - static const std::map DEFAULT_EXTRUSION_ROLES_COLORS; - // - // Palette used to render options - // EViewType: FeatureType - // - static const std::map DEFAULT_OPTIONS_COLORS; }; } // namespace libvgcode