mesh_volume — 3D mesh_process op

• Data kinds: mesh → measurement

• Call: import fullseye as fs; fs.ledger.mesh_volume(mesh) -> 'float' (to call the implementation directly, import mesh_props; mesh_props.mesh_volume(mesh) -> 'float'; from the registry, ops3d.get("mesh_volume"))

Usage

Signed volume enclosed by a closed triangle mesh → float.

By the divergence theorem, V = (1/6)·Σ v0 · (v1 × v2). If the face winding points outward (right-handed) the result is positive, if inward it is negative -- the sign is itself the orientation check: if a negative value comes back, the normals are flipped.

Args:

mesh: tuple of (vertices (N,3), faces (M,3)).

Returns:

Signed volume (float, cube (power 3) of the coordinate unit).

Raises:

ValueError: when mesh is not the 2 elements (vertices, faces), the shape is invalid,

coordinates are non-finite, an index is non-integer or out of range, or it is empty.

★The output of voxel_to_mesh (marching cubes) is wound inward, so passing it as is gives a negative value (measured: -985.67 for a cube of 1000 voxels). "Negative = the normals are flipped" is correct, but with this combination, flipped is the default, so if you only want the volume, take abs() or rewind with faces[:, ::-1]. Use it as an orientation check on meshes whose winding you chose yourself (or whose orientation you made consistent).

Limitation (honest): the divergence theorem holds only for closed surfaces. For an open mesh (a scan with holes) a number is still returned, but it is "the volume of the solid whose holes are closed off toward the origin", not the quantity you want. Whether it is closed should be checked by whether boundary_vertices is empty, or boundary_edges of mesh_edge_stats is 0 or not -- check this first. In a mesh with self-intersections, overlapping regions are counted twice with sign (this too is behaviour exactly as the theorem says, and it is not detected).

Reference (public): polyhedron volume via the divergence theorem is a standard formula. For example, C. Zhang & T. Chen, "Efficient feature extraction for 2D/3D objects in mesh representation", ICIP 2001.

Background guides (the physics and conventions behind this op)

• blender_interop — Using Blender alongside — build the shape, measure it with fullseye (pitfalls: axes, units, ground truth)

References (sample data, literature)

• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).

• Operator provenance and references — the sources of the research/methods this op family came from.

Runnable examples (verified samples that actually call this op)

• hull_bounds — py -3.11 examples_3d/hull_bounds.py

• mesh_props — py -3.11 examples_3d/mesh_props.py

• minimal_surfaces — py -3.11 examples_3d/minimal_surfaces.py

Ops the type connects to (they accept measurement as input)

vol_gaussian_psf · fuse_to_voxel · fresnel_reflectance · snell_angle

Same category (mesh_process)

laplacian_smooth · taubin_smooth · decimate_qem · face_normals · vertex_normals · mesh_area · vertex_curvature · face_areas


*Provenance: mesh_props.py — 3D operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.