Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Bubnik <bubnikv@gmail.com>2021-06-01 20:30:26 +0300
committerVojtech Bubnik <bubnikv@gmail.com>2021-06-01 20:30:26 +0300
commit0bfc53f5a53ca3794e184358c6cc110d0691b663 (patch)
treee0b7d1fabebed5b007fc8e64d7ca596fc43e84e7 /src/libslic3r
parent49c2fc160dee45638cce2086d3141b0aaa97297a (diff)
VertexFaceIndex: vertex index to incident face indices built for
indexed_triangle_set.
Diffstat (limited to 'src/libslic3r')
-rw-r--r--src/libslic3r/TriangleMesh.cpp25
-rw-r--r--src/libslic3r/TriangleMesh.hpp23
2 files changed, 48 insertions, 0 deletions
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<std::vector<size_t>> 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<typename ThrowOnCancelCallback>
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<std::vector<size_t>> 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<size_t>::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<size_t> m_vertex_to_face_start;
+ std::vector<size_t> 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.