mesh_volume

Function mesh_volume 

Source
pub fn mesh_volume(mesh: &Mesh) -> f64
Expand 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.