From 2b59a16dc7d3206a52eee5201df1bf21eb21e06f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Thu, 7 Oct 2021 12:45:53 +0200 Subject: [PATCH] Refactored rendering of the contour around areas selected by smart fill to prepare it for the FDM supports painting gizmo. --- .../GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 87 ++++--------------- .../GUI/Gizmos/GLGizmoMmuSegmentation.hpp | 18 ---- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 63 +++++++++++++- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 41 +++++++++ 4 files changed, 116 insertions(+), 93 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index e2088d4ac..3153b880b 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -592,11 +592,6 @@ std::array GLGizmoMmuSegmentation::get_cursor_sphere_right_button_colo return {color[0], color[1], color[2], 0.25f}; } -static std::array get_seed_fill_color(const std::array &base_color) -{ - return {base_color[0] * 0.75f, base_color[1] * 0.75f, base_color[2] * 0.75f, 1.f}; -} - void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) { if (m_update_render_data) @@ -612,14 +607,14 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) for (size_t color_idx = 0; color_idx < m_gizmo_scene.triangle_indices.size(); ++color_idx) if (m_gizmo_scene.has_VBOs(color_idx)) { if (color_idx > m_colors.size()) // Seed fill VBO - shader->set_uniform("uniform_color", get_seed_fill_color(color_idx == (m_colors.size() + 1) ? m_default_volume_color : m_colors[color_idx - (m_colors.size() + 1) - 1])); + shader->set_uniform("uniform_color", TriangleSelectorGUI::get_seed_fill_color(color_idx == (m_colors.size() + 1) ? m_default_volume_color : m_colors[color_idx - (m_colors.size() + 1) - 1])); else // Normal VBO shader->set_uniform("uniform_color", color_idx == 0 ? m_default_volume_color : m_colors[color_idx - 1]); m_gizmo_scene.render(color_idx); } - if (m_gizmo_scene.has_contour_VBO()) { + if (m_paint_contour.has_VBO()) { ScopeGuard guard_gouraud([shader]() { shader->start_using(); }); shader->stop_using(); @@ -627,7 +622,7 @@ void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) contour_shader->start_using(); glsafe(::glDepthFunc(GL_LEQUAL)); - m_gizmo_scene.render_contour(); + m_paint_contour.render(); glsafe(::glDepthFunc(GL_LESS)); contour_shader->stop_using(); @@ -666,23 +661,24 @@ void TriangleSelectorMmGui::update_render_data() m_gizmo_scene.finalize_triangle_indices(); + m_paint_contour.release_geometry(); std::vector contour_edges = this->get_seed_fill_contour(); - m_gizmo_scene.contour_vertices.reserve(contour_edges.size() * 6); + m_paint_contour.contour_vertices.reserve(contour_edges.size() * 6); for (const Vec2i &edge : contour_edges) { - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.x()); - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.y()); - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(0)].v.z()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.x()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.y()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(0)].v.z()); - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.x()); - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.y()); - m_gizmo_scene.contour_vertices.emplace_back(m_vertices[edge(1)].v.z()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.x()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.y()); + m_paint_contour.contour_vertices.emplace_back(m_vertices[edge(1)].v.z()); } - m_gizmo_scene.contour_indices.assign(m_gizmo_scene.contour_vertices.size() / 3, 0); - std::iota(m_gizmo_scene.contour_indices.begin(), m_gizmo_scene.contour_indices.end(), 0); - m_gizmo_scene.contour_indices_size = m_gizmo_scene.contour_indices.size(); + m_paint_contour.contour_indices.assign(m_paint_contour.contour_vertices.size() / 3, 0); + std::iota(m_paint_contour.contour_indices.begin(), m_paint_contour.contour_indices.end(), 0); + m_paint_contour.contour_indices_size = m_paint_contour.contour_indices.size(); - m_gizmo_scene.finalize_contour(); + m_paint_contour.finalize_geometry(); } wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const @@ -706,14 +702,6 @@ void GLMmSegmentationGizmo3DScene::release_geometry() { glsafe(::glDeleteBuffers(1, &triangle_indices_VBO_id)); triangle_indices_VBO_id = 0; } - if (this->contour_vertices_VBO_id) { - glsafe(::glDeleteBuffers(1, &this->contour_vertices_VBO_id)); - this->contour_vertices_VBO_id = 0; - } - if (this->contour_indices_VBO_id) { - glsafe(::glDeleteBuffers(1, &this->contour_indices_VBO_id)); - this->contour_indices_VBO_id = 0; - } this->clear(); } @@ -741,29 +729,6 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); } -void GLMmSegmentationGizmo3DScene::render_contour() const -{ - assert(this->contour_vertices_VBO_id != 0); - assert(this->contour_indices_VBO_id != 0); - - glsafe(::glLineWidth(4.0f)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_vertices_VBO_id)); - glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr)); - - glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); - - if (this->contour_indices_size > 0) { - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->contour_indices_VBO_id)); - glsafe(::glDrawElements(GL_LINES, GLsizei(this->contour_indices_size), GL_UNSIGNED_INT, nullptr)); - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); - } - - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); -} - void GLMmSegmentationGizmo3DScene::finalize_vertices() { assert(this->vertices_VBO_id == 0); @@ -791,26 +756,4 @@ void GLMmSegmentationGizmo3DScene::finalize_triangle_indices() } } -void GLMmSegmentationGizmo3DScene::finalize_contour() -{ - assert(this->contour_vertices_VBO_id == 0); - assert(this->contour_indices_VBO_id == 0); - - if (!this->contour_vertices.empty()) { - glsafe(::glGenBuffers(1, &this->contour_vertices_VBO_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_vertices_VBO_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_vertices.size() * sizeof(float), this->contour_vertices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - this->contour_vertices.clear(); - } - - if (!this->contour_indices.empty()) { - glsafe(::glGenBuffers(1, &this->contour_indices_VBO_id)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->contour_indices_VBO_id)); - glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW)); - glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); - this->contour_indices.clear(); - } -} - } // namespace Slic3r diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 851a5ac4f..604edf64d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -25,8 +25,6 @@ public: return this->triangle_indices_VBO_ids[triangle_indices_idx] != 0; } - [[nodiscard]] inline bool has_contour_VBO() const { return this->contour_indices_VBO_id != 0; } - // Release the geometry data, release OpenGL VBOs. void release_geometry(); // Finalize the initialization of the geometry, upload the geometry to OpenGL VBO objects @@ -35,9 +33,6 @@ public: // Finalize the initialization of the indices, upload the indices to OpenGL VBO objects // and possibly releasing it if it has been loaded into the VBOs. void finalize_triangle_indices(); - // Finalize the initialization of the contour geometry and the indices, upload both to OpenGL VBO objects - // and possibly releasing it if it has been loaded into the VBOs. - void finalize_contour(); void clear() { @@ -47,34 +42,21 @@ public: for (size_t &triangle_indices_size : this->triangle_indices_sizes) triangle_indices_size = 0; - - this->contour_vertices.clear(); - this->contour_indices.clear(); - this->contour_indices_size = 0; } void render(size_t triangle_indices_idx) const; - void render_contour() const; - std::vector vertices; std::vector> triangle_indices; - std::vector contour_vertices; - std::vector contour_indices; - // When the triangle indices are loaded into the graphics card as Vertex Buffer Objects, // the above mentioned std::vectors are cleared and the following variables keep their original length. std::vector triangle_indices_sizes; - size_t contour_indices_size{0}; // IDs of the Vertex Array Objects, into which the geometry has been loaded. // Zero if the VBOs are not sent to GPU yet. unsigned int vertices_VBO_id{0}; std::vector triangle_indices_VBO_ids; - - unsigned int contour_vertices_VBO_id{0}; - unsigned int contour_indices_VBO_id{0}; }; class TriangleSelectorMmGui : public TriangleSelectorGUI { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 42bdd0843..56073b5b7 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -541,7 +541,10 @@ void GLGizmoPainterBase::on_load(cereal::BinaryInputArchive&) m_schedule_update = true; } - +std::array TriangleSelectorGUI::get_seed_fill_color(const std::array &base_color) +{ + return {base_color[0] * 0.75f, base_color[1] * 0.75f, base_color[2] * 0.75f, 1.f}; +} void TriangleSelectorGUI::render(ImGuiWrapper* imgui) { @@ -575,8 +578,6 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) #endif } - - void TriangleSelectorGUI::update_render_data() { int enf_cnt = 0; @@ -608,7 +609,63 @@ void TriangleSelectorGUI::update_render_data() iva->finalize_geometry(true); } +void GLPaintContour::render() const +{ + assert(this->m_contour_VBO_id != 0); + assert(this->m_contour_EBO_id != 0); + glsafe(::glLineWidth(4.0f)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_contour_VBO_id)); + glsafe(::glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), nullptr)); + + glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); + + if (this->contour_indices_size > 0) { + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->m_contour_EBO_id)); + glsafe(::glDrawElements(GL_LINES, GLsizei(this->contour_indices_size), GL_UNSIGNED_INT, nullptr)); + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + } + + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); +} + +void GLPaintContour::finalize_geometry() +{ + assert(this->m_contour_VBO_id == 0); + assert(this->m_contour_EBO_id == 0); + + if (!this->contour_vertices.empty()) { + glsafe(::glGenBuffers(1, &this->m_contour_VBO_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_contour_VBO_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_vertices.size() * sizeof(float), this->contour_vertices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + this->contour_vertices.clear(); + } + + if (!this->contour_indices.empty()) { + glsafe(::glGenBuffers(1, &this->m_contour_EBO_id)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->m_contour_EBO_id)); + glsafe(::glBufferData(GL_ARRAY_BUFFER, this->contour_indices.size() * sizeof(unsigned int), this->contour_indices.data(), GL_STATIC_DRAW)); + glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); + this->contour_indices.clear(); + } +} + +void GLPaintContour::release_geometry() +{ + if (this->m_contour_VBO_id) { + glsafe(::glDeleteBuffers(1, &this->m_contour_VBO_id)); + this->m_contour_VBO_id = 0; + } + if (this->m_contour_EBO_id) { + glsafe(::glDeleteBuffers(1, &this->m_contour_EBO_id)); + this->m_contour_EBO_id = 0; + } + this->clear(); +} #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG void TriangleSelectorGUI::render_debug(ImGuiWrapper* imgui) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 8d37f2404..172e876d3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -10,6 +10,7 @@ #include "libslic3r/Model.hpp" #include +#include @@ -26,6 +27,41 @@ enum class PainterGizmoType { MMU_SEGMENTATION }; +class GLPaintContour +{ +public: + GLPaintContour() = default; + + void render() const; + + inline bool has_VBO() const { return this->m_contour_EBO_id != 0; } + + // Release the geometry data, release OpenGL VBOs. + void release_geometry(); + + // Finalize the initialization of the contour geometry and the indices, upload both to OpenGL VBO objects + // and possibly releasing it if it has been loaded into the VBOs. + void finalize_geometry(); + + void clear() + { + this->contour_vertices.clear(); + this->contour_indices.clear(); + this->contour_indices_size = 0; + } + + std::vector contour_vertices; + std::vector contour_indices; + + // When the triangle indices are loaded into the graphics card as Vertex Buffer Objects, + // the above mentioned std::vectors are cleared and the following variables keep their original length. + size_t contour_indices_size{0}; + + // IDs of the Vertex Array Objects, into which the geometry has been loaded. + // Zero if the VBOs are not sent to GPU yet. + GLuint m_contour_VBO_id{0}; + GLuint m_contour_EBO_id{0}; +}; class TriangleSelectorGUI : public TriangleSelector { public: @@ -49,12 +85,17 @@ public: protected: bool m_update_render_data = false; + static std::array get_seed_fill_color(const std::array &base_color); + private: void update_render_data(); GLIndexedVertexArray m_iva_enforcers; GLIndexedVertexArray m_iva_blockers; std::array m_varrays; + +protected: + GLPaintContour m_paint_contour; }; class GLGizmoTransparentRender