Half-Edge Data Structure
HalfEdge Structure:
1class HalfEdge:2 def __init__(self, origin_vertex):3 self.origin = origin_vertex # Vertex where the directed half-edge begins4 self.pair = None # Oppositely directed half-edge on adjacent face5 self.next = None # Next half-edge around current face (counter-clockwise)6 self.prev = None # Previous half-edge around current face7 self.face = None # Face bounded by this half-edge89class HalfEdgeMesh:10 def __init__(self):11 self.vertices = []12 self.half_edges = []13 self.faces = []1415 def edge_loop(self, start_he):16 """Traverse all half-edges bounding a face in O(deg(face)) time."""17 curr = start_he18 loop = []19 while True:20 loop.append(curr)21 curr = curr.next22 if curr == start_he:23 break24 return loop
The Half-Edge Data Structure (Doubly Connected Edge List / DCEL) splits each manifold edge into two oppositely directed half-edges. This enables constant-time O(1) adjacency navigation across faces, edges, and vertex star rings.
One-Ring Circulator:
1def one_ring_neighbors(vertex):2 """Yield all adjacent vertices around a 1-ring star in counter-clockwise order."""3 curr_he = vertex.half_edge4 while True:5 yield curr_he.pair.origin # Opposite vertex of the outgoing edge6 # Advance circulator: swing to next incident edge via twin and next7 curr_he = curr_he.prev.pair8 if curr_he == vertex.half_edge:9 break1011def vertex_valence(vertex):12 """Compute number of edges connected to vertex."""13 return sum(1 for _ in one_ring_neighbors(vertex))
A Vertex Circulator queries the 1-ring neighborhood of a vertex without searching the entire mesh. By repeatedly stepping h ← h.prev.pair, it orbits around the center hub in O(k) time proportional to vertex valence.
Related Concepts
NURBS B-spline blending, surface skinning through profile curves, and curve seam alignment.
Manifold geometry, hole filling, half-edge structures, and remeshing.
Half-edge connectivity, boundary loop detection, non-manifold vertex checks, and the Euler-Poincaré characteristic.