Volume straight from the descriptor

Updated 2026-10-30 15:31; study: ~/code/data/meshes/fcp_3010_hull (sections/hull/README.txt).

Package v5.31 (commit db3e6ceb; the working tree only raises MAX_ATOMS), defaults (parts="tracked-fit", interp="poly", the gwn point slicer), 128 layers, 2048 atoms; the 12 objects of the collision section. The exact volume is the source mesh's (tetrahedra over its faces). From each mesh, 20k area-uniform surface points (seed 3) with the true normals; every point method gets the same points. FCP's volume is one contraction of the stored atoms: a ring's area is π Σk k (ax,kby,k − bx,kay,k) in its Fourier coefficients, and the height atoms are orthonormal on a part's layer centres, so the sum of the ring areas over the layers is the same expression in the atom vectors: V = dz · ∏scale · π Σparts sign · |Σk k (⟨ax,k, by,k⟩ − ⟨bx,k, ay,k⟩)| (the midpoint rule over the layers; no ring is evaluated, no grid, no mesh; one numba loop). Standard route from points: screened Poisson reconstruction (Open3D 0.20, depth 8), then its mesh's volume, with the true normals (the best case) and with normals estimated from the points (what a scan gives). CPU: Intel i5-10400F; FCP's encode on numba's 12 threads and on a GTX 1650; Poisson on one thread (its threaded run was slower here). Times are medians over the objects.

methodvolume error, median |%|max |%|objects within 1 % building the representation, msthe volume, µs
exact: tetrahedron sum over the source meshexactexact12 / 12–51.9
FCP from the mesh (encode 2048 atoms, 128 layers)0.310.7412 / 12124 (87 ms on CUDA)38.0
FCP from 20k points (same encode, no normals)0.251.7611 / 122791 (981 ms on CUDA)32.2
FCP from the mesh (128 layers, 6144 atoms)0.170.7412 / 12111 (63 ms on CUDA)48.8
FCP from 20k points (128 layers, 6144 atoms)0.281.8211 / 122430 (914 ms on CUDA)41.4
FCP from the mesh (256 layers, 6144 atoms)0.130.7112 / 12199 (126 ms on CUDA)48.4
FCP from 20k points (256 layers, 6144 atoms)0.241.8711 / 124237 (1430 ms on CUDA)45.6
screened Poisson (depth 8) from 20k points, true normals0.220.9012 / 121484 (1 thread)6306.4
screened Poisson from 20k points, normals estimated (30 neighbours, tangent-plane orientation)71.62151.842 / 122291 (1 thread, normals included)7526.9

Accuracy: FCP is within 0.74 % of the exact volume from the mesh (median 0.31 %) and within 1.76 % from the points (median 0.25 %), without normals; Poisson with the true normals is as close (median 0.22 %, max 0.90 %). With estimated normals Poisson is off by more than 5 % on 10 of 12 objects (bowl +152 %, bowl serving +145 %, mug +141 %, bowl dog +125 %, flower pot +109 %, mug ace +85 %, shoe +58 %, jogger +19 %, dino +6 %, spring -20 %): on the thin-walled ones the orientation flips across a wall and the surface closes over the opening (renders). More atoms, more layers: 6144 atoms at 128 layers and at 256 layers move the error little: from the mesh the median falls 0.31 → 0.17 → 0.13 % but the worst stays 0.71 %; from the points it is 0.25 / 0.28 / 0.24 %. The per-object errors keep their sign and size across the settings (mugs and bowls 0.2–0.7 % low, the spring from points 1.8 % high): a bias of the encoding and of the point slicer, not a shortage of atoms. The 6144-atom runs had other jobs on the machine (load average about 7, against about 0 for the 2048 run): their times in the first table are upper bounds. Time: once encoded, FCP's volume takes 20–57 µs, about the cost of the tetrahedron sum over the source mesh itself (27–235 µs, numba): faster on 9 of 12 objects, the gain growing with the mesh (spring, 77k faces: 5.1×); the volume of a Poisson mesh takes 3.3–12.7 ms (NumPy). The cost from points is the encode: 2.8 s on the CPU and 1.0 s on CUDA (median), against 1.5 s for Poisson on one thread; the descriptor, once made, also answers the other queries of this report. Caveats: clean, complete, uniformly sampled points; Poisson's meshes are not watertight by Open3D's strict test (the volume is taken as is, its sign ignored); learned reconstruction is not compared.

objectmesh facesFCP from mesh, error % (128 layers, 2048 atoms)FCP from points, error % (128, 2048) from mesh (128, 6144)from points (128, 6144)from mesh (256, 6144)from points (256, 6144) Poisson, true normals, error %Poisson, estimated normals, error %exact volume, µs FCP volume, µs (128, 2048)FCP encode from mesh, ms (CPU; 128, 2048)FCP encode from points, ms (CPU; 128, 2048) FCP encode from points, ms (CUDA; 128, 2048)Poisson, true normals, msPoisson, estimated normals, ms
mug8454-0.53-0.40-0.52-0.40-0.52-0.430.44140.96272982252395114692280
mug ace11224-0.090.00-0.09-0.00-0.010.040.5884.9234351473620131714992276
bowl14030-0.39-0.18-0.39-0.18-0.42-0.190.76151.84793299284099613232076
bowl serving5946-0.49-0.30-0.48-0.30-0.48-0.300.90145.353420117225695611971965
bowl dog4612-0.74-0.37-0.74-0.37-0.71-0.380.44124.9933241173017106914692302
flower pot7768-0.44-0.35-0.44-0.34-0.48-0.330.30108.7144271623251123015312333
shoe24314-0.280.20-0.250.26-0.19-0.080.1058.327939197218978811122889
jogger20090-0.09-0.15-0.06-0.12-0.08-0.13-0.0218.816632121234290127412195
dino19690-0.330.02-0.040.17-0.070.180.156.096057127274296531102815
horse13840-0.10-0.04-0.050.01-0.020.030.120.184446101202471838013940
spring76796-0.101.76-0.041.82-0.021.870.10-20.04235463023092124517784709
knot288000.01-0.310.01-0.300.00-0.29-0.09-0.0886322153629113511132028
Six objects: the original mesh, FCP decoded from the mesh and from 20k points, Poisson with true and with estimated normals, each with its volume error
The surfaces behind the volumes: the original mesh, the FCP descriptor decoded (from the mesh and from 20k points; the volume itself is computed from the atoms, not from this mesh), and Poisson's reconstruction with the true and with estimated normals; under each, the volume error against the exact volume (FCP at 128 layers, 2048 atoms).