Speed up the rendering of triangles in painting gizmos by only copying triangle data to the GPU when triangles were changed by painting.
This commit is contained in:
parent
28219142c5
commit
c0092a7b0a
6 changed files with 92 additions and 51 deletions
|
@ -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<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->supported_facets.get_data());
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TriangleSelectorMmuGui>(*mesh, m_modified_extruders_colors, m_original_extruders_colors[size_t(extruder_idx)]));
|
||||
m_triangle_selectors.emplace_back(std::make_unique<TriangleSelectorMmGui>(*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<float, 4> 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<float, 4> 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
|
||||
|
|
|
@ -5,20 +5,22 @@
|
|||
|
||||
namespace Slic3r::GUI {
|
||||
|
||||
class TriangleSelectorMmuGui : public TriangleSelectorGUI {
|
||||
class TriangleSelectorMmGui : public TriangleSelectorGUI {
|
||||
public:
|
||||
explicit TriangleSelectorMmuGui(const TriangleMesh& mesh, const std::vector<std::array<float, 4>> &colors, const std::array<float, 4> &default_volume_color)
|
||||
explicit TriangleSelectorMmGui(const TriangleMesh& mesh, const std::vector<std::array<float, 4>> &colors, const std::array<float, 4> &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<GLIndexedVertexArray>(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<std::array<float, 4>> &m_colors;
|
||||
std::vector<GLIndexedVertexArray> m_iva_colors;
|
||||
const std::array<float, 4> m_default_volume_color;
|
||||
|
|
|
@ -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<float, 4> enforcers_color{0.47f, 0.47f, 1.f, 1.f};
|
||||
static constexpr std::array<float, 4> 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)
|
||||
{
|
||||
|
|
|
@ -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<GLIndexedVertexArray, 3> m_varrays;
|
||||
|
|
|
@ -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<TriangleSelectorGUI>(*mesh));
|
||||
m_triangle_selectors.back()->deserialize(mv->seam_facets.get_data());
|
||||
m_triangle_selectors.back()->request_update_render_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue