From ae53c7cb2ede95bdb7eb1b8e52c95b52b309c3eb Mon Sep 17 00:00:00 2001 From: Enrico Turri Date: Mon, 21 May 2018 15:57:03 +0200 Subject: [PATCH] Volumes rendering moved to c++ --- lib/Slic3r/GUI/3DScene.pm | 88 ++++++++++++++----------- xs/src/slic3r/GUI/3DScene.cpp | 5 ++ xs/src/slic3r/GUI/3DScene.hpp | 1 + xs/src/slic3r/GUI/GLCanvas3D.cpp | 67 +++++++++++++++---- xs/src/slic3r/GUI/GLCanvas3D.hpp | 25 +++---- xs/src/slic3r/GUI/GLCanvas3DManager.cpp | 35 ++++++---- xs/src/slic3r/GUI/GLCanvas3DManager.hpp | 15 +++-- xs/xsp/GUI_3DScene.xsp | 9 ++- 8 files changed, 159 insertions(+), 86 deletions(-) diff --git a/lib/Slic3r/GUI/3DScene.pm b/lib/Slic3r/GUI/3DScene.pm index dcd8e3110..d720b4060 100644 --- a/lib/Slic3r/GUI/3DScene.pm +++ b/lib/Slic3r/GUI/3DScene.pm @@ -1470,7 +1470,10 @@ sub Render { glDisable(GL_MULTISAMPLE) if ($self->{can_multisample}); glDisable(GL_LIGHTING); glDisable(GL_BLEND); - $self->draw_volumes(1); +#============================================================================================================================== + Slic3r::GUI::_3DScene::render_volumes($self, 1); +# $self->draw_volumes(1); +#============================================================================================================================== glPopAttrib(); glFlush(); my $col = [ glReadPixels_p($pos->x, $self->GetSize->GetHeight - $pos->y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE) ]; @@ -1598,7 +1601,10 @@ sub Render { # draw objects if (! $self->use_plain_shader) { - $self->draw_volumes; +#============================================================================================================================== + Slic3r::GUI::_3DScene::render_volumes($self, 0); +# $self->draw_volumes; +#============================================================================================================================== } elsif ($self->UseVBOs) { if ($self->enable_picking) { $self->mark_volumes_for_layer_height; @@ -1663,44 +1669,46 @@ sub Render { $self->SwapBuffers(); } -sub draw_volumes { - # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking. - my ($self, $fakecolor) = @_; - - # do not cull backfaces to show broken geometry, if any - glDisable(GL_CULL_FACE); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - foreach my $volume_idx (0..$#{$self->volumes}) { - my $volume = $self->volumes->[$volume_idx]; - - if ($fakecolor) { - # Object picking mode. Render the object with a color encoding the object index. - my $r = ($volume_idx & 0x000000FF) >> 0; - my $g = ($volume_idx & 0x0000FF00) >> 8; - my $b = ($volume_idx & 0x00FF0000) >> 16; - glColor4f($r/255.0, $g/255.0, $b/255.0, 1); - } elsif ($volume->selected) { - glColor4f(@{ &SELECTED_COLOR }); - } elsif ($volume->hover) { - glColor4f(@{ &HOVER_COLOR }); - } else { - glColor4f(@{ $volume->color }); - } - - $volume->render; - } - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - - glDisable(GL_BLEND); - glEnable(GL_CULL_FACE); -} +#============================================================================================================================== +#sub draw_volumes { +# # $fakecolor is a boolean indicating, that the objects shall be rendered in a color coding the object index for picking. +# my ($self, $fakecolor) = @_; +# +# # do not cull backfaces to show broken geometry, if any +# glDisable(GL_CULL_FACE); +# +# glEnable(GL_BLEND); +# glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +# +# glEnableClientState(GL_VERTEX_ARRAY); +# glEnableClientState(GL_NORMAL_ARRAY); +# +# foreach my $volume_idx (0..$#{$self->volumes}) { +# my $volume = $self->volumes->[$volume_idx]; +# +# if ($fakecolor) { +# # Object picking mode. Render the object with a color encoding the object index. +# my $r = ($volume_idx & 0x000000FF) >> 0; +# my $g = ($volume_idx & 0x0000FF00) >> 8; +# my $b = ($volume_idx & 0x00FF0000) >> 16; +# glColor4f($r/255.0, $g/255.0, $b/255.0, 1); +# } elsif ($volume->selected) { +# glColor4f(@{ &SELECTED_COLOR }); +# } elsif ($volume->hover) { +# glColor4f(@{ &HOVER_COLOR }); +# } else { +# glColor4f(@{ $volume->color }); +# } +# +# $volume->render; +# } +# glDisableClientState(GL_NORMAL_ARRAY); +# glDisableClientState(GL_VERTEX_ARRAY); +# +# glDisable(GL_BLEND); +# glEnable(GL_CULL_FACE); +#} +#============================================================================================================================== sub mark_volumes_for_layer_height { my ($self) = @_; diff --git a/xs/src/slic3r/GUI/3DScene.cpp b/xs/src/slic3r/GUI/3DScene.cpp index 40e6f1851..a7f5bd89e 100644 --- a/xs/src/slic3r/GUI/3DScene.cpp +++ b/xs/src/slic3r/GUI/3DScene.cpp @@ -1938,6 +1938,11 @@ void _3DScene::render_axes(wxGLCanvas* canvas) s_canvas_mgr.render_axes(canvas); } +void _3DScene::render_volumes(wxGLCanvas* canvas, bool fake_colors) +{ + s_canvas_mgr.render_volumes(canvas, fake_colors); +} + void _3DScene::render_cutting_plane(wxGLCanvas* canvas) { s_canvas_mgr.render_cutting_plane(canvas); diff --git a/xs/src/slic3r/GUI/3DScene.hpp b/xs/src/slic3r/GUI/3DScene.hpp index 22b869563..24223b6b6 100644 --- a/xs/src/slic3r/GUI/3DScene.hpp +++ b/xs/src/slic3r/GUI/3DScene.hpp @@ -600,6 +600,7 @@ public: static void render_background(wxGLCanvas* canvas); static void render_bed(wxGLCanvas* canvas); static void render_axes(wxGLCanvas* canvas); + static void render_volumes(wxGLCanvas* canvas, bool fake_colors); static void render_cutting_plane(wxGLCanvas* canvas); static void render_warning_texture(wxGLCanvas* canvas); static void render_legend_texture(wxGLCanvas* canvas); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.cpp b/xs/src/slic3r/GUI/GLCanvas3D.cpp index f55563f7a..80eea86f0 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.cpp @@ -203,7 +203,7 @@ const BoundingBoxf3& GLCanvas3D::Bed::get_bounding_box() const return m_bounding_box; } -void GLCanvas3D::Bed::render() +void GLCanvas3D::Bed::render() const { unsigned int triangles_vcount = m_triangles.get_data_size() / 3; if (triangles_vcount > 0) @@ -311,7 +311,7 @@ void GLCanvas3D::Axes::set_length(float length) m_length = length; } -void GLCanvas3D::Axes::render() +void GLCanvas3D::Axes::render() const { ::glDisable(GL_LIGHTING); // disable depth testing so that axes are not covered by ground @@ -352,14 +352,14 @@ bool GLCanvas3D::CuttingPlane::set(float z, const ExPolygons& polygons) return m_lines.set_from_lines(lines, m_z); } -void GLCanvas3D::CuttingPlane::render(const BoundingBoxf3& bb) +void GLCanvas3D::CuttingPlane::render(const BoundingBoxf3& bb) const { ::glDisable(GL_LIGHTING); _render_plane(bb); _render_contour(); } -void GLCanvas3D::CuttingPlane::_render_plane(const BoundingBoxf3& bb) +void GLCanvas3D::CuttingPlane::_render_plane(const BoundingBoxf3& bb) const { if (m_z >= 0.0f) { @@ -386,7 +386,7 @@ void GLCanvas3D::CuttingPlane::_render_plane(const BoundingBoxf3& bb) } } -void GLCanvas3D::CuttingPlane::_render_contour() +void GLCanvas3D::CuttingPlane::_render_contour() const { ::glEnableClientState(GL_VERTEX_ARRAY); @@ -745,7 +745,7 @@ void GLCanvas3D::select_view(const std::string& direction) } } -void GLCanvas3D::render_background() +void GLCanvas3D::render_background() const { static const float COLOR[3] = { 10.0f / 255.0f, 98.0f / 255.0f, 144.0f / 255.0f }; @@ -776,22 +776,65 @@ void GLCanvas3D::render_background() ::glPopMatrix(); } -void GLCanvas3D::render_bed() +void GLCanvas3D::render_bed() const { m_bed.render(); } -void GLCanvas3D::render_axes() +void GLCanvas3D::render_axes() const { m_axes.render(); } -void GLCanvas3D::render_cutting_plane() +void GLCanvas3D::render_volumes(bool fake_colors) const +{ + static const float INV_255 = 1.0f / 255.0f; + + if (m_volumes == nullptr) + return; + + ::glEnable(GL_LIGHTING); + + // do not cull backfaces to show broken geometry, if any + ::glDisable(GL_CULL_FACE); + + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + ::glEnableClientState(GL_VERTEX_ARRAY); + ::glEnableClientState(GL_NORMAL_ARRAY); + + unsigned int volume_id = 0; + for (const GLVolume* vol : m_volumes->volumes) + { + if (fake_colors) + { + // Object picking mode. Render the object with a color encoding the object index. + unsigned int r = (volume_id & 0x000000FF) >> 0; + unsigned int g = (volume_id & 0x0000FF00) >> 8; + unsigned int b = (volume_id & 0x00FF0000) >> 16; + ::glColor4f((float)r * INV_255, (float)g * INV_255, (float)b * INV_255, 1.0f); + } + else + ::glColor4f(vol->render_color[0], vol->render_color[1], vol->render_color[2], vol->render_color[3]); + + vol->render(); + ++volume_id; + } + + ::glDisableClientState(GL_NORMAL_ARRAY); + ::glDisableClientState(GL_VERTEX_ARRAY); + ::glDisable(GL_BLEND); + + ::glEnable(GL_CULL_FACE); +} + +void GLCanvas3D::render_cutting_plane() const { m_cutting_plane.render(volumes_bounding_box()); } -void GLCanvas3D::render_warning_texture() +void GLCanvas3D::render_warning_texture() const { if (!m_warning_texture_enabled) return; @@ -824,7 +867,7 @@ void GLCanvas3D::render_warning_texture() } } -void GLCanvas3D::render_legend_texture() +void GLCanvas3D::render_legend_texture() const { if (!m_legend_texture_enabled) return; @@ -856,7 +899,7 @@ void GLCanvas3D::render_legend_texture() } } -void GLCanvas3D::render_texture(unsigned int tex_id, float left, float right, float bottom, float top) +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); diff --git a/xs/src/slic3r/GUI/GLCanvas3D.hpp b/xs/src/slic3r/GUI/GLCanvas3D.hpp index de244511a..29be07490 100644 --- a/xs/src/slic3r/GUI/GLCanvas3D.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3D.hpp @@ -89,7 +89,7 @@ public: const BoundingBoxf3& get_bounding_box() const; - void render(); + void render() const; private: void _calc_bounding_box(); @@ -111,7 +111,7 @@ public: float get_length() const; void set_length(float length); - void render(); + void render() const; }; class CuttingPlane @@ -124,11 +124,11 @@ public: bool set(float z, const ExPolygons& polygons); - void render(const BoundingBoxf3& bb); + void render(const BoundingBoxf3& bb) const; private: - void _render_plane(const BoundingBoxf3& bb); - void _render_contour(); + void _render_plane(const BoundingBoxf3& bb) const; + void _render_contour() const; }; class LayersEditing @@ -225,14 +225,15 @@ public: void zoom_to_volumes(); void select_view(const std::string& direction); - void render_background(); - void render_bed(); - void render_axes(); - void render_cutting_plane(); - void render_warning_texture(); - void render_legend_texture(); + void render_background() const; + void render_bed() const; + void render_axes() const; + void render_volumes(bool fake_colors) const; + void render_cutting_plane() const; + void render_warning_texture() const; + void render_legend_texture() const; - void render_texture(unsigned int tex_id, float left, float right, float bottom, float top); + void render_texture(unsigned int tex_id, float left, float right, float bottom, float top) const; void register_on_viewport_changed_callback(void* callback); diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp index 4ff07b782..7e8cf913f 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.cpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.cpp @@ -390,51 +390,58 @@ void GLCanvas3DManager::select_view(wxGLCanvas* canvas, const std::string& direc it->second->select_view(direction); } -void GLCanvas3DManager::render_background(wxGLCanvas* canvas) +void GLCanvas3DManager::render_background(wxGLCanvas* canvas) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_background(); } -void GLCanvas3DManager::render_bed(wxGLCanvas* canvas) +void GLCanvas3DManager::render_bed(wxGLCanvas* canvas) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_bed(); } -void GLCanvas3DManager::render_axes(wxGLCanvas* canvas) +void GLCanvas3DManager::render_axes(wxGLCanvas* canvas) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_axes(); } -void GLCanvas3DManager::render_cutting_plane(wxGLCanvas* canvas) +void GLCanvas3DManager::render_volumes(wxGLCanvas* canvas, bool fake_colors) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); + if (it != m_canvases.end()) + it->second->render_volumes(fake_colors); +} + +void GLCanvas3DManager::render_cutting_plane(wxGLCanvas* canvas) const +{ + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_cutting_plane(); } -void GLCanvas3DManager::render_warning_texture(wxGLCanvas* canvas) +void GLCanvas3DManager::render_warning_texture(wxGLCanvas* canvas) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_warning_texture(); } -void GLCanvas3DManager::render_legend_texture(wxGLCanvas* canvas) +void GLCanvas3DManager::render_legend_texture(wxGLCanvas* canvas) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_legend_texture(); } -void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) +void GLCanvas3DManager::render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const { - CanvasesMap::iterator it = _get_canvas(canvas); + CanvasesMap::const_iterator it = _get_canvas(canvas); if (it != m_canvases.end()) it->second->render_texture(tex_id, left, right, bottom, top); } diff --git a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp index f7293049e..f2ff8a112 100644 --- a/xs/src/slic3r/GUI/GLCanvas3DManager.hpp +++ b/xs/src/slic3r/GUI/GLCanvas3DManager.hpp @@ -107,14 +107,15 @@ public: void zoom_to_volumes(wxGLCanvas* canvas); void select_view(wxGLCanvas* canvas, const std::string& direction); - void render_background(wxGLCanvas* canvas); - void render_bed(wxGLCanvas* canvas); - void render_axes(wxGLCanvas* canvas); - void render_cutting_plane(wxGLCanvas* canvas); - void render_warning_texture(wxGLCanvas* canvas); - void render_legend_texture(wxGLCanvas* canvas); + void render_background(wxGLCanvas* canvas) const; + void render_bed(wxGLCanvas* canvas) const; + void render_axes(wxGLCanvas* canvas) const; + void render_volumes(wxGLCanvas* canvas, bool fake_colors) const; + void render_cutting_plane(wxGLCanvas* canvas) const; + void render_warning_texture(wxGLCanvas* canvas) const; + void render_legend_texture(wxGLCanvas* canvas) const; - void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top); + void render_texture(wxGLCanvas* canvas, unsigned int tex_id, float left, float right, float bottom, float top) const; void register_on_viewport_changed_callback(wxGLCanvas* canvas, void* callback); diff --git a/xs/xsp/GUI_3DScene.xsp b/xs/xsp/GUI_3DScene.xsp index 6fd23a2f0..40332e7ec 100644 --- a/xs/xsp/GUI_3DScene.xsp +++ b/xs/xsp/GUI_3DScene.xsp @@ -461,7 +461,14 @@ render_axes(canvas) SV *canvas; CODE: _3DScene::render_axes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas")); - + +void +render_volumes(canvas, fake_colors) + SV *canvas; + bool fake_colors; + CODE: + _3DScene::render_volumes((wxGLCanvas*)wxPli_sv_2_object(aTHX_ canvas, "Wx::GLCanvas"), fake_colors); + void render_cutting_plane(canvas) SV *canvas;