diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index 8f07d3bca9..5273162fdc 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -127,7 +127,7 @@ bool TriangleSelector::select_triangle(int facet_idx, EnforcerBlockerType type, assert(facet_idx < int(m_triangles.size())); Triangle* tr = &m_triangles[facet_idx]; - if (! tr->valid) + if (! tr->valid()) return false; int num_of_inside_vertices = vertices_inside(facet_idx); @@ -177,7 +177,7 @@ bool TriangleSelector::select_triangle(int facet_idx, EnforcerBlockerType type, // Make sure that we did not lose track of invalid triangles. assert(m_invalid_triangles == std::count_if(m_triangles.begin(), m_triangles.end(), - [](const Triangle& tr) { return ! tr.valid; })); + [](const Triangle& tr) { return ! tr.valid(); })); // Do garbage collection maybe? if (2*m_invalid_triangles > int(m_triangles.size())) @@ -213,7 +213,7 @@ void TriangleSelector::split_triangle(int facet_idx) tr->set_division(-1); for (int i=0; i<=tr->number_of_split_sides(); ++i) { m_triangles[tr->children[i]].set_state(old_type); - m_triangles[tr->children[i]].valid = true; + m_triangles[tr->children[i]].m_valid = true; --m_invalid_triangles; } return; @@ -343,7 +343,7 @@ void TriangleSelector::undivide_triangle(int facet_idx) if (tr.is_split()) { for (int i=0; i<=tr.number_of_split_sides(); ++i) { undivide_triangle(tr.children[i]); - m_triangles[tr.children[i]].valid = false; + m_triangles[tr.children[i]].m_valid = false; ++m_invalid_triangles; } tr.set_division(0); // not split @@ -356,7 +356,7 @@ void TriangleSelector::remove_useless_children(int facet_idx) // Check that all children are leafs of the same type. If not, try to // make them (recursive call). Remove them if sucessful. - assert(facet_idx < int(m_triangles.size()) && m_triangles[facet_idx].valid); + assert(facet_idx < int(m_triangles.size()) && m_triangles[facet_idx].valid()); Triangle& tr = m_triangles[facet_idx]; if (! tr.is_split()) { @@ -367,7 +367,7 @@ void TriangleSelector::remove_useless_children(int facet_idx) // Call this for all non-leaf children. for (int child_idx=0; child_idx<=tr.number_of_split_sides(); ++child_idx) { - assert(child_idx < int(m_triangles.size()) && m_triangles[child_idx].valid); + assert(child_idx < int(m_triangles.size()) && m_triangles[child_idx].valid()); if (m_triangles[tr.children[child_idx]].is_split()) remove_useless_children(tr.children[child_idx]); } @@ -397,7 +397,7 @@ void TriangleSelector::garbage_collect() int new_idx = m_orig_size_indices; std::vector new_triangle_indices(m_triangles.size(), -1); for (int i = m_orig_size_indices; i vertex_map(m_vertices.size(), -1); for (const Triangle& tr : m_triangles) { - if (tr.valid && ! tr.is_split() && tr.get_state() == state) { + if (tr.valid() && ! tr.is_split() && tr.get_state() == state) { stl_triangle_vertex_indices indices; for (int i=0; i<3; ++i) { - out.vertices.emplace_back(m_vertices[tr.verts_idxs[i]].v); - indices[i] = out.vertices.size() - 1; + int j = tr.verts_idxs[i]; + if (vertex_map[j] == -1) { + vertex_map[j] = int(out.vertices.size()); + out.vertices.emplace_back(m_vertices[j].v); + } + indices[i] = vertex_map[j]; } out.indices.emplace_back(indices); } @@ -769,7 +774,7 @@ void TriangleSelector::seed_fill_apply_on_triangles(EnforcerBlockerType new_stat triangle.set_state(new_state); for (Triangle &triangle : m_triangles) - if (triangle.is_split() && triangle.valid) { + if (triangle.is_split() && triangle.valid()) { size_t facet_idx = &triangle - &m_triangles.front(); remove_useless_children(facet_idx); } diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index 4fd454055c..21bfc6c987 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -87,9 +87,6 @@ protected: // Triangle normal (a shader might need it). Vec3f normal; - // Is this triangle valid or marked to be removed? - bool valid{true}; - // Children triangles. std::array children; @@ -106,18 +103,24 @@ protected: // Get if the triangle has been selected or not by seed fill. bool is_selected_by_seed_fill() const { assert(! is_split()); return m_selected_by_seed_fill; } + // Is this triangle valid or marked to be removed? + bool valid() const throw() { return m_valid; } // Get info on how it's split. - bool is_split() const { return number_of_split_sides() != 0; } - int number_of_split_sides() const { return number_of_splits; } - int special_side() const { assert(is_split()); return special_side_idx; } - bool was_split_before() const { return old_number_of_splits != 0; } + bool is_split() const throw() { return number_of_split_sides() != 0; } + int number_of_split_sides() const throw() { return number_of_splits; } + int special_side() const throw() { assert(is_split()); return special_side_idx; } + bool was_split_before() const throw() { return old_number_of_splits != 0; } void forget_history() { old_number_of_splits = 0; } private: + friend TriangleSelector; + int number_of_splits; int special_side_idx; EnforcerBlockerType state; bool m_selected_by_seed_fill = false; + // Is this triangle valid or marked to be removed? + bool m_valid{true}; // How many children were spawned during last split? // Is not reset on remerging the triangle. diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 4e90446afb..236515784a 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -430,7 +430,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) for (size_t color_idx = 0; color_idx < m_iva_colors.size(); ++color_idx) { for (const Triangle &tr : m_triangles) { - if (!tr.valid || tr.is_split() || tr.is_selected_by_seed_fill() || tr.get_state() != EnforcerBlockerType(color_idx)) + if (!tr.valid() || tr.is_split() || tr.is_selected_by_seed_fill() || tr.get_state() != EnforcerBlockerType(color_idx)) continue; for (int i = 0; i < 3; ++i) @@ -446,7 +446,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) } for (const Triangle &tr : m_triangles) { - if (!tr.valid || tr.is_split() || !tr.is_selected_by_seed_fill()) continue; + if (!tr.valid() || tr.is_split() || !tr.is_selected_by_seed_fill()) continue; for (int i = 0; i < 3; ++i) m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 268657fce9..c17163b91c 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -587,7 +587,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) m_iva_seed_fill.release_geometry(); for (const Triangle& tr : m_triangles) { - if (!tr.valid || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE || tr.is_selected_by_seed_fill()) + if (!tr.valid() || tr.is_split() || tr.get_state() == EnforcerBlockerType::NONE || tr.is_selected_by_seed_fill()) continue; GLIndexedVertexArray& va = tr.get_state() == EnforcerBlockerType::ENFORCER @@ -609,7 +609,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) } for (const Triangle &tr : m_triangles) { - if (!tr.valid || tr.is_split() || !tr.is_selected_by_seed_fill()) + if (!tr.valid() || tr.is_split() || !tr.is_selected_by_seed_fill()) continue; for (int i = 0; i < 3; ++i)