From f31c55ceed96cddea7a0e32fb86edac2b6232b85 Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Thu, 24 May 2018 13:46:17 +0200 Subject: [PATCH] 3DScene layer editing overlay textures rendering moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 71 +++--- xs/src/slic3r/GUI/3DScene.cpp | 5 + xs/src/slic3r/GUI/3DScene.hpp | 1 + xs/src/slic3r/GUI/GLCanvas3D.cpp | 315 +++++++++++++++++++++--- xs/src/slic3r/GUI/GLCanvas3D.hpp | 68 ++++- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 7 + xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 1 + xs/xsp/GUI_3DScene.xsp | 6 + 8 files changed, 403 insertions(+), 71 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index 7696e2718..ae91b5247 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1484,6 +1484,11 @@ sub Render { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Slic3r::GUI::_3DScene::render_background($self); Slic3r::GUI::_3DScene::render_bed($self); + Slic3r::GUI::_3DScene::render_axes($self); + Slic3r::GUI::_3DScene::render_objects($self, $self->UseVBOs); + Slic3r::GUI::_3DScene::render_cutting_plane($self); + Slic3r::GUI::_3DScene::render_warning_texture($self); + Slic3r::GUI::_3DScene::render_legend_texture($self); # if ($self->enable_picking && !$self->_mouse_dragging) { # if (my $pos = $self->_mouse_pos) { @@ -1577,17 +1582,9 @@ sub Render { # # glDisable(GL_BLEND); # } -#============================================================================================================================== - - my $volumes_bb = $self->volumes_bounding_box; - -#============================================================================================================================== - Slic3r::GUI::_3DScene::render_axes($self); - Slic3r::GUI::_3DScene::render_objects($self, $self->UseVBOs); - Slic3r::GUI::_3DScene::render_cutting_plane($self); - Slic3r::GUI::_3DScene::render_warning_texture($self); - Slic3r::GUI::_3DScene::render_legend_texture($self); - +# +# my $volumes_bb = $self->volumes_bounding_box; +# # { # # draw axes # # disable depth testing so that axes are not covered by ground @@ -1771,21 +1768,21 @@ sub _load_image_set_texture { return $params; } -sub _variable_layer_thickness_load_overlay_image { - my ($self) = @_; - $self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png') - if (! $self->{layer_preview_annotation}->{loaded}); - return $self->{layer_preview_annotation}->{valid}; -} - -sub _variable_layer_thickness_load_reset_image { - my ($self) = @_; - $self->{layer_preview_reset_image} = $self->_load_image_set_texture('variable_layer_height_reset.png') - if (! $self->{layer_preview_reset_image}->{loaded}); - return $self->{layer_preview_reset_image}->{valid}; -} - #============================================================================================================================== +#sub _variable_layer_thickness_load_overlay_image { +# my ($self) = @_; +# $self->{layer_preview_annotation} = $self->_load_image_set_texture('variable_layer_height_tooltip.png') +# if (! $self->{layer_preview_annotation}->{loaded}); +# return $self->{layer_preview_annotation}->{valid}; +#} +# +#sub _variable_layer_thickness_load_reset_image { +# my ($self) = @_; +# $self->{layer_preview_reset_image} = $self->_load_image_set_texture('variable_layer_height_reset.png') +# if (! $self->{layer_preview_reset_image}->{loaded}); +# return $self->{layer_preview_reset_image}->{valid}; +#} +# ## Paint the tooltip. #sub _render_image { # my ($self, $image, $l, $r, $b, $t) = @_; @@ -1876,27 +1873,21 @@ sub draw_active_object_annotations { glBindTexture(GL_TEXTURE_2D, 0); $self->{layer_height_edit_shader}->disable; - # Paint the tooltip. - if ($self->_variable_layer_thickness_load_overlay_image) { #============================================================================================================================== - my $zoom = Slic3r::GUI::_3DScene::get_camera_zoom($self); - my $gap = 10/$zoom; - my ($l, $r, $b, $t) = ($bar_left - $self->{layer_preview_annotation}->{width}/$zoom - $gap, $bar_left - $gap, $reset_bottom + $self->{layer_preview_annotation}->{height}/$zoom + $gap, $reset_bottom + $gap); - Slic3r::GUI::_3DScene::render_texture($self, $self->{layer_preview_annotation}->{texture_id}, $l, $r, $t, $b); - + Slic3r::GUI::_3DScene::render_layer_editing_textures($self); + +# # Paint the tooltip. +# if ($self->_variable_layer_thickness_load_overlay_image) # my $gap = 10/$self->_zoom; # my ($l, $r, $b, $t) = ($bar_left - $self->{layer_preview_annotation}->{width}/$self->_zoom - $gap, $bar_left - $gap, $reset_bottom + $self->{layer_preview_annotation}->{height}/$self->_zoom + $gap, $reset_bottom + $gap); # $self->_render_image($self->{layer_preview_annotation}, $l, $r, $t, $b); -#============================================================================================================================== - } - - # Paint the reset button. - if ($self->_variable_layer_thickness_load_reset_image) { -#============================================================================================================================== - Slic3r::GUI::_3DScene::render_texture($self, $self->{layer_preview_reset_image}->{texture_id}, $reset_left, $reset_right, $reset_bottom, $reset_top); +# } +# +# # Paint the reset button. +# if ($self->_variable_layer_thickness_load_reset_image) { # $self->_render_image($self->{layer_preview_reset_image}, $reset_left, $reset_right, $reset_bottom, $reset_top); +# } #============================================================================================================================== - } # Paint the graph. #FIXME show some kind of legend. diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index a6e46b11a..5c3492edc 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -2065,6 +2065,11 @@ void _3DScene::render_legend_texture(wxGLCanvas* canvas) s_canvas_mgr.render_legend_texture(canvas); } +void _3DScene::render_layer_editing_textures(wxGLCanvas* canvas) +{ + s_canvas_mgr.render_layer_editing_textures(canvas); +} + void _3DScene::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) { s_canvas_mgr.render_texture(canvas, tex_id, left, right, bottom, top); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 03b242164..cc2d0d5c5 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -631,6 +631,7 @@ public: static void render_cutting_plane(wxGLCanvas* canvas); static void render_warning_texture(wxGLCanvas* canvas); static void render_legend_texture(wxGLCanvas* canvas); + static void render_layer_editing_textures(wxGLCanvas* canvas); static void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index da639b144..a0065348a 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -6,7 +6,9 @@ #include "../../libslic3r/PrintConfig.hpp" #include + #include +#include #include @@ -23,6 +25,9 @@ static const float VIEW_BOTTOM[2] = { 0.0f, 180.0f }; static const float VIEW_FRONT[2] = { 0.0f, 90.0f }; static const float VIEW_REAR[2] = { 180.0f, 90.0f }; +static const float VARIABLE_LAYER_THICKNESS_BAR_WIDTH = 70.0f; +static const float VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT = 22.0f; + namespace Slic3r { namespace GUI { @@ -85,6 +90,94 @@ unsigned int GeometryBuffer::get_data_size() const return (unsigned int)m_data.size(); } +Size::Size() + : m_width(0) + , m_height(0) +{ +} + +Size::Size(int width, int height) + : m_width(width) + , m_height(height) +{ +} + +int Size::get_width() const +{ + return m_width; +} + +void Size::set_width(int width) +{ + m_width = width; +} + +int Size::get_height() const +{ + return m_height; +} + +void Size::set_height(int height) +{ + m_height = height; +} + +Rect::Rect() + : m_left(0.0f) + , m_top(0.0f) + , m_right(0.0f) + , m_bottom(0.0f) +{ +} + +Rect::Rect(float left, float top, float right, float bottom) + : m_left(left) + , m_top(top) + , m_right(right) + , m_bottom(bottom) +{ +} + +float Rect::get_left() const +{ + return m_left; +} + +void Rect::set_left(float left) +{ + m_left = left; +} + +float Rect::get_top() const +{ + return m_top; +} + +void Rect::set_top(float top) +{ + m_top = top; +} + +float Rect::get_right() const +{ + return m_right; +} + +void Rect::set_right(float right) +{ + m_right = right; +} + +float Rect::get_bottom() const +{ + return m_bottom; +} + +void Rect::set_bottom(float bottom) +{ + m_bottom = bottom; +} + GLCanvas3D::Camera::Camera() : m_type(CT_Ortho) , m_zoom(1.0f) @@ -406,16 +499,178 @@ void GLCanvas3D::CuttingPlane::_render_contour() const ::glDisableClientState(GL_VERTEX_ARRAY); } +GLCanvas3D::LayersEditing::GLTextureData::GLTextureData() + : id(0) + , width(0) + , height(0) +{ +} + +GLCanvas3D::LayersEditing::GLTextureData::GLTextureData(unsigned int id, int width, int height) + : id(id) + , width(width) + , height(height) +{ +} + GLCanvas3D::LayersEditing::LayersEditing() : m_enabled(false) { } +GLCanvas3D::LayersEditing::~LayersEditing() +{ + if (m_tooltip_texture.id != 0) + { + ::glDeleteTextures(1, &m_tooltip_texture.id); + m_tooltip_texture = GLTextureData(); + } + + if (m_reset_texture.id != 0) + { + ::glDeleteTextures(1, &m_reset_texture.id); + m_reset_texture = GLTextureData(); + } +} + bool GLCanvas3D::LayersEditing::is_enabled() const { return m_enabled; } +void GLCanvas3D::LayersEditing::render(const GLCanvas3D& canvas) const +{ + const Rect& bar_rect = _get_bar_rect_viewport(canvas); + const Rect& reset_rect = _get_reset_rect_viewport(canvas); + _render_tooltip_texture(canvas, bar_rect, reset_rect); + _render_reset_texture(canvas, reset_rect); +} + +GLCanvas3D::LayersEditing::GLTextureData GLCanvas3D::LayersEditing::_load_texture_from_file(const std::string& filename) const +{ + const std::string& path = resources_dir() + "/icons/"; + + // Load a PNG with an alpha channel. + wxImage image; + if (!image.LoadFile(path + filename, wxBITMAP_TYPE_PNG)) + return GLTextureData(); + + int width = image.GetWidth(); + int height = image.GetHeight(); + int n_pixels = width * height; + + if (n_pixels <= 0) + return GLTextureData(); + + // Get RGB & alpha raw data from wxImage, pack them into an array. + unsigned char* img_rgb = image.GetData(); + if (img_rgb == nullptr) + return GLTextureData(); + + unsigned char* img_alpha = image.GetAlpha(); + + std::vector data(n_pixels * 4, 0); + for (int i = 0; i < n_pixels; ++i) + { + int data_id = i * 4; + int img_id = i * 3; + data[data_id + 0] = img_rgb[img_id + 0]; + data[data_id + 1] = img_rgb[img_id + 1]; + data[data_id + 2] = img_rgb[img_id + 2]; + data[data_id + 3] = (img_alpha != nullptr) ? img_alpha[i] : 255; + } + + // sends data to gpu + GLuint tex_id; + ::glGenTextures(1, &tex_id); + ::glBindTexture(GL_TEXTURE_2D, tex_id); + ::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); + ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, (GLsizei)width, (GLsizei)height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const void*)data.data()); + ::glBindTexture(GL_TEXTURE_2D, 0); + + return GLTextureData((unsigned int)tex_id, width, height); +} + +void GLCanvas3D::LayersEditing::_render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const +{ + if (m_tooltip_texture.id == 0) + { + m_tooltip_texture = _load_texture_from_file("variable_layer_height_tooltip.png"); + if (m_tooltip_texture.id == 0) + return; + } + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + float gap = 10.0f * inv_zoom; + + float bar_left = bar_rect.get_left(); + float reset_bottom = reset_rect.get_bottom(); + + float l = bar_left - (float)m_tooltip_texture.width * inv_zoom - gap; + float r = bar_left - gap; + float t = reset_bottom + (float)m_tooltip_texture.height * inv_zoom + gap; + float b = reset_bottom + gap; + + canvas.render_texture(m_tooltip_texture.id, l, r, b, t); +} + +void GLCanvas3D::LayersEditing::_render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const +{ + if (m_reset_texture.id == 0) + { + m_reset_texture = _load_texture_from_file("variable_layer_height_reset.png"); + if (m_reset_texture.id == 0) + return; + } + + canvas.render_texture(m_reset_texture.id, reset_rect.get_left(), reset_rect.get_right(), reset_rect.get_bottom(), reset_rect.get_top()); +} + +Rect GLCanvas3D::LayersEditing::_get_bar_rect_screen(const GLCanvas3D& canvas) const +{ + const Size& cnv_size = canvas.get_canvas_size(); + float w = (float)cnv_size.get_width(); + float h = (float)cnv_size.get_height(); + + return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, 0.0f, w, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT); +} + +Rect GLCanvas3D::LayersEditing::_get_reset_rect_screen(const GLCanvas3D& canvas) const +{ + const Size& cnv_size = canvas.get_canvas_size(); + float w = (float)cnv_size.get_width(); + float h = (float)cnv_size.get_height(); + + return Rect(w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH, h - VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT, w, h); +} + +Rect GLCanvas3D::LayersEditing::_get_bar_rect_viewport(const GLCanvas3D& canvas) const +{ + const Size& cnv_size = canvas.get_canvas_size(); + float half_w = 0.5f * (float)cnv_size.get_width(); + float half_h = 0.5f * (float)cnv_size.get_height(); + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, half_h * inv_zoom, half_w * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom); +} + +Rect GLCanvas3D::LayersEditing::_get_reset_rect_viewport(const GLCanvas3D& canvas) const +{ + const Size& cnv_size = canvas.get_canvas_size(); + float half_w = 0.5f * (float)cnv_size.get_width(); + float half_h = 0.5f * (float)cnv_size.get_height(); + + float zoom = canvas.get_camera_zoom(); + float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; + + return Rect((half_w - VARIABLE_LAYER_THICKNESS_BAR_WIDTH) * inv_zoom, (-half_h + VARIABLE_LAYER_THICKNESS_RESET_BUTTON_HEIGHT) * inv_zoom, half_w * inv_zoom, -half_h * inv_zoom); +} + GLCanvas3D::Shader::Shader() : m_enabled(false) , m_shader(nullptr) @@ -524,7 +779,6 @@ GLCanvas3D::~GLCanvas3D() bool GLCanvas3D::init(bool useVBOs) { ::glClearColor(0.0f, 0.0f, 0.0f, 1.0f); -// ::glColor3f(1.0f, 0.0f, 0.0f); ::glEnable(GL_DEPTH_TEST); ::glClearDepth(1.0f); ::glDepthFunc(GL_LEQUAL); @@ -540,7 +794,6 @@ bool GLCanvas3D::init(bool useVBOs) GLfloat ambient[4] = { 0.3f, 0.3f, 0.3f, 1.0f }; ::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); -// ::glEnable(GL_LIGHTING); ::glEnable(GL_LIGHT0); ::glEnable(GL_LIGHT1); @@ -968,8 +1221,6 @@ void GLCanvas3D::picking_pass() { if (is_picking_enabled() && !is_mouse_dragging() && (m_volumes != nullptr)) { - const Pointf& pos = get_mouse_position(); -// if (pos) { // Render the object for picking. // FIXME This cannot possibly work in a multi - sampled context as the color gets mangled by the anti - aliasing. // Better to use software ray - casting on a bounding - box hierarchy. @@ -991,12 +1242,11 @@ void GLCanvas3D::picking_pass() if (is_multisample_allowed()) ::glEnable(GL_MULTISAMPLE); -// ::glFlush(); - - const std::pair& cnv_size = _get_canvas_size(); + const Size& cnv_size = get_canvas_size(); + const Pointf& pos = get_mouse_position(); GLubyte color[4]; - ::glReadPixels(pos.x, cnv_size.second - pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); + ::glReadPixels(pos.x, cnv_size.get_height() - pos.y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (void*)color); int volume_id = color[0] + color[1] * 256 + color[2] * 256 * 256; set_hover_volume_id(-1); @@ -1021,7 +1271,6 @@ void GLCanvas3D::picking_pass() } } } -// } } void GLCanvas3D::render_background() const @@ -1181,11 +1430,11 @@ void GLCanvas3D::render_warning_texture() const ::glPushMatrix(); ::glLoadIdentity(); - const std::pair& cnv_size = _get_canvas_size(); + const Size& cnv_size = get_canvas_size(); float zoom = get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; float l = (-0.5f * (float)w) * inv_zoom; - float t = (-0.5f * (float)cnv_size.second + (float)h) * inv_zoom; + float t = (-0.5f * (float)cnv_size.get_height() + (float)h) * inv_zoom; float r = l + (float)w * inv_zoom; float b = t - (float)h * inv_zoom; @@ -1214,11 +1463,11 @@ void GLCanvas3D::render_legend_texture() const ::glPushMatrix(); ::glLoadIdentity(); - const std::pair& cnv_size = _get_canvas_size(); + const Size& cnv_size = get_canvas_size(); float zoom = get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; - float l = (-0.5f * (float)cnv_size.first) * inv_zoom; - float t = (0.5f * (float)cnv_size.second) * inv_zoom; + float l = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; + float t = (0.5f * (float)cnv_size.get_height()) * inv_zoom; float r = l + (float)w * inv_zoom; float b = t - (float)h * inv_zoom; render_texture(tex_id, l, r, b, t); @@ -1229,6 +1478,11 @@ void GLCanvas3D::render_legend_texture() const } } +void GLCanvas3D::render_layer_editing_textures() const +{ + m_layers_editing.render(*this); +} + void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const { ::glColor4f(1.0f, 1.0f, 1.0f, 1.0f); @@ -1278,8 +1532,8 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) if (m_canvas != nullptr) { - const std::pair& cnv_size = _get_canvas_size(); - resize((unsigned int)cnv_size.first, (unsigned int)cnv_size.second); + const Size& cnv_size = get_canvas_size(); + resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); m_canvas->Refresh(); } } @@ -1319,6 +1573,17 @@ void GLCanvas3D::on_char(wxKeyEvent& evt) } } +Size GLCanvas3D::get_canvas_size() const +{ + int w = 0; + int h = 0; + + if (m_canvas != nullptr) + m_canvas->GetSize(&w, &h); + + return Size(w, h); +} + void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) { // Calculate the zoom factor needed to adjust viewport to bounding box. @@ -1333,24 +1598,14 @@ void GLCanvas3D::_zoom_to_bounding_box(const BoundingBoxf3& bbox) if (is_shown_on_screen()) { - const std::pair& cnv_size = _get_canvas_size(); - resize((unsigned int)cnv_size.first, (unsigned int)cnv_size.second); + const Size& cnv_size = get_canvas_size(); + resize((unsigned int)cnv_size.get_width(), (unsigned int)cnv_size.get_height()); if (m_canvas != nullptr) m_canvas->Refresh(); } } } -std::pair GLCanvas3D::_get_canvas_size() const -{ - std::pair ret(0, 0); - - if (m_canvas != nullptr) - m_canvas->GetSize(&ret.first, &ret.second); - - return ret; -} - float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const { float max_bb_size = bbox.max_size(); @@ -1433,8 +1688,8 @@ float GLCanvas3D::_get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) co max_x *= 2.0; max_y *= 2.0; - const std::pair& cnv_size = _get_canvas_size(); - return (float)std::min((coordf_t)cnv_size.first / max_x, (coordf_t)cnv_size.second / max_y); + const Size& cnv_size = get_canvas_size(); + return (float)std::min((coordf_t)cnv_size.get_width() / max_x, (coordf_t)cnv_size.get_height() / max_y); } void GLCanvas3D::_deregister_callbacks() diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index 3c0275c9e..7c32ea06c 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -32,6 +32,46 @@ public: unsigned int get_data_size() const; }; +class Size +{ + int m_width; + int m_height; + +public: + Size(); + Size(int width, int height); + + int get_width() const; + void set_width(int width); + + int get_height() const; + void set_height(int height); +}; + +class Rect +{ + float m_left; + float m_top; + float m_right; + float m_bottom; + +public: + Rect(); + Rect(float left, float top, float right, float bottom); + + float get_left() const; + void set_left(float left); + + float get_top() const; + void set_top(float top); + + float get_right() const; + void set_right(float right); + + float get_bottom() const; + void set_bottom(float bottom); +}; + class GLCanvas3D { public: @@ -135,12 +175,36 @@ public: class LayersEditing { + struct GLTextureData + { + unsigned int id; + int width; + int height; + + GLTextureData(); + GLTextureData(unsigned int id, int width, int height); + }; + bool m_enabled; + mutable GLTextureData m_tooltip_texture; + mutable GLTextureData m_reset_texture; public: LayersEditing(); + ~LayersEditing(); bool is_enabled() const; + + void render(const GLCanvas3D& canvas) const; + + private: + GLTextureData _load_texture_from_file(const std::string& filename) const; + void _render_tooltip_texture(const GLCanvas3D& canvas, const Rect& bar_rect, const Rect& reset_rect) const; + void _render_reset_texture(const GLCanvas3D& canvas, const Rect& reset_rect) const; + Rect _get_bar_rect_screen(const GLCanvas3D& canvas) const; + Rect _get_reset_rect_screen(const GLCanvas3D& canvas) const; + Rect _get_bar_rect_viewport(const GLCanvas3D& canvas) const; + Rect _get_reset_rect_viewport(const GLCanvas3D& canvas) const; }; class Shader @@ -299,6 +363,7 @@ public: void render_cutting_plane() const; void render_warning_texture() const; void render_legend_texture() const; + void render_layer_editing_textures() const; void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; @@ -309,9 +374,10 @@ public: void on_idle(wxIdleEvent& evt); void on_char(wxKeyEvent& evt); + Size get_canvas_size() const; + private: void _zoom_to_bounding_box(const BoundingBoxf3& bbox); - std::pair _get_canvas_size() const; float _get_zoom_to_bounding_box_factor(const BoundingBoxf3& bbox) const; void _deregister_callbacks(); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index c5a15696d..adcae3ddb 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -560,6 +560,13 @@ void GLCanvas3DManager::render_legend_texture(wxGLCanvas* canvas) const it->second->render_legend_texture(); } +void GLCanvas3DManager::render_layer_editing_textures(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->render_layer_editing_textures(); +} + void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const { CanvasesMap::const_iterator it = _get_canvas(canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index e0b2a1d2e..7f64e94b4 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -139,6 +139,7 @@ public: void render_cutting_plane(wxGLCanvas* canvas) const; void render_warning_texture(wxGLCanvas* canvas) const; void render_legend_texture(wxGLCanvas* canvas) const; + void render_layer_editing_textures(wxGLCanvas* canvas) const; void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const; diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index a2be3b1df..306ecf53f 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -632,6 +632,12 @@ render_legend_texture(canvas) CODE: _3DScene::render_legend_texture((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); +void +render_layer_editing_textures(canvas) + SV *canvas; + CODE: + _3DScene::render_layer_editing_textures((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); + void render_texture(canvas, tex_id, left, right, bottom, top) SV *canvas;