From c0092a7b0a3339f234074947570b79237019c6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= Date: Fri, 25 Jun 2021 17:32:47 +0200 Subject: [PATCH] Speed up the rendering of triangles in painting gizmos by only copying triangle data to the GPU when triangles were changed by painting. --- src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp | 13 +++-- .../GUI/Gizmos/GLGizmoMmuSegmentation.cpp | 56 +++++++++++------- .../GUI/Gizmos/GLGizmoMmuSegmentation.hpp | 8 ++- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp | 57 ++++++++++++------- src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp | 7 +++ src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp | 2 + 6 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp index 5fa4ab51d..4048155fe 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp @@ -170,6 +170,7 @@ void GLGizmoFdmSupports::on_render_input_window(float x, float y, float bottom_l if (mv->is_model_part()) { ++idx; m_triangle_selectors[idx]->reset(); + m_triangle_selectors[idx]->request_update_render_data(); } } @@ -285,13 +286,12 @@ void GLGizmoFdmSupports::select_facets_by_angle(float threshold_deg, bool block) // Now calculate dot product of vert_direction and facets' normals. int idx = -1; - for (const stl_facet& facet : mv->mesh().stl.facet_start) { + for (const stl_facet &facet : mv->mesh().stl.facet_start) { ++idx; - if (facet.normal.dot(down) > dot_limit) - m_triangle_selectors[mesh_id]->set_facet(idx, - block - ? EnforcerBlockerType::BLOCKER - : EnforcerBlockerType::ENFORCER); + if (facet.normal.dot(down) > dot_limit) { + m_triangle_selectors[mesh_id]->set_facet(idx, block ? EnforcerBlockerType::BLOCKER : EnforcerBlockerType::ENFORCER); + m_triangle_selectors.back()->request_update_render_data(); + } } } @@ -346,6 +346,7 @@ void GLGizmoFdmSupports::update_from_model_object() m_triangle_selectors.emplace_back(std::make_unique(*mesh)); m_triangle_selectors.back()->deserialize(mv->supported_facets.get_data()); + m_triangle_selectors.back()->request_update_render_data(); } } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 02fd81af8..ef2aac3eb 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -296,8 +296,10 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott if (m_imgui->checkbox(_L("Seed fill"), m_seed_fill_enabled)) if (!m_seed_fill_enabled) - for (auto &triangle_selector : m_triangle_selectors) + for (auto &triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); + triangle_selector->request_update_render_data(); + } m_imgui->text(m_desc["seed_fill_angle"] + ":"); ImGui::AlignTextToFramePadding(); @@ -319,6 +321,7 @@ void GLGizmoMmuSegmentation::on_render_input_window(float x, float y, float bott if (mv->is_model_part()) { ++idx; m_triangle_selectors[idx]->reset(); + m_triangle_selectors[idx]->request_update_render_data(); } } @@ -437,8 +440,9 @@ void GLGizmoMmuSegmentation::init_model_triangle_selectors() const TriangleMesh *mesh = &mv->mesh(); int extruder_idx = (mv->extruder_id() > 0) ? mv->extruder_id() - 1 : 0; - m_triangle_selectors.emplace_back(std::make_unique(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)])); + m_triangle_selectors.emplace_back(std::make_unique(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)])); m_triangle_selectors.back()->deserialize(mv->mmu_segmentation_facets.get_data()); + m_triangle_selectors.back()->request_update_render_data(); } m_original_volumes_extruder_idxs = get_extruder_id_for_volumes(*mo); } @@ -466,10 +470,38 @@ std::array GLGizmoMmuSegmentation::get_cursor_sphere_right_button_colo return {color[0], color[1], color[2], 0.25f}; } -void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) +void TriangleSelectorMmGui::render(ImGuiWrapper *imgui) { static constexpr std::array seed_fill_color{0.f, 1.f, 0.44f, 1.f}; + if (m_update_render_data) + update_render_data(); + + auto *shader = wxGetApp().get_current_shader(); + if (!shader) + return; + assert(shader->get_name() == "gouraud"); + + for (size_t i = 0; i <= m_iva_colors.size(); ++i) { + GLIndexedVertexArray &iva = i == m_iva_colors.size() ? m_iva_seed_fill : m_iva_colors[i]; + if (!iva.vertices_and_normals_interleaved.empty() && m_update_render_data) { + iva.vertices_and_normals_interleaved_size = iva.vertices_and_normals_interleaved.size(); + iva.triangle_indices.assign(iva.vertices_and_normals_interleaved_size / 6, 0); + std::iota(iva.triangle_indices.begin(), iva.triangle_indices.end(), 0); + iva.triangle_indices_size = iva.triangle_indices.size(); + iva.finalize_geometry(true); + } + if (iva.has_VBOs()) { + shader->set_uniform("uniform_color", (i == 0) ? m_default_volume_color : i == m_iva_colors.size() ? seed_fill_color : m_colors[i - 1]); + iva.render(); + } + } + + m_update_render_data = false; +} + +void TriangleSelectorMmGui::update_render_data() +{ for (auto &iva_color : m_iva_colors) iva_color.release_geometry(); m_iva_seed_fill.release_geometry(); @@ -496,24 +528,6 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) } } } - - auto* shader = wxGetApp().get_current_shader(); - if (!shader) - return; - assert(shader->get_name() == "gouraud"); - - for (size_t i = 0; i <= m_iva_colors.size(); ++i) - if (GLIndexedVertexArray &iva = i == m_iva_colors.size() ? m_iva_seed_fill : m_iva_colors[i]; - ! iva.vertices_and_normals_interleaved.empty()) { - iva.vertices_and_normals_interleaved_size = iva.vertices_and_normals_interleaved.size(); - iva.triangle_indices.assign(iva.vertices_and_normals_interleaved_size / 6, 0); - std::iota(iva.triangle_indices.begin(), iva.triangle_indices.end(), 0); - iva.triangle_indices_size = iva.triangle_indices.size(); - iva.finalize_geometry(true); - shader->set_uniform("uniform_color", - (i == 0) ? m_default_volume_color : i == m_iva_colors.size() ? seed_fill_color : m_colors[i - 1]); - iva.render(); - } } wxString GLGizmoMmuSegmentation::handle_snapshot_action_name(bool shift_down, GLGizmoPainterBase::Button button_down) const diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp index 5ece0ec2a..19cc64a72 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.hpp @@ -5,20 +5,22 @@ namespace Slic3r::GUI { -class TriangleSelectorMmuGui : public TriangleSelectorGUI { +class TriangleSelectorMmGui : public TriangleSelectorGUI { public: - explicit TriangleSelectorMmuGui(const TriangleMesh& mesh, const std::vector> &colors, const std::array &default_volume_color) + explicit TriangleSelectorMmGui(const TriangleMesh& mesh, const std::vector> &colors, const std::array &default_volume_color) : TriangleSelectorGUI(mesh), m_colors(colors), m_default_volume_color(default_volume_color) { // Plus 1 is because the first position is allocated for non-painted triangles. m_iva_colors = std::vector(colors.size() + 1); } - ~TriangleSelectorMmuGui() override = default; + ~TriangleSelectorMmGui() override = default; // Render current selection. Transformation matrices are supposed // to be already set. void render(ImGuiWrapper* imgui) override; private: + void update_render_data(); + const std::vector> &m_colors; std::vector m_iva_colors; const std::array m_default_volume_color; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index f672471d6..c265942e5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -402,6 +402,8 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous } else m_triangle_selectors[m_rr.mesh_id]->select_patch(m_rr.hit, int(m_rr.facet), camera_pos, m_cursor_radius, m_cursor_type, new_state, trafo_matrix, m_triangle_splitting_enabled); + + m_triangle_selectors[m_rr.mesh_id]->request_update_render_data(); m_last_mouse_click = mouse_position; } @@ -428,8 +430,10 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous update_raycast_cache(mouse_position, camera, trafo_matrices); auto seed_fill_unselect_all = [this]() { - for (auto &triangle_selector : m_triangle_selectors) + for (auto &triangle_selector : m_triangle_selectors) { triangle_selector->seed_fill_unselect_all_triangles(); + triangle_selector->request_update_render_data(); + } }; if (m_rr.mesh_id == -1) { @@ -447,6 +451,7 @@ bool GLGizmoPainterBase::gizmo_event(SLAGizmoEventType action, const Vec2d& mous assert(m_rr.mesh_id < int(m_triangle_selectors.size())); m_triangle_selectors[m_rr.mesh_id]->seed_fill_select_triangles(m_rr.hit, int(m_rr.facet), m_seed_fill_angle); + m_triangle_selectors[m_rr.mesh_id]->request_update_render_data(); m_seed_fill_last_mesh_id = m_rr.mesh_id; return true; } @@ -589,28 +594,11 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) static constexpr std::array enforcers_color{0.47f, 0.47f, 1.f, 1.f}; static constexpr std::array blockers_color{1.f, 0.44f, 0.44f, 1.f}; - int enf_cnt = 0; - int blc_cnt = 0; - - for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) - iva->release_geometry(); - - for (const Triangle& tr : m_triangles) { - if (!tr.valid() || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE) - continue; - - GLIndexedVertexArray &iva = tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers; - int & cnt = tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt; - - for (int i = 0; i < 3; ++i) - iva.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); - iva.push_triangle(cnt, cnt + 1, cnt + 2); - cnt += 3; + if (m_update_render_data) { + update_render_data(); + m_update_render_data = false; } - for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) - iva->finalize_geometry(true); - auto* shader = wxGetApp().get_current_shader(); if (! shader) return; @@ -635,6 +623,33 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) +void TriangleSelectorGUI::update_render_data() +{ + int enf_cnt = 0; + int blc_cnt = 0; + + for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) + iva->release_geometry(); + + for (const Triangle &tr : m_triangles) { + if (!tr.valid() || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE) + continue; + + GLIndexedVertexArray &iva = tr.get_state() == EnforcerBlockerType::ENFORCER ? m_iva_enforcers : m_iva_blockers; + int & cnt = tr.get_state() == EnforcerBlockerType::ENFORCER ? enf_cnt : blc_cnt; + + for (int i = 0; i < 3; ++i) + iva.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); + iva.push_triangle(cnt, cnt + 1, cnt + 2); + cnt += 3; + } + + for (auto *iva : {&m_iva_enforcers, &m_iva_blockers}) + iva->finalize_geometry(true); +} + + + #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 b64585e9f..bfda33a20 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -38,13 +38,20 @@ public: virtual void render(ImGuiWrapper *imgui); void render() { this->render(nullptr); } + void request_update_render_data() { m_update_render_data = true; }; + #ifdef PRUSASLICER_TRIANGLE_SELECTOR_DEBUG void render_debug(ImGuiWrapper* imgui); bool m_show_triangles{false}; bool m_show_invalid{false}; #endif +protected: + bool m_update_render_data = false; + private: + void update_render_data(); + GLIndexedVertexArray m_iva_enforcers; GLIndexedVertexArray m_iva_blockers; std::array m_varrays; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp index 6b28e8ca7..92b1b6603 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSeam.cpp @@ -127,6 +127,7 @@ void GLGizmoSeam::on_render_input_window(float x, float y, float bottom_limit) if (mv->is_model_part()) { ++idx; m_triangle_selectors[idx]->reset(); + m_triangle_selectors[idx]->request_update_render_data(); } } @@ -257,6 +258,7 @@ void GLGizmoSeam::update_from_model_object() m_triangle_selectors.emplace_back(std::make_unique(*mesh)); m_triangle_selectors.back()->deserialize(mv->seam_facets.get_data()); + m_triangle_selectors.back()->request_update_render_data(); } }