pub fn mesh_volume(mesh: &Mesh) -> f64Expand description
Signed volume of a Mesh, via the divergence theorem.
Positive for a closed, outward-wound mesh; negative if inward-wound;
meaningless if the mesh is not closed — the divergence theorem this sum
implements requires a closed surface, and an open one has no true volume
to read regardless of where it sits. That reading is translation-stable
only up to a bounded QUANTIZATION noise floor, not exactly
translation-invariant: mesh_to_tris rounds every coordinate to
kernel::mesh_bridge::SNAP_GRID (1/65536 m, ~15.26 µm) before this
function ever sees it, and a non-grid-aligned translation moves each
vertex’s rounding independently, so the sum drifts by roughly
surface_area * SNAP_GRID (plus, at far-from-origin offsets, the
coarser f32-ulp term the Mesh positions already carried on the way in).
Because it delegates to signed_volume6, which sums about the
operand’s own AABB centre rather than a fixed point, that drift is the
ONLY thing that moves the reading — a world-origin implementation would
additionally vary with the reference point itself, wrong by orders of
magnitude more (see the
mesh_volume_is_stable_far_from_the_world_origin_for_an_open_mesh test
below, which pins the AABB-centred reading’s noise floor and would fail
hard against that class of regression). It is still not the mesh’s actual
volume. Callers that need a trustworthy reading (e.g. reporting a split
zone piece’s volume) must establish closedness first, same requirement
signed_volume6 itself carries.
Delegates to signed_volume_of - itself one line over signed_volume6,
which returns SIX times the volume - rather than dividing here as well.
#2579 landed that helper an hour before this file did, with a doc that says
exactly why the divide belongs in one place: “a caller that wants the VOLUME
divides once, here, rather than growing a second hand-rolled sum in another
module, which is how two producers of the same number start to disagree.”
The reference point is what makes the shared implementation matter:
signed_volume6 deliberately sums about the OPERAND’S OWN AABB CENTRE
rather than the world origin. That
choice is not cosmetic — see signed_volume::signed_volume6’s doc for the
#198779 incident where a world-origin reference turned a crack sliver on a
far-from-origin operand into a wildly wrong, sign-flipping volume. A split
zone piece is exactly the shape of operand that provokes this: it can sit
anywhere in a building/national-grid-scale model and can carry the same
kind of boundary sliver from the cut that produced it, so this function
inherits the AABB-centred reference rather than exposing a second,
world-origin-referenced volume primitive alongside it.
This is a raw, UNGATED kernel primitive — it reads whatever Mesh it is
handed, closed or not, and (via mesh_to_tris) silently drops any
out-of-range-index or non-finite triangle. It is the low-level counterpart
to geom_closure::GeometryHasher::volume, which is the crate’s
closedness-GATED, per-entity volume: that one returns None unless the
hasher’s accumulated GeometryClosure proves the entity is a single
closed orientable solid, but it requires that accumulated per-entity
state — it has nothing to gate a bare, freshly-produced Mesh (e.g. a
zone-split piece) that never went through the hasher. A caller of THIS
function that needs the same trustworthiness guarantee must establish
closedness itself first — router::voids::geom::mesh_is_closed_exact is
the crate’s existing closed-surface check but is pub(super)-scoped to
that module today, so a caller outside it needs either that visibility
widened or an equivalent check of its own — same requirement
GeometryHasher::volume’s own gate establishes upstream.
router::voids::geom::mesh_signed_volume folds the same sum over the f32
positions unsnapped and panics on a bad index; this one reads the kernel
grid through mesh_to_tris.