Tetmesh
The Tetmesh module fills the solid a closed surface encloses with tetrahedra. The surface is recovered exactly: every input face is a union of tetrahedron faces, and the tetrahedralization is constrained Delaunay.
Include the module with:
#include <trueform/tetmesh.hpp>
Meshing a Surface
auto [tets, children, face_facets, report] = tf::make_tet_mesh(mesh.polygons());
if (report.status == tf::tet_mesh_status::meshed) {
for (auto tet : tets.tetrahedra()) {
// tet[0..3] are the corner points
}
}
The input converts once onto the exact integer lattice the library's converter gives its coordinate type, less the ten bits the constraint recovery splits below it, and every output point is a site's exact position mapped back. Where an edge needs a split finer than its frame, or a face a point its lattice does not name, that one site stands below the frame, as deep as the lattice admits — 23 bits for float input, 20 for double — and nothing else moves; report.deep_sites and report.deepest say how many and how deep. Faces that cross each other are cut where they cross, so a self-intersecting surface meshes too. Inside is decided by the surface's winding: a cell is kept when the surface winds around it a positive number of times, so a shell wound inward inside another is a cavity.
The Boundary
Coplanar input triangles that meet, wound alike, form one facet — coplanar exactly, on the lattice. A facet is recovered as one region: its interior edges are not kept, and the tet mesh triangulates its interior freely. Block k of children holds the triangles of the tet mesh that cover facet k, indexed into tets.points() and wound as its faces; block f of face_facets lists, ascending, the facets input face f lies in — one, unless a crossing cut the face:
for (auto facet : face_facets[f])
for (const auto &triangle : children[facet]) {
// triangle[0..2] index tets.points()
}
The Report
| Status | Meaning |
|---|---|
meshed | Every face and edge recovered and the surface winds consistently |
refused | Some edge or face could not be recovered, counted in the report by kind: edges and faces needing a site deeper than the lattice admits, and edges whose recovery would pass the site budget, such as an edge passing a gap far narrower than itself. A mesh is returned only when the surface still winds consistently |
unwound | The surface is open or inconsistently wound; no mesh |
rank_deficient | The points do not span three dimensions |
capacity | The index type cannot name the cells or points |
report.census carries the constraint recovery's counts: segment rounds, corner-shell splits, refused segments, and the face routes — rebuilds, refinements, restorations.
Every tetrahedron is non-negative exactly; report.flat counts those whose corners are coplanar. The mesh is emitted in the output coordinate type, and an export narrower than the lattice, float by default for float input, may flatten a sliver below its resolution past zero; report.inverted counts those cells. Emitting in double, tf::make_tet_mesh<tf::none_t, double>, keeps them positive. A closed surface wound inward encloses only cells of negative winding, so it meshes to no cell at all; report.negative_cells counts them, since the winding states the matter's side and is never repaired.
