Track ID: mesh-redesign_20260320
Summary
Extend Mesh<T, Dims, VertexTraits> to support composable vertex trait mixins, per-face normals (lazily computed and cached), a lazy vertex-to-face adjacency index, and a vertex normal helper function. This is a prerequisite for eventually replacing ITK/VTK mesh usage in volume-cartographer and registration-toolkit.
Acceptance Criteria
Implementation Plan
Phase 1: DefaultVertexTraits Restructure
- Task 1.1: Update
TestMesh.cpp — replace NormalTrait/ColorTrait tests with WithNormal/WithColor compositions
- Task 1.2: Add
traits::WithNormal<T,Dims> and traits::WithColor to Mesh.hpp
- Task 1.3: Empty
DefaultVertexTraits; update Doxygen
Phase 2: Lazy Vertex-to-Face Adjacency Index
- Task 2.1: Write tests for
vertexFaces(idx)
- Task 2.2: Add
mutable adjacency storage and buildAdjacency_() helper
- Task 2.3: Implement
vertexFaces(idx)
Phase 3: Lazy Face Normal Cache
- Task 3.1: Write tests for
faceNormal(idx)
- Task 3.2: Add
mutable face normal cache vector to Mesh
- Task 3.3: Implement
faceNormal(idx) with static_assert for Dims == 3
Phase 4: Vertex Normal Helper
- Task 4.1: Write tests for
vertexNormal(mesh, idx)
- Task 4.2: Implement
vertexNormal free function
Notes
WithNormal/WithColor trait mixins are composed via multiple inheritance; downstream I/O functions detect them at compile time via std::void_t + if constexpr
- Face normal cache uses a
mutable std::vector<std::optional<Vec<T,Dims>>> parallel to faces_; slots reset to nullopt on invalidation
- Blocks: #mesh-io (see that issue once created)
Track ID:
mesh-redesign_20260320Summary
Extend
Mesh<T, Dims, VertexTraits>to support composable vertex trait mixins, per-face normals (lazily computed and cached), a lazy vertex-to-face adjacency index, and a vertex normal helper function. This is a prerequisite for eventually replacing ITK/VTK mesh usage in volume-cartographer and registration-toolkit.Acceptance Criteria
traits::WithNormal<T,Dims>andtraits::WithColoradded as composable opt-in mixins;DefaultVertexTraitsemptied and docs updatedvertexFaces(idx)— lazy vertex-to-face adjacency index, invalidated on any topology mutationfaceNormal(idx)— lazily computed and cached per-face normal (3D only); cache invalidated on mutationvertexNormal(mesh, idx)— free helper computing angle-weighted average of incident face normals; no cachingFaceremainsstd::vector<std::size_t>; no breaking change to existing call sitesImplementation Plan
Phase 1: DefaultVertexTraits Restructure
TestMesh.cpp— replaceNormalTrait/ColorTraittests withWithNormal/WithColorcompositionstraits::WithNormal<T,Dims>andtraits::WithColortoMesh.hppDefaultVertexTraits; update DoxygenPhase 2: Lazy Vertex-to-Face Adjacency Index
vertexFaces(idx)mutableadjacency storage andbuildAdjacency_()helpervertexFaces(idx)Phase 3: Lazy Face Normal Cache
faceNormal(idx)mutableface normal cache vector toMeshfaceNormal(idx)withstatic_assertfor Dims == 3Phase 4: Vertex Normal Helper
vertexNormal(mesh, idx)vertexNormalfree functionNotes
WithNormal/WithColortrait mixins are composed via multiple inheritance; downstream I/O functions detect them at compile time viastd::void_t+if constexprmutable std::vector<std::optional<Vec<T,Dims>>>parallel tofaces_; slots reset tonullopton invalidation