Modules | C++

Tetmesh

Constrained Delaunay tetrahedralization of closed surfaces.
This module is in active development: its surface and its results may change between releases.

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

make_tet_mesh.cpp
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:

children.cpp
for (auto facet : face_facets[f])
  for (const auto &triangle : children[facet]) {
    // triangle[0..2] index tets.points()
  }

The Report

StatusMeaning
meshedEvery face and edge recovered and the surface winds consistently
refusedSome 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
unwoundThe surface is open or inconsistently wound; no mesh
rank_deficientThe points do not span three dimensions
capacityThe 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.