Module adjacency

Source
Expand description

Edge adjacency derived once, so algorithms stop rebuilding it.

§Why this exists

Healing, genus, smoothing, decimation, and decomposition each needed the same fact: which triangles meet along each edge. Every one of them built its own BTreeMap<(u32, u32), _> inline, with its own key convention and its own degenerate-triangle handling. Five implementations of one idea is five places for the invariant to drift.

This derives it once. The algorithms ask questions instead of rebuilding the answer.

§Not a half-edge structure

A true half-edge (or winged-edge) representation stores per-half-edge next/twin/face links and supports mutation through them. That is the right structure for algorithms that rewrite connectivity in place.

This is deliberately less: an immutable, derived index answering adjacency queries over a TriMesh that stays the owner of the data. Every current consumer reads adjacency and writes a new mesh, so nothing needs mutable topology, and a mutable structure would add an invariant to maintain for no consumer.

The name says what it is. If in-place connectivity editing ever appears, that is a separate type, not a field bolted onto this one.

§Degenerate triangles

A triangle with a repeated corner ([4, 4, 7]) has an edge from a vertex to itself. Counting it as adjacency makes a sound mesh look non-manifold. Such triangles are excluded and counted in EdgeAdjacency::degenerate_triangles, matching what audit_mesh already does, so the two never disagree about what is usable.

Structs§

EdgeAdjacency
Edge-to-triangle adjacency over a triangle mesh.
EdgeKey
An undirected edge, canonically ordered so both sides collide.
EdgeUse
One triangle’s use of an edge, and the direction it traversed.