From 4c4485a9b5338a17b4838e94d65761659fa6cd9a Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Tue, 21 Apr 2020 15:55:26 +0200 Subject: [PATCH] GCodeViewer -> Extrusion toolpaths colored by tool --- src/slic3r/GUI/BitmapCache.cpp | 5 +++ src/slic3r/GUI/GCodeViewer.cpp | 64 ++++++++++++++++++++++++++++------ src/slic3r/GUI/GCodeViewer.hpp | 12 ++++--- src/slic3r/GUI/GLCanvas3D.cpp | 6 ++-- src/slic3r/GUI/GLCanvas3D.hpp | 2 +- src/slic3r/GUI/GUI_Preview.cpp | 2 +- src/slic3r/GUI/GUI_Utils.hpp | 9 +++++ 7 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/slic3r/GUI/BitmapCache.cpp b/src/slic3r/GUI/BitmapCache.cpp index 8627ef4cb..c345f6bf7 100644 --- a/src/slic3r/GUI/BitmapCache.cpp +++ b/src/slic3r/GUI/BitmapCache.cpp @@ -3,6 +3,9 @@ #include "libslic3r/Utils.hpp" #include "../Utils/MacDarkMode.hpp" #include "GUI.hpp" +#if ENABLE_GCODE_VIEWER +#include "GUI_Utils.hpp" +#endif // ENABLE_GCODE_VIEWER #include @@ -352,6 +355,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi } +#if !ENABLE_GCODE_VIEWER static inline int hex_digit_to_int(const char c) { return @@ -359,6 +363,7 @@ static inline int hex_digit_to_int(const char c) (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } +#endif // !ENABLE_GCODE_VIEWER bool BitmapCache::parse_color(const std::string& scolor, unsigned char* rgb_out) { diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index ad15a0bb9..0b5be1974 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -8,6 +8,9 @@ #include "Camera.hpp" #include "I18N.hpp" #include "libslic3r/I18N.hpp" +#if ENABLE_GCODE_VIEWER +#include "GUI_Utils.hpp" +#endif // ENABLE_GCODE_VIEWER #include #include @@ -27,6 +30,31 @@ static GCodeProcessor::EMoveType buffer_type(unsigned char id) { return static_cast(static_cast(GCodeProcessor::EMoveType::Retract) + id); } +std::vector> decode_colors(const std::vector& colors) +{ + static const float INV_255 = 1.0f / 255.0f; + + std::vector> output(colors.size(), {0.0f, 0.0f, 0.0f} ); + for (size_t i = 0; i < colors.size(); ++i) + { + const std::string& color = colors[i]; + const char* c = color.data() + 1; + if ((color.size() == 7) && (color.front() == '#')) + { + for (size_t j = 0; j < 3; ++j) + { + int digit1 = hex_digit_to_int(*c++); + int digit2 = hex_digit_to_int(*c++); + if ((digit1 == -1) || (digit2 == -1)) + break; + + output[i][j] = float(digit1 * 16 + digit2) * INV_255; + } + } + } + return output; +} + void GCodeViewer::VBuffer::reset() { // release gpu memory @@ -68,7 +96,7 @@ bool GCodeViewer::IBuffer::init_shader(const std::string& vertex_shader_src, con void GCodeViewer::IBuffer::add_path(const GCodeProcessor::MoveVertex& move) { unsigned int id = static_cast(data.size()); - paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate() }); + paths.push_back({ move.type, move.extrusion_role, id, id, move.height, move.width, move.feedrate, move.fan_speed, move.volumetric_rate(), move.extruder_id }); } std::array GCodeViewer::Extrusions::Range::get_color_at(float value) const @@ -95,7 +123,7 @@ std::array GCodeViewer::Extrusions::Range::get_color_at(float value) c return ret; } -const std::array, erCount> GCodeViewer::Extrusion_Role_Colors{ { +const std::array, erCount> GCodeViewer::Extrusion_Role_Colors {{ { 1.00f, 1.00f, 1.00f }, // erNone { 1.00f, 1.00f, 0.40f }, // erPerimeter { 1.00f, 0.65f, 0.00f }, // erExternalPerimeter @@ -113,7 +141,7 @@ const std::array, erCount> GCodeViewer::Extrusion_Role_Colo { 0.00f, 0.00f, 0.00f } // erMixed }}; -const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors{ { +const std::array, GCodeViewer::Range_Colors_Count> GCodeViewer::Range_Colors {{ { 0.043f, 0.173f, 0.478f }, // bluish { 0.075f, 0.349f, 0.522f }, { 0.110f, 0.533f, 0.569f }, @@ -126,8 +154,9 @@ const std::array, GCodeViewer::Range_Colors_Count> GCodeVie { 0.761f, 0.322f, 0.235f } // reddish }}; -void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized) +void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized) { + // avoid processing if called with the same gcode_result if (m_last_result_id == gcode_result.id) return; @@ -136,6 +165,8 @@ void GCodeViewer::load(const GCodeProcessor::Result& gcode_result, const Print& // release gpu memory, if used reset(); + m_tool_colors = decode_colors(str_tool_colors); + load_toolpaths(gcode_result); load_shells(print, initialized); } @@ -170,10 +201,7 @@ void GCodeViewer::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_r } break; } - default: - { - break; - } + default: { break; } } } } @@ -188,6 +216,7 @@ void GCodeViewer::reset() } m_bounding_box = BoundingBoxf3(); + m_tool_colors = std::vector>(); m_extrusions.reset_role_visibility_flags(); m_extrusions.reset_ranges(); m_shells.volumes.clear(); @@ -430,7 +459,7 @@ void GCodeViewer::render_toolpaths() const case EViewType::Feedrate: { color = m_extrusions.ranges.feedrate.get_color_at(path.feedrate); break; } case EViewType::FanSpeed: { color = m_extrusions.ranges.fan_speed.get_color_at(path.fan_speed); break; } case EViewType::VolumetricRate: { color = m_extrusions.ranges.volumetric_rate.get_color_at(path.volumetric_rate); break; } - case EViewType::Tool: + case EViewType::Tool: { color = m_tool_colors[path.extruder_id]; break; } case EViewType::ColorPrint: default: { color = { 1.0f, 1.0f, 1.0f }; break; } } @@ -640,7 +669,22 @@ void GCodeViewer::render_overlay() const case EViewType::Feedrate: { add_range(m_extrusions.ranges.feedrate, 1); break; } case EViewType::FanSpeed: { add_range(m_extrusions.ranges.fan_speed, 0); break; } case EViewType::VolumetricRate: { add_range(m_extrusions.ranges.volumetric_rate, 3); break; } - case EViewType::Tool: { break; } + case EViewType::Tool: + { + size_t tools_count = m_tool_colors.size(); + for (size_t i = 0; i < tools_count; ++i) + { + ImVec2 pos(ImGui::GetCursorPosX() + 2.0f, ImGui::GetCursorPosY() + 2.0f); + draw_list->AddRect(ImVec2(pos.x, pos.y), ImVec2(pos.x + ICON_BORDER_SIZE, pos.y + ICON_BORDER_SIZE), ICON_BORDER_COLOR, 0.0f, 0); + const std::array& color = m_tool_colors[i]; + ImU32 fill_color = ImGui::GetColorU32(ImVec4(color[0], color[1], color[2], 1.0)); + draw_list->AddRectFilled(ImVec2(pos.x + 1.0f, pos.y + 1.0f), ImVec2(pos.x + ICON_BORDER_SIZE - 1.0f, pos.y + ICON_BORDER_SIZE - 1.0f), fill_color); + ImGui::SetCursorPosX(pos.x + ICON_BORDER_SIZE + GAP_ICON_TEXT); + ImGui::AlignTextToFramePadding(); + imgui.text((boost::format(Slic3r::I18N::translate(L("Extruder %d"))) % (i + 1)).str()); + } + break; + } case EViewType::ColorPrint: { break; } } diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index a4d42556c..956dd0b5d 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -45,10 +45,12 @@ class GCodeViewer float feedrate{ 0.0f }; float fan_speed{ 0.0f }; float volumetric_rate{ 0.0f }; + unsigned char extruder_id{ 0 }; bool matches(const GCodeProcessor::MoveVertex& move) const { return type == move.type && role == move.extrusion_role && height == move.height && width == move.width && - feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate(); + feedrate == move.feedrate && fan_speed == move.fan_speed && volumetric_rate == move.volumetric_rate() && + extruder_id == move.extruder_id; } }; @@ -146,11 +148,11 @@ public: }; private: + unsigned int m_last_result_id{ 0 }; VBuffer m_vertices; std::vector m_buffers{ static_cast(GCodeProcessor::EMoveType::Extrude) }; BoundingBoxf3 m_bounding_box; - - unsigned int m_last_result_id{ 0 }; + std::vector> m_tool_colors; std::vector m_layers_zs; std::vector m_roles; Extrusions m_extrusions; @@ -167,7 +169,9 @@ public: return init_shaders(); } - void load(const GCodeProcessor::Result& gcode_result, const Print& print, bool initialized); + // extract rendering data from the given parameters + void load(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors, const Print& print, bool initialized); + // recalculate ranges in dependence of what is visible void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); void reset(); diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index e174a5783..540896a59 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -2835,7 +2835,7 @@ static void load_gcode_retractions(const GCodePreviewData::Retraction& retractio #endif // !ENABLE_GCODE_VIEWER #if ENABLE_GCODE_VIEWER -void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) +void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors) { #if ENABLE_GCODE_VIEWER_DEBUG_OUTPUT static unsigned int last_result_id = 0; @@ -2852,7 +2852,7 @@ void GLCanvas3D::load_gcode_preview(const GCodeProcessor::Result& gcode_result) out.close(); } #endif // ENABLE_GCODE_VIEWER_DEBUG_OUTPUT - m_gcode_viewer.load(gcode_result, *this->fff_print(), m_initialized); + m_gcode_viewer.load(gcode_result, str_tool_colors , *this->fff_print(), m_initialized); } void GLCanvas3D::refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result) @@ -6594,6 +6594,7 @@ void GLCanvas3D::_load_wipe_tower_toolpaths(const std::vector& str_ BOOST_LOG_TRIVIAL(debug) << "Loading wipe tower toolpaths in parallel - end" << m_volumes.log_memory_info() << log_memory_info(); } +#if !ENABLE_GCODE_VIEWER static inline int hex_digit_to_int(const char c) { return @@ -6602,7 +6603,6 @@ static inline int hex_digit_to_int(const char c) (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; } -#if !ENABLE_GCODE_VIEWER void GLCanvas3D::_load_gcode_extrusion_paths(const GCodePreviewData& preview_data, const std::vector& tool_colors) { BOOST_LOG_TRIVIAL(debug) << "Loading G-code extrusion paths - start" << m_volumes.log_memory_info() << log_memory_info(); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 312eeaa3b..54f6e181e 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -664,7 +664,7 @@ public: void reload_scene(bool refresh_immediately, bool force_full_scene_refresh = false); #if ENABLE_GCODE_VIEWER - void load_gcode_preview(const GCodeProcessor::Result& gcode_result); + void load_gcode_preview(const GCodeProcessor::Result& gcode_result, const std::vector& str_tool_colors); void refresh_toolpaths_ranges(const GCodeProcessor::Result& gcode_result); #else void load_gcode_preview(const GCodePreviewData& preview_data, const std::vector& str_tool_colors); diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 206051149..9476ad1f0 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -984,7 +984,7 @@ void Preview::load_print_as_fff(bool keep_z_range) if (gcode_preview_data_valid) { // Load the real G-code preview. #if ENABLE_GCODE_VIEWER - m_canvas->load_gcode_preview(*m_gcode_result); + m_canvas->load_gcode_preview(*m_gcode_result, colors); m_canvas->refresh_toolpaths_ranges(*m_gcode_result); #else m_canvas->load_gcode_preview(*m_gcode_preview_data, colors); diff --git a/src/slic3r/GUI/GUI_Utils.hpp b/src/slic3r/GUI/GUI_Utils.hpp index 0d5249e25..057c72b1d 100644 --- a/src/slic3r/GUI/GUI_Utils.hpp +++ b/src/slic3r/GUI/GUI_Utils.hpp @@ -343,6 +343,15 @@ public: std::ostream& operator<<(std::ostream &os, const WindowMetrics& metrics); +#if ENABLE_GCODE_VIEWER +inline int hex_digit_to_int(const char c) +{ + return + (c >= '0' && c <= '9') ? int(c - '0') : + (c >= 'A' && c <= 'F') ? int(c - 'A') + 10 : + (c >= 'a' && c <= 'f') ? int(c - 'a') + 10 : -1; +} +#endif // ENABLE_GCODE_VIEWER }}