From 0bfc53f5a53ca3794e184358c6cc110d0691b663 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Tue, 1 Jun 2021 19:30:26 +0200 Subject: [PATCH] VertexFaceIndex: vertex index to incident face indices built for indexed_triangle_set. --- src/libslic3r/TriangleMesh.cpp | 25 +++++++++++++++++++++++++ src/libslic3r/TriangleMesh.hpp | 23 +++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/libslic3r/TriangleMesh.cpp b/src/libslic3r/TriangleMesh.cpp index 4954ff46c..a8e952a2b 100644 --- a/src/libslic3r/TriangleMesh.cpp +++ b/src/libslic3r/TriangleMesh.cpp @@ -685,6 +685,31 @@ std::vector> create_vertex_faces_index(const indexed_triangl return index; } +void VertexFaceIndex::create(const indexed_triangle_set &its) +{ + m_vertex_to_face_start.assign(its.vertices.size() + 1, 0); + // 1) Calculate vertex incidence by scatter. + for (auto &face : its.indices) { + ++ m_vertex_to_face_start[face(0) + 1]; + ++ m_vertex_to_face_start[face(1) + 1]; + ++ m_vertex_to_face_start[face(2) + 1]; + } + // 2) Prefix sum to calculate offsets to m_vertex_faces_all. + for (size_t i = 2; i < m_vertex_to_face_start.size(); ++ i) + m_vertex_to_face_start[i] += m_vertex_to_face_start[i - 1]; + // 3) Scatter indices of faces incident to a vertex into m_vertex_faces_all. + m_vertex_faces_all.assign(m_vertex_to_face_start.back(), 0); + for (size_t face_idx = 0; face_idx < its.indices.size(); ++ face_idx) { + auto &face = its.indices[face_idx]; + for (int i = 0; i < 3; ++ i) + m_vertex_faces_all[m_vertex_to_face_start[face(i)] ++] = face_idx; + } + // 4) The previous loop modified m_vertex_to_face_start. Revert the change. + for (auto i = int(m_vertex_to_face_start.size()) - 1; i > 0; -- i) + m_vertex_to_face_start[i] = m_vertex_to_face_start[i - 1]; + m_vertex_to_face_start.front() = 0; +} + // Map from a face edge to a unique edge identifier or -1 if no neighbor exists. // Two neighbor faces share a unique edge identifier even if they are flipped. template diff --git a/src/libslic3r/TriangleMesh.hpp b/src/libslic3r/TriangleMesh.hpp index 55fffa726..6d7fd48e4 100644 --- a/src/libslic3r/TriangleMesh.hpp +++ b/src/libslic3r/TriangleMesh.hpp @@ -93,6 +93,29 @@ private: // vertex. std::vector> create_vertex_faces_index(const indexed_triangle_set &its); +// Index of face indices incident with a vertex index. +struct VertexFaceIndex +{ +public: + using iterator = std::vector::const_iterator; + + VertexFaceIndex(const indexed_triangle_set &its) { this->create(its); } + VertexFaceIndex() {} + + void create(const indexed_triangle_set &its); + void clear() { m_vertex_to_face_start.clear(); m_vertex_faces_all.clear(); } + + // Iterators of face indices incident with the input vertex_id. + iterator begin(size_t vertex_id) const throw() { return m_vertex_faces_all.begin() + m_vertex_to_face_start[vertex_id]; } + iterator end (size_t vertex_id) const throw() { return m_vertex_faces_all.begin() + m_vertex_to_face_start[vertex_id + 1]; } + // Vertex incidence. + size_t count(size_t vertex_id) const throw() { return m_vertex_to_face_start[vertex_id + 1] - m_vertex_to_face_start[vertex_id]; } + +private: + std::vector m_vertex_to_face_start; + std::vector m_vertex_faces_all; +}; + // Map from a face edge to a unique edge identifier or -1 if no neighbor exists. // Two neighbor faces share a unique edge identifier even if they are flipped. // Used for chaining slice lines into polygons.