VertexFaceIndex: vertex index to incident face indices built for

indexed_triangle_set.
This commit is contained in:
Vojtech Bubnik 2021-06-01 19:30:26 +02:00
parent 49c2fc160d
commit 0bfc53f5a5
2 changed files with 48 additions and 0 deletions

View File

@ -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>

View File

@ -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.