From 63fe2a9fb960ce6b74609dd0f5329f4c69b38bfb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 19 Jul 2018 13:18:19 +0200 Subject: [PATCH] Warning and legend textures moved from _3DScene class to GLCanvas3D class --- xs/src/slic3r/GUI/3DScene.cpp | 272 +---------------------- xs/src/slic3r/GUI/3DScene.hpp | 41 ---- xs/src/slic3r/GUI/GLCanvas3D.cpp | 278 +++++++++++++++++++++++- xs/src/slic3r/GUI/GLCanvas3D.hpp | 35 +++ xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 9 + xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 2 + 6 files changed, 313 insertions(+), 324 deletions(-) diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 565be4438..2ffd788eb 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -22,11 +22,6 @@ #include #include -#include -#include -#include -#include - #include #include "GUI.hpp" @@ -1589,228 +1584,8 @@ void _3DScene::point3_to_verts(const Point3& point, double width, double height, thick_point_to_verts(point, width, height, volume); } -_3DScene::LegendTexture _3DScene::s_legend_texture; -_3DScene::WarningTexture _3DScene::s_warning_texture; GUI::GLCanvas3DManager _3DScene::s_canvas_mgr; -const unsigned char _3DScene::WarningTexture::Background_Color[3] = { 9, 91, 134 }; -const unsigned char _3DScene::WarningTexture::Opacity = 255; - -bool _3DScene::WarningTexture::generate(const std::string& msg) -{ - reset(); - - if (msg.empty()) - return false; - - wxMemoryDC memDC; - // select default font - memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - - // calculates texture size - wxCoord w, h; - memDC.GetTextExtent(msg, &w, &h); - m_width = (int)w; - m_height = (int)h; - - // generates bitmap - wxBitmap bitmap(m_width, m_height); - -#if defined(__APPLE__) || defined(_MSC_VER) - bitmap.UseAlpha(); -#endif - - memDC.SelectObject(bitmap); - memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); - memDC.Clear(); - - memDC.SetTextForeground(*wxWHITE); - - // draw message - memDC.DrawText(msg, 0, 0); - - memDC.SelectObject(wxNullBitmap); - - // Convert the bitmap into a linear data ready to be loaded into the GPU. - wxImage image = bitmap.ConvertToImage(); - image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); - - // prepare buffer - std::vector data(4 * m_width * m_height, 0); - for (int h = 0; h < m_height; ++h) - { - int hh = h * m_width; - unsigned char* px_ptr = data.data() + 4 * hh; - for (int w = 0; w < m_width; ++w) - { - *px_ptr++ = image.GetRed(w, h); - *px_ptr++ = image.GetGreen(w, h); - *px_ptr++ = image.GetBlue(w, h); - *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; - } - } - - // sends buffer to gpu - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - ::glGenTextures(1, &m_id); - ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - ::glBindTexture(GL_TEXTURE_2D, 0); - - return true; -} - -const unsigned char _3DScene::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; -const unsigned char _3DScene::LegendTexture::Background_Color[3] = { 9, 91, 134 }; -const unsigned char _3DScene::LegendTexture::Opacity = 255; - -bool _3DScene::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors) -{ - reset(); - - // collects items to render - auto title = _(preview_data.get_legend_title()); - const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors); - - unsigned int items_count = (unsigned int)items.size(); - if (items_count == 0) - // nothing to render, return - return false; - - wxMemoryDC memDC; - // select default font - memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); - - // calculates texture size - wxCoord w, h; - memDC.GetTextExtent(title, &w, &h); - int title_width = (int)w; - int title_height = (int)h; - - int max_text_width = 0; - int max_text_height = 0; - for (const GCodePreviewData::LegendItem& item : items) - { - memDC.GetTextExtent(GUI::from_u8(item.text), &w, &h); - max_text_width = std::max(max_text_width, (int)w); - max_text_height = std::max(max_text_height, (int)h); - } - - m_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width); - m_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square; - if (items_count > 1) - m_height += (items_count - 1) * Px_Square_Contour; - - // generates bitmap - wxBitmap bitmap(m_width, m_height); - -#if defined(__APPLE__) || defined(_MSC_VER) - bitmap.UseAlpha(); -#endif - - memDC.SelectObject(bitmap); - memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); - memDC.Clear(); - - memDC.SetTextForeground(*wxWHITE); - - // draw title - int title_x = Px_Border; - int title_y = Px_Border; - memDC.DrawText(title, title_x, title_y); - - // draw icons contours as background - int squares_contour_x = Px_Border; - int squares_contour_y = Px_Border + title_height + Px_Title_Offset; - int squares_contour_width = Px_Square + 2 * Px_Square_Contour; - int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour; - if (items_count > 1) - squares_contour_height += (items_count - 1) * Px_Square_Contour; - - wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]); - wxPen pen(color); - wxBrush brush(color); - memDC.SetPen(pen); - memDC.SetBrush(brush); - memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); - - // draw items (colored icon + text) - int icon_x = squares_contour_x + Px_Square_Contour; - int icon_x_inner = icon_x + 1; - int icon_y = squares_contour_y + Px_Square_Contour; - int icon_y_step = Px_Square + Px_Square_Contour; - - int text_x = icon_x + Px_Square + Px_Text_Offset; - int text_y_offset = (Px_Square - max_text_height) / 2; - - int px_inner_square = Px_Square - 2; - - for (const GCodePreviewData::LegendItem& item : items) - { - // draw darker icon perimeter - const std::vector& item_color_bytes = item.color.as_bytes(); - wxImage::HSVValue dark_hsv = wxImage::RGBtoHSV(wxImage::RGBValue(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2])); - dark_hsv.value *= 0.75; - wxImage::RGBValue dark_rgb = wxImage::HSVtoRGB(dark_hsv); - color.Set(dark_rgb.red, dark_rgb.green, dark_rgb.blue, item_color_bytes[3]); - pen.SetColour(color); - brush.SetColour(color); - memDC.SetPen(pen); - memDC.SetBrush(brush); - memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square)); - - // draw icon interior - color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]); - pen.SetColour(color); - brush.SetColour(color); - memDC.SetPen(pen); - memDC.SetBrush(brush); - memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square)); - - // draw text - memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); - - // update y - icon_y += icon_y_step; - } - - memDC.SelectObject(wxNullBitmap); - - // Convert the bitmap into a linear data ready to be loaded into the GPU. - wxImage image = bitmap.ConvertToImage(); - image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); - - // prepare buffer - std::vector data(4 * m_width * m_height, 0); - for (int h = 0; h < m_height; ++h) - { - int hh = h * m_width; - unsigned char* px_ptr = data.data() + 4 * hh; - for (int w = 0; w < m_width; ++w) - { - *px_ptr++ = image.GetRed(w, h); - *px_ptr++ = image.GetGreen(w, h); - *px_ptr++ = image.GetBlue(w, h); - *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; - } - } - - // sends buffer to gpu - ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - ::glGenTextures(1, &m_id); - ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); - ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); - ::glBindTexture(GL_TEXTURE_2D, 0); - - return true; -} - void _3DScene::init_gl() { s_canvas_mgr.init_gl(); @@ -2213,54 +1988,9 @@ void _3DScene::load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* pr s_canvas_mgr.load_gcode_preview(canvas, preview_data, str_tool_colors); } -void _3DScene::generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors) -{ - s_legend_texture.generate(preview_data, tool_colors); -} - void _3DScene::reset_legend_texture() { - s_legend_texture.reset(); -} - -unsigned int _3DScene::get_legend_texture_id() -{ - return s_legend_texture.get_id(); -} - -int _3DScene::get_legend_texture_width() -{ - return s_legend_texture.get_width(); -} - -int _3DScene::get_legend_texture_height() -{ - return s_legend_texture.get_height(); -} - -void _3DScene::generate_warning_texture(const std::string& msg) -{ - s_warning_texture.generate(msg); -} - -void _3DScene::reset_warning_texture() -{ - s_warning_texture.reset(); -} - -unsigned int _3DScene::get_warning_texture_id() -{ - return s_warning_texture.get_id(); -} - -int _3DScene::get_warning_texture_width() -{ - return s_warning_texture.get_width(); -} - -int _3DScene::get_warning_texture_height() -{ - return s_warning_texture.get_height(); + s_canvas_mgr.reset_legend_texture(); } } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 4103d59f3..a2ca1de7c 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -8,7 +8,6 @@ #include "../../libslic3r/Utils.hpp" #include "../../libslic3r/Model.hpp" #include "../../slic3r/GUI/GLCanvas3DManager.hpp" -#include "../../slic3r/GUI/GLTexture.hpp" class wxBitmap; class wxWindow; @@ -441,32 +440,6 @@ private: class _3DScene { - class WarningTexture : public GUI::GLTexture - { - static const unsigned char Background_Color[3]; - static const unsigned char Opacity; - - public: - bool generate(const std::string& msg); - }; - - class LegendTexture : public GUI::GLTexture - { - static const int Px_Title_Offset = 5; - static const int Px_Text_Offset = 5; - static const int Px_Square = 20; - static const int Px_Square_Contour = 1; - static const int Px_Border = Px_Square / 2; - static const unsigned char Squares_Border_Color[3]; - static const unsigned char Background_Color[3]; - static const unsigned char Opacity; - - public: - bool generate(const GCodePreviewData& preview_data, const std::vector& tool_colors); - }; - - static LegendTexture s_legend_texture; - static WarningTexture s_warning_texture; static GUI::GLCanvas3DManager s_canvas_mgr; public: @@ -568,22 +541,8 @@ public: static void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector& str_tool_colors); static void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector& str_tool_colors); - // generates the legend texture in dependence of the current shown view type - static void generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors); static void reset_legend_texture(); - static unsigned int get_legend_texture_id(); - static int get_legend_texture_width(); - static int get_legend_texture_height(); - - // generates a warning texture containing the given message - static void generate_warning_texture(const std::string& msg); - static void reset_warning_texture(); - - static unsigned int get_warning_texture_id(); - static int get_warning_texture_width(); - static int get_warning_texture_height(); - static void thick_lines_to_verts(const Lines& lines, const std::vector& widths, const std::vector& heights, bool closed, double top_z, GLVolume& volume); static void thick_lines_to_verts(const Lines3& lines, const std::vector& widths, const std::vector& heights, bool closed, GLVolume& volume); static void extrusionentity_to_verts(const ExtrusionPath& extrusion_path, float print_z, GLVolume& volume); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index ddc4feec9..684757c79 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -15,6 +15,10 @@ #include #include +#include +#include +#include +#include #include #include @@ -1457,6 +1461,224 @@ float GLCanvas3D::Gizmos::_get_total_overlay_height() const return height; } +const unsigned char GLCanvas3D::WarningTexture::Background_Color[3] = { 9, 91, 134 }; +const unsigned char GLCanvas3D::WarningTexture::Opacity = 255; + +bool GLCanvas3D::WarningTexture::generate(const std::string& msg) +{ + reset(); + + if (msg.empty()) + return false; + + wxMemoryDC memDC; + // select default font + memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + + // calculates texture size + wxCoord w, h; + memDC.GetTextExtent(msg, &w, &h); + m_width = (int)w; + m_height = (int)h; + + // generates bitmap + wxBitmap bitmap(m_width, m_height); + +#if defined(__APPLE__) || defined(_MSC_VER) + bitmap.UseAlpha(); +#endif + + memDC.SelectObject(bitmap); + memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); + memDC.Clear(); + + memDC.SetTextForeground(*wxWHITE); + + // draw message + memDC.DrawText(msg, 0, 0); + + memDC.SelectObject(wxNullBitmap); + + // Convert the bitmap into a linear data ready to be loaded into the GPU. + wxImage image = bitmap.ConvertToImage(); + image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); + + // prepare buffer + std::vector data(4 * m_width * m_height, 0); + for (int h = 0; h < m_height; ++h) + { + int hh = h * m_width; + unsigned char* px_ptr = data.data() + 4 * hh; + for (int w = 0; w < m_width; ++w) + { + *px_ptr++ = image.GetRed(w, h); + *px_ptr++ = image.GetGreen(w, h); + *px_ptr++ = image.GetBlue(w, h); + *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + } + } + + // sends buffer to gpu + ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + ::glGenTextures(1, &m_id); + ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glBindTexture(GL_TEXTURE_2D, 0); + + return true; +} + +const unsigned char GLCanvas3D::LegendTexture::Squares_Border_Color[3] = { 64, 64, 64 }; +const unsigned char GLCanvas3D::LegendTexture::Background_Color[3] = { 9, 91, 134 }; +const unsigned char GLCanvas3D::LegendTexture::Opacity = 255; + +bool GLCanvas3D::LegendTexture::generate(const GCodePreviewData& preview_data, const std::vector& tool_colors) +{ + reset(); + + // collects items to render + auto title = _(preview_data.get_legend_title()); + const GCodePreviewData::LegendItemsList& items = preview_data.get_legend_items(tool_colors); + + unsigned int items_count = (unsigned int)items.size(); + if (items_count == 0) + // nothing to render, return + return false; + + wxMemoryDC memDC; + // select default font + memDC.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); + + // calculates texture size + wxCoord w, h; + memDC.GetTextExtent(title, &w, &h); + int title_width = (int)w; + int title_height = (int)h; + + int max_text_width = 0; + int max_text_height = 0; + for (const GCodePreviewData::LegendItem& item : items) + { + memDC.GetTextExtent(GUI::from_u8(item.text), &w, &h); + max_text_width = std::max(max_text_width, (int)w); + max_text_height = std::max(max_text_height, (int)h); + } + + m_width = std::max(2 * Px_Border + title_width, 2 * (Px_Border + Px_Square_Contour) + Px_Square + Px_Text_Offset + max_text_width); + m_height = 2 * (Px_Border + Px_Square_Contour) + title_height + Px_Title_Offset + items_count * Px_Square; + if (items_count > 1) + m_height += (items_count - 1) * Px_Square_Contour; + + // generates bitmap + wxBitmap bitmap(m_width, m_height); + +#if defined(__APPLE__) || defined(_MSC_VER) + bitmap.UseAlpha(); +#endif + + memDC.SelectObject(bitmap); + memDC.SetBackground(wxBrush(wxColour(Background_Color[0], Background_Color[1], Background_Color[2]))); + memDC.Clear(); + + memDC.SetTextForeground(*wxWHITE); + + // draw title + int title_x = Px_Border; + int title_y = Px_Border; + memDC.DrawText(title, title_x, title_y); + + // draw icons contours as background + int squares_contour_x = Px_Border; + int squares_contour_y = Px_Border + title_height + Px_Title_Offset; + int squares_contour_width = Px_Square + 2 * Px_Square_Contour; + int squares_contour_height = items_count * Px_Square + 2 * Px_Square_Contour; + if (items_count > 1) + squares_contour_height += (items_count - 1) * Px_Square_Contour; + + wxColour color(Squares_Border_Color[0], Squares_Border_Color[1], Squares_Border_Color[2]); + wxPen pen(color); + wxBrush brush(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(squares_contour_x, squares_contour_y, squares_contour_width, squares_contour_height)); + + // draw items (colored icon + text) + int icon_x = squares_contour_x + Px_Square_Contour; + int icon_x_inner = icon_x + 1; + int icon_y = squares_contour_y + Px_Square_Contour; + int icon_y_step = Px_Square + Px_Square_Contour; + + int text_x = icon_x + Px_Square + Px_Text_Offset; + int text_y_offset = (Px_Square - max_text_height) / 2; + + int px_inner_square = Px_Square - 2; + + for (const GCodePreviewData::LegendItem& item : items) + { + // draw darker icon perimeter + const std::vector& item_color_bytes = item.color.as_bytes(); + wxImage::HSVValue dark_hsv = wxImage::RGBtoHSV(wxImage::RGBValue(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2])); + dark_hsv.value *= 0.75; + wxImage::RGBValue dark_rgb = wxImage::HSVtoRGB(dark_hsv); + color.Set(dark_rgb.red, dark_rgb.green, dark_rgb.blue, item_color_bytes[3]); + pen.SetColour(color); + brush.SetColour(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(icon_x, icon_y, Px_Square, Px_Square)); + + // draw icon interior + color.Set(item_color_bytes[0], item_color_bytes[1], item_color_bytes[2], item_color_bytes[3]); + pen.SetColour(color); + brush.SetColour(color); + memDC.SetPen(pen); + memDC.SetBrush(brush); + memDC.DrawRectangle(wxRect(icon_x_inner, icon_y + 1, px_inner_square, px_inner_square)); + + // draw text + memDC.DrawText(GUI::from_u8(item.text), text_x, icon_y + text_y_offset); + + // update y + icon_y += icon_y_step; + } + + memDC.SelectObject(wxNullBitmap); + + // Convert the bitmap into a linear data ready to be loaded into the GPU. + wxImage image = bitmap.ConvertToImage(); + image.SetMaskColour(Background_Color[0], Background_Color[1], Background_Color[2]); + + // prepare buffer + std::vector data(4 * m_width * m_height, 0); + for (int h = 0; h < m_height; ++h) + { + int hh = h * m_width; + unsigned char* px_ptr = data.data() + 4 * hh; + for (int w = 0; w < m_width; ++w) + { + *px_ptr++ = image.GetRed(w, h); + *px_ptr++ = image.GetGreen(w, h); + *px_ptr++ = image.GetBlue(w, h); + *px_ptr++ = image.IsTransparent(w, h) ? 0 : Opacity; + } + } + + // sends buffer to gpu + ::glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + ::glGenTextures(1, &m_id); + ::glBindTexture(GL_TEXTURE_2D, (GLuint)m_id); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)m_width, (GLsizei)m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + ::glBindTexture(GL_TEXTURE_2D, 0); + + return true; +} + GLGizmoBase* GLCanvas3D::Gizmos::_get_current() const { GizmosMap::const_iterator it = m_gizmos.find(m_current); @@ -2079,21 +2301,21 @@ void GLCanvas3D::reload_scene(bool force) if (!contained) { enable_warning_texture(true); - _3DScene::generate_warning_texture(L("Detected object outside print volume")); + _generate_warning_texture(L("Detected object outside print volume")); m_on_enable_action_buttons_callback.call(state == ModelInstance::PVS_Fully_Outside); } else { enable_warning_texture(false); m_volumes.reset_outside_state(); - _3DScene::reset_warning_texture(); + _reset_warning_texture(); m_on_enable_action_buttons_callback.call(!m_model->objects.empty()); } } else { enable_warning_texture(false); - _3DScene::reset_warning_texture(); + _reset_warning_texture(); m_on_enable_action_buttons_callback.call(false); } } @@ -2484,11 +2706,11 @@ void GLCanvas3D::load_gcode_preview(const GCodePreviewData& preview_data, const _load_gcode_unretractions(preview_data); if (m_volumes.empty()) - _3DScene::reset_legend_texture(); + reset_legend_texture(); else { - _3DScene::generate_legend_texture(preview_data, tool_colors); - + _generate_legend_texture(preview_data, tool_colors); + // removes empty volumes m_volumes.volumes.erase(std::remove_if(m_volumes.volumes.begin(), m_volumes.volumes.end(), [](const GLVolume* volume) { return volume->print_zs.empty(); }), m_volumes.volumes.end()); @@ -3176,6 +3398,14 @@ Point GLCanvas3D::get_local_mouse_position() const return Point(mouse_pos.x, mouse_pos.y); } +void GLCanvas3D::reset_legend_texture() +{ + if (!set_current()) + return; + + m_legend_texture.reset(); +} + bool GLCanvas3D::_is_shown_on_screen() const { return (m_canvas != nullptr) ? m_canvas->IsShownOnScreen() : false; @@ -3584,11 +3814,11 @@ void GLCanvas3D::_render_warning_texture() const return; // If the warning texture has not been loaded into the GPU, do it now. - unsigned int tex_id = _3DScene::get_warning_texture_id(); + unsigned int tex_id = m_warning_texture.get_id(); if (tex_id > 0) { - unsigned int w = _3DScene::get_warning_texture_width(); - unsigned int h = _3DScene::get_warning_texture_height(); + int w = m_warning_texture.get_width(); + int h = m_warning_texture.get_height(); if ((w > 0) && (h > 0)) { ::glDisable(GL_DEPTH_TEST); @@ -3617,11 +3847,11 @@ void GLCanvas3D::_render_legend_texture() const return; // If the legend texture has not been loaded into the GPU, do it now. - unsigned int tex_id = _3DScene::get_legend_texture_id(); + unsigned int tex_id = m_legend_texture.get_id(); if (tex_id > 0) { - unsigned int w = _3DScene::get_legend_texture_width(); - unsigned int h = _3DScene::get_legend_texture_height(); + int w = m_legend_texture.get_width(); + int h = m_legend_texture.get_height(); if ((w > 0) && (h > 0)) { ::glDisable(GL_DEPTH_TEST); @@ -4535,5 +4765,29 @@ std::vector GLCanvas3D::_parse_colors(const std::vector& col return output; } +void GLCanvas3D::_generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors) +{ + if (!set_current()) + return; + + m_legend_texture.generate(preview_data, tool_colors); +} + +void GLCanvas3D::_generate_warning_texture(const std::string& msg) +{ + if (!set_current()) + return; + + m_warning_texture.generate(msg); +} + +void GLCanvas3D::_reset_warning_texture() +{ + if (!set_current()) + return; + + m_warning_texture.reset(); +} + } // namespace GUI } // namespace Slic3r diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index cc998226b..d18ca0cab 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -394,9 +394,35 @@ public: GLGizmoBase* _get_current() const; }; + class WarningTexture : public GUI::GLTexture + { + static const unsigned char Background_Color[3]; + static const unsigned char Opacity; + + public: + bool generate(const std::string& msg); + }; + + class LegendTexture : public GUI::GLTexture + { + static const int Px_Title_Offset = 5; + static const int Px_Text_Offset = 5; + static const int Px_Square = 20; + static const int Px_Square_Contour = 1; + static const int Px_Border = Px_Square / 2; + static const unsigned char Squares_Border_Color[3]; + static const unsigned char Background_Color[3]; + static const unsigned char Opacity; + + public: + bool generate(const GCodePreviewData& preview_data, const std::vector& tool_colors); + }; + private: wxGLCanvas* m_canvas; wxGLContext* m_context; + LegendTexture m_legend_texture; + WarningTexture m_warning_texture; wxTimer* m_timer; Camera m_camera; Bed m_bed; @@ -578,6 +604,8 @@ public: Size get_canvas_size() const; Point get_local_mouse_position() const; + void reset_legend_texture(); + private: bool _is_shown_on_screen() const; void _force_zoom_to_bed(); @@ -643,6 +671,13 @@ private: void _on_move(const std::vector& volume_idxs); void _on_select(int volume_idx); + // generates the legend texture in dependence of the current shown view type + void _generate_legend_texture(const GCodePreviewData& preview_data, const std::vector& tool_colors); + + // generates a warning texture containing the given message + void _generate_warning_texture(const std::string& msg); + void _reset_warning_texture(); + static std::vector _parse_colors(const std::vector& colors); }; diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 7a68cbc81..23a8f4c15 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -550,6 +550,15 @@ void GLCanvas3DManager::load_gcode_preview(wxGLCanvas* canvas, const GCodePrevie it->second->load_gcode_preview(*preview_data, str_tool_colors); } +void GLCanvas3DManager::reset_legend_texture() +{ + for (CanvasesMap::value_type& canvas : m_canvases) + { + if (canvas.second != nullptr) + canvas.second->reset_legend_texture(); + } +} + void GLCanvas3DManager::register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback) { CanvasesMap::iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index c813fd477..98205982f 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -137,6 +137,8 @@ public: void load_wipe_tower_toolpaths(wxGLCanvas* canvas, const std::vector& str_tool_colors); void load_gcode_preview(wxGLCanvas* canvas, const GCodePreviewData* preview_data, const std::vector& str_tool_colors); + void reset_legend_texture(); + void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); void register_on_double_click_callback(wxGLCanvas* canvas, void* callback); void register_on_right_click_callback(wxGLCanvas* canvas, void* callback);