Bounding volumes straight from the descriptor

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

Package v5.31 (commit db3e6ceb), mesh encodes, the 12 objects of the collision section. The axis-aligned box (AABB), an oriented box (OBB) and the smallest enclosing sphere come from points that can be vertices of the descriptor's convex hull, found without a grid, a mesh or a hull surface: each ring's Fourier coefficients straight from its part's atoms (the part's height basis times its atoms; each part's end rings held to its edges), then one numba kernel, the rings in parallel: a ring's 128 samples, its 2D hull and its support point in 64 directions; per direction the rings on the upper envelope of (height, support) are kept (0.4k–4.8k points at 128 layers). The AABB is their minimum and maximum; the OBB is the smallest of six boxes that keep one axis of the world frame or of the descriptor's own frame and turn the other two to the minimum-area rectangle of the projected hull (rotating calipers, the six in parallel); the sphere is the exact smallest ball of the points (randomized incremental). References from the source mesh: its vertex AABB; for the OBB the smaller of trimesh's minimum-volume box and Open3D's minimal box (each is smaller than the other on some objects: Open3D's by up to 2.9 % on the shoe); the exact smallest ball (qhull, then the same ball algorithm). "Outside" is the farthest source-mesh vertex outside FCP's bound, in % of the diagonal. Times: CPU i5-10400F (numba on 12 threads for FCP; the references as the libraries run), medians over the objects; FCP's times are from an idle machine (load average 0.3), the accuracy columns from a later run of the same code.

layersatomsAABB volume / mesh'sAABB: outside, max % OBB volume / smallest reference OBBOBB: outside, max %sphere radius / exactsphere: outside, max % AABB + sphere, msall three, ms (range)
12820480.978–1.0190.520.977–1.0360.500.999–1.0070.150.981.41 (0.91–4.10)
12861440.979–1.0180.520.977–1.0350.500.999–1.0070.121.001.48 (0.92–3.90)
25661440.977–1.0150.530.977–1.0390.470.994–1.0030.341.782.44 (1.40–7.30)

Against the standard routes (128 layers, 2048 atoms; the standard routes work on the source mesh's vertices, 2.3k–38k; ms, median and range over the 12 objects):

boundmethodtime, mssize
AABBFCP (with the sphere; the pass is shared)0.98 (0.66–3.33)0.978–1.019 of the mesh's, approximate
Open3D AxisAlignedBoundingBox, mesh vertices0.01 (0.01–0.08)exact
NumPy min / max, mesh vertices0.34 (0.11–1.84)exact
OBBFCP (all three bounds)1.41 (0.91–4.10)0.977–1.036 of the smallest reference
trimesh oriented_bounds (minimum volume)79.71 (20.41–150.91)1.000–1.030
Open3D create_from_points_minimal339.02 (29.05–3844.13)1.000–1.001
Open3D create_from_points (principal axes)3.53 (1.69–16.99)1.000–1.498 (median 1.183)
sphereFCP (with the AABB)0.98 (0.66–3.33)radius 0.999–1.007 of the exact
exact: qhull, then the smallest ball of its vertices3.94 (2.13–18.17)1 (the reference)
trimesh minimum_nsphere19.34 (3.38–959.53)1.0000–1.0040 (larger than exact by over 1e-5 on 4 objects)

Verdict (128 layers, 2048 atoms; speed against the fastest standard route giving the same kind of bound, per object; accuracy given up against the reference):

boundFCP speed vs the best standard routesize vs the reference farthest source vertex outside FCP's bounduse FCP?
AABB29–201× slower (Open3D, 0.015 ms) -2.2 to +1.9 % volumeup to 0.52 % of the diagonal (median 0.11 %) no, when the mesh or the points are at hand: theirs is exact and faster
OBB18–86× faster (median 52×) than the faster minimal box; 1.5–4.3× than Open3D's principal-axes box -2.3 to +3.6 % volume (principal-axes box: up to +50 %) up to 0.50 % (median 0.14 %) yes: a near-minimal box, faster than a principal-axes box
sphere2.2–6.7× faster (median 3.8×) than the exact route -0.06 to +0.7 % radiusup to 0.15 % (median 0.02 %) yes, if a radius within 1 % will do
all three20–89× faster (median 55×): 1.4 ms against 83 ms as aboveup to 0.52 %yes

The accuracy given up: 2.2 % in the AABB's volume, 3.6 % in the OBB's, 0.7 % in the sphere's radius (worst objects). Most of it is the encoding's own error (on the source mesh the same ball algorithm gives the exact ball); the OBB adds its search over six frames: on the shoe its box is 3.6 % larger than Open3D's minimal box, which there is 2.9 % smaller than trimesh's. None of the descriptor's bounds encloses the object for certain; inflate them by about 0.5 % of the diagonal where enclosure must hold. The standard routes run as well on a point cloud's points: the descriptor's advantage is where the descriptor is what one holds (stored, sent, or encoded for its other queries), and where a near-minimal OBB is wanted quickly.

Six objects with their AABB, OBB and smallest sphere: from the descriptor (orange) and from the mesh (dashed black)
The source mesh with the bound from the descriptor (orange, 128 layers, 2048 atoms) and the reference from the mesh (dashed black: its AABB, trimesh's minimum-volume OBB, the exact smallest ball). Where the two coincide only the orange is visible. The OBBs of the dog bowl, the shoe and the knot are turned differently about the vertical axis but hold nearly the same volume (bowl dog 1.010, shoe 1.036, knot 0.995 of the reference volume): a round bowl's box is the same in any turn, so the smallest one is not unique.