i
i
i
i
i
i
i
i
12.1. Triangle Meshes 271
Vertex {
// ... per-vertex data ...
Edge e; // any edge leaving vertex
}
In practice the Edge is stored by borrowing two bits of storage from the triangle
index t to store the edge index i, so that the total storage requirements remain the
same.
In this structure the neighbor array for a triangle tells which of the neighboring
triangles’ edges are shared with the three edges of that triangle. With this extra
information, we always know where to find the original triangle, which leads to
an invariant of the data structure: for any jth edge of any triangle t,
t.nbr[j].t.nbr[t.nbr[j].i].t == t.
Knowing which edge we came in through lets us know immediately which edge to
leave through in order to continue traversing around a vertex, leading to a stream-
lined algorithm:
TrianglesOfVertex(v) {
{t, i} = v.e;
do {
{t, i} = t.nbr[i];
} while (t != v.t);
}
The triangle-neighbor structure is quite compact. For a mesh with only vertex
positions, we are storing four numbers (three coordinates and an edge) per vertex
and six (three vertex indices and three edges) per face, for a total of 4n
v
+6n
t
≈
16n
v
units of storage per vertex, compared with 9n
v
for the basic indexed mesh.
The triangle neighbor structure as presented here works only for manifold
meshes, because it depends on returning to the starting triangle to terminate the
traversal of a vertex’s neighbors, which will not happen at a boundary vertex that
doesn’t have a full cycle of triangles. However, it is not difficult to generalize
it to manifolds with boundary, by introducing a suitable sentinel value (such as
−1) for the neighbors of boundary triangles and taking care that the boundary
vertices point to the most counterclockwise neighboring triangle, rather than to
any arbitrary triangle.
The Winged-Edge Structure
One widely used mesh data structure that stores connectivity information at the
edges instead of the faces is the winged-edge data structure. This data struc-