diff --git a/src/libslic3r/TriangleSelector.cpp b/src/libslic3r/TriangleSelector.cpp index c7e7ef7b0..ec3b39c34 100644 --- a/src/libslic3r/TriangleSelector.cpp +++ b/src/libslic3r/TriangleSelector.cpp @@ -112,8 +112,9 @@ void TriangleSelector::seed_fill_select_triangles(const Vec3f& hit, int facet_st assert(neighbor_idx >= 0); if (neighbor_idx >= 0 && !visited[neighbor_idx]) { // Check if neighbour_facet_idx is satisfies angle in seed_fill_angle and append it to facet_queue if it do. - double dot_product = m_triangles[neighbor_idx].normal.dot(m_triangles[current_facet].normal); - if (std::clamp(dot_product, 0., 1.) >= facet_angle_limit) + const Vec3f &n1 = m_mesh->stl.facet_start[m_triangles[neighbor_idx].source_triangle].normal; + const Vec3f &n2 = m_mesh->stl.facet_start[m_triangles[current_facet].source_triangle].normal; + if (std::clamp(n1.dot(n2), 0.f, 1.f) >= facet_angle_limit) facet_queue.push(neighbor_idx); } } @@ -201,6 +202,8 @@ void TriangleSelector::set_facet(int facet_idx, EnforcerBlockerType state) m_triangles[facet_idx].set_state(state); } +// called by select_patch()->select_triangle() +// to decide which sides of the traingle to split and to actually split it calling set_division() and perform_split(). void TriangleSelector::split_triangle(int facet_idx) { if (m_triangles[facet_idx].is_split()) { @@ -475,8 +478,7 @@ void TriangleSelector::reset(const EnforcerBlockerType reset_state) m_triangles.reserve(m_mesh->its.indices.size()); for (size_t i=0; iits.indices.size(); ++i) { const stl_triangle_vertex_indices& ind = m_mesh->its.indices[i]; - const Vec3f& normal = m_mesh->stl.facet_start[i].normal; - push_triangle(ind[0], ind[1], ind[2], normal, reset_state); + push_triangle(ind[0], ind[1], ind[2], i, reset_state); } m_orig_size_vertices = m_vertices.size(); m_orig_size_indices = m_triangles.size(); @@ -503,20 +505,20 @@ void TriangleSelector::set_edge_limit(float edge_limit) -void TriangleSelector::push_triangle(int a, int b, int c, const Vec3f& normal, const EnforcerBlockerType state) +void TriangleSelector::push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state) { for (int i : {a, b, c}) { assert(i >= 0 && i < int(m_vertices.size())); ++m_vertices[i].ref_cnt; } - m_triangles.emplace_back(a, b, c, normal, state); + m_triangles.emplace_back(a, b, c, source_triangle, state); } - +// called by deserialize() and select_patch()->select_triangle()->split_triangle() void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_state) { Triangle* tr = &m_triangles[facet_idx]; - const Vec3f normal = tr->normal; + int source_triangle = tr->source_triangle; assert(tr->is_split()); @@ -524,7 +526,7 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat int sides_to_split = tr->number_of_split_sides(); // indices of triangle vertices - std::vector verts_idxs; + boost::container::small_vector verts_idxs; int idx = tr->special_side(); for (int j=0; j<3; ++j) { verts_idxs.push_back(tr->verts_idxs[idx++]); @@ -537,8 +539,8 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[1]].v + m_vertices[verts_idxs[2]].v)/2.); verts_idxs.insert(verts_idxs.begin()+2, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], normal); - push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], normal); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[2], source_triangle); + push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[0], source_triangle); break; case 2: @@ -548,9 +550,9 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[0]].v + m_vertices[verts_idxs[3]].v)/2.); verts_idxs.insert(verts_idxs.begin()+4, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], normal); - push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], normal); - push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], normal); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[4], source_triangle); + push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[4], source_triangle); + push_triangle(verts_idxs[2], verts_idxs[3], verts_idxs[4], source_triangle); break; case 3: @@ -561,10 +563,10 @@ void TriangleSelector::perform_split(int facet_idx, EnforcerBlockerType old_stat m_vertices.emplace_back((m_vertices[verts_idxs[4]].v + m_vertices[verts_idxs[0]].v)/2.); verts_idxs.insert(verts_idxs.begin()+5, m_vertices.size() - 1); - push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], normal); - push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], normal); - push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], normal); - push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], normal); + push_triangle(verts_idxs[0], verts_idxs[1], verts_idxs[5], source_triangle); + push_triangle(verts_idxs[1], verts_idxs[2], verts_idxs[3], source_triangle); + push_triangle(verts_idxs[3], verts_idxs[4], verts_idxs[5], source_triangle); + push_triangle(verts_idxs[1], verts_idxs[3], verts_idxs[5], source_triangle); break; default: @@ -694,6 +696,7 @@ void TriangleSelector::deserialize(const std::pair parents; diff --git a/src/libslic3r/TriangleSelector.hpp b/src/libslic3r/TriangleSelector.hpp index b08858bbb..87f5e8c21 100644 --- a/src/libslic3r/TriangleSelector.hpp +++ b/src/libslic3r/TriangleSelector.hpp @@ -76,19 +76,21 @@ protected: public: // Use TriangleSelector::push_triangle to create a new triangle. // It increments/decrements reference counter on vertices. - Triangle(int a, int b, int c, const Vec3f& normal_, const EnforcerBlockerType init_state) + Triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType init_state) : verts_idxs{a, b, c}, - normal{normal_}, - state{init_state}, - number_of_splits{0}, - special_side_idx{0}, - old_number_of_splits{0} - {} + source_triangle{source_triangle}, + state{init_state} + { + // Initialize bit fields. Default member initializers are not supported by C++17. + m_selected_by_seed_fill = false; + m_valid = true; + old_number_of_splits = 0; + } // Indices into m_vertices. std::array verts_idxs; - // Triangle normal (a shader might need it). - Vec3f normal; + // Index of the source triangle at the initial (unsplit) mesh. + int source_triangle; // Children triangles. std::array children; @@ -118,16 +120,20 @@ protected: private: friend TriangleSelector; - int number_of_splits; - int special_side_idx; + // Packing the rest of member variables into 4 bytes, aligned to 4 bytes boundary. + char number_of_splits { 0 }; + // Index of a vertex opposite to the split edge (for number_of_splits == 1) + // or index of a vertex shared by the two split edges (for number_of_splits == 2). + // For number_of_splits == 3, special_side_idx is always zero. + char special_side_idx { 0 }; EnforcerBlockerType state; - bool m_selected_by_seed_fill = false; + bool m_selected_by_seed_fill : 1; // Is this triangle valid or marked to be removed? - bool m_valid{true}; + bool m_valid : 1; // How many children were spawned during last split? // Is not reset on remerging the triangle. - int old_number_of_splits; + char old_number_of_splits : 2; }; struct Vertex { @@ -185,7 +191,7 @@ private: void remove_useless_children(int facet_idx); // No hidden meaning. Triangles are meant. bool is_pointer_in_triangle(int facet_idx) const; bool is_edge_inside_cursor(int facet_idx) const; - void push_triangle(int a, int b, int c, const Vec3f &normal, const EnforcerBlockerType state = EnforcerBlockerType{0}); + void push_triangle(int a, int b, int c, int source_triangle, const EnforcerBlockerType state = EnforcerBlockerType{0}); void perform_split(int facet_idx, EnforcerBlockerType old_state); }; diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index db64bdab5..d23e28437 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -154,8 +154,9 @@ public: push_geometry(float(x), float(y), float(z), float(nx), float(ny), float(nz)); } - inline void push_geometry(const Vec3d& p, const Vec3d& n) { - push_geometry(p(0), p(1), p(2), n(0), n(1), n(2)); + template + inline void push_geometry(const Eigen::MatrixBase& p, const Eigen::MatrixBase& n) { + push_geometry(float(p(0)), float(p(1)), float(p(2)), float(n(0)), float(n(1)), float(n(2))); } inline void push_triangle(int idx1, int idx2, int idx3) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 236515784..e04a5c49d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -434,12 +434,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) continue; for (int i = 0; i < 3; ++i) - m_iva_colors[color_idx].push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - double(tr.normal[0]), - double(tr.normal[1]), - double(tr.normal[2])); + m_iva_colors[color_idx].push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); m_iva_colors[color_idx].push_triangle(color_cnt[color_idx], color_cnt[color_idx] + 1, color_cnt[color_idx] + 2); color_cnt[color_idx] += 3; } @@ -449,12 +444,7 @@ void TriangleSelectorMmuGui::render(ImGuiWrapper *imgui) 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]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - double(tr.normal[0]), - double(tr.normal[1]), - double(tr.normal[2])); + m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2); seed_fill_cnt += 3; } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index c17163b91..64b41e46e 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -598,12 +598,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) : blc_cnt; for (int i=0; i<3; ++i) - va.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - double(tr.normal[0]), - double(tr.normal[1]), - double(tr.normal[2])); + va.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); va.push_triangle(cnt, cnt + 1, cnt + 2); cnt += 3; } @@ -613,12 +608,7 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) continue; for (int i = 0; i < 3; ++i) - m_iva_seed_fill.push_geometry(double(m_vertices[tr.verts_idxs[i]].v[0]), - double(m_vertices[tr.verts_idxs[i]].v[1]), - double(m_vertices[tr.verts_idxs[i]].v[2]), - double(tr.normal[0]), - double(tr.normal[1]), - double(tr.normal[2])); + m_iva_seed_fill.push_geometry(m_vertices[tr.verts_idxs[i]].v, m_mesh->stl.facet_start[tr.source_triangle].normal); m_iva_seed_fill.push_triangle(seed_fill_cnt, seed_fill_cnt + 1, seed_fill_cnt + 2); seed_fill_cnt += 3; }