Skip to content

Commit 959d383

Browse files
committed
TSDF + ESDF + Occupancy + Decay + fast marching cubes
Add native CUDA kernels and Python wrappers for TSDF and ESDF reconstruction, occupancy mapping, dynamic-scene decay, and a fast sparse-compact marching-cubes variant. These features sit on top of the nanoVDB allocator-overrides change (parent PR) and share a common `PersistentTSDFState` + `BuildPointTruncationShell` substrate. Topology + state primitives src/fvdb/detail/ops/BuildPointTruncationShell.{cu,h} Shared primitive that turns `(points, base_grid, truncation_margin)` into the set of voxels within the truncation shell. Used by both depth and LiDAR TSDF integrators. src/fvdb/detail/ops/PersistentTSDFState.{cu,h} Grow-on-touch state holder for incremental integration: wraps a monotonically-growing live grid with fixed-shape tsdf / weights / optional feature sidecars and exposes a `grow` method that expands the grid + sidecars atomically while preserving values at already-live voxels. src/python/PersistentTSDFStateBinding.cpp Pybind11 binding for the above. Integrators src/fvdb/detail/ops/IntegrateTSDF.{cu,h} (modified) Depth TSDF integrator now uses `BuildPointTruncationShell` and `PersistentTSDFState`, and exposes a new N-frame batched entry point `integrateTSDFBatch` that grows the union grid one frame at a time and copy-forwards sidecars through the persistent-state object. Bit-identical to the per-frame loop (pinned by `test_integrate_tsdf_frames_matches_sequential`). src/fvdb/detail/ops/IntegrateTSDFFromPoints.{cu,h} Native LiDAR / range-sensor TSDF integrator: per-point thread HDDA-walks the union grid and `atomicAdd`s a running-sum into (sum_w_sdf, sum_w, sum_w_feat) accumulators within the truncation (and optionally free-space) band. Single-frame, with-features, and N-frames-batched variants. src/fvdb/detail/ops/IntegrateOccupancyFromPoints.{cu,h} LiDAR occupancy mapping with free-space carving and log-odds updates. Single-frame and N-frames-batched variants. Same ray-walk structure as the LiDAR TSDF integrator. ESDF src/fvdb/detail/ops/ComputeESDF.{cu,h} Euclidean Signed Distance Field from an integrated narrow-band TSDF. Composition pattern is `dilateGrid -> esdfSeed -> N sweeps of 26-N min-propagation`, reusing the topology-op primitives. src/fvdb/detail/ops/DirtyMaskFromSidecars.{cu,h} Per-voxel dirty-mask primitive that lets the incremental ESDF variant scope work to just the voxels whose sidecars changed. Marching cubes src/fvdb/detail/ops/MarchingCubesFast.{cu,h} Sparse-compact, packed-key marching cubes for fp32 / fp16 CUDA. `marchingCubes` now dispatches to this for eligible inputs and to `marchingCubesLegacy` (the previous default, kept verbatim) otherwise. src/fvdb/detail/ops/MarchingCubes.{cu,h} (modified) Routes through to the new fast path. Python surface fvdb/functional/_meshing.py Wrappers for the new N-frame + with-features + LiDAR variants of TSDF integration, occupancy mapping (single + frames), and ESDF (single + incremental). fvdb/functional/_topology.py Wrapper for `dirty_mask_from_sidecars_single`. fvdb/grid.py New methods on `Grid`: `decay_and_prune`, `integrate_tsdf_frames`, `integrate_tsdf_with_features`, `integrate_tsdf_from_points` (+ frames + with-features variants), `integrate_occupancy_from_points` (+ frames), `compute_esdf`, `compute_esdf_incremental`. `decay_and_prune` is implemented entirely in Python on top of existing fvdb sidecar + topology primitives. fvdb/functional/__init__.py Export the new functional names. src/python/Bindings.cpp, src/python/GridBatchOps.cpp Register the new C++ bindings. Tests tests/unit/test_persistent_tsdf_state.py tests/unit/test_compute_esdf.py tests/unit/test_dirty_mask.py tests/unit/test_integrate_occupancy.py tests/unit/test_decay_and_prune.py tests/unit/test_basic_ops.py (extended) Cover the new primitives, the persistent-state invariants (`grow` semantics, sidecar carry-forward), bit-identity of the batched-vs-sequential TSDF paths, atomic-noise tolerance for the LiDAR/occupancy variants, and fp16-vs-fp32 numerical agreement for the new marching-cubes fast path. Signed-off-by: Francis Williams <francis@fwilliams.info>
1 parent 4ec7afe commit 959d383

33 files changed

Lines changed: 9236 additions & 130 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ set(FVDB_BINDINGS_CPP_FILES
139139
src/python/GridBatchDataBinding.cpp
140140
src/python/GridBatchOps.cpp
141141
src/python/JaggedTensorBinding.cpp
142+
src/python/PersistentTSDFStateBinding.cpp
142143
src/python/ViewerBinding.cpp)
143144

144145
# Build library

fvdb/functional/__init__.py

Lines changed: 91 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -10,51 +10,6 @@
1010
- ``*_single`` -- operates on :class:`~fvdb.Grid` with plain ``torch.Tensor``.
1111
"""
1212

13-
# Grid constructors (batch)
14-
from ._constructors import (
15-
concatenate_grids,
16-
gridbatch_from_dense,
17-
gridbatch_from_dense_axis_aligned_bounds,
18-
gridbatch_from_ijk,
19-
gridbatch_from_mesh,
20-
gridbatch_from_nearest_voxels_to_points,
21-
gridbatch_from_points,
22-
gridbatch_from_zero_grids,
23-
gridbatch_from_zero_voxels,
24-
)
25-
26-
# isort: split
27-
28-
# Grid constructors (single)
29-
from ._constructors import (
30-
grid_from_dense,
31-
grid_from_dense_axis_aligned_bounds,
32-
grid_from_ijk,
33-
grid_from_mesh,
34-
grid_from_nearest_voxels_to_points,
35-
grid_from_points,
36-
grid_from_zero_voxels,
37-
)
38-
39-
# Dense <-> sparse I/O and grid-to-grid injection
40-
from ._dense import (
41-
inject_batch,
42-
inject_from_dense_cmajor_batch,
43-
inject_from_dense_cmajor_single,
44-
inject_from_dense_cminor_batch,
45-
inject_from_dense_cminor_single,
46-
inject_from_ijk_batch,
47-
inject_from_ijk_single,
48-
inject_single,
49-
inject_to_dense_cmajor_batch,
50-
inject_to_dense_cmajor_single,
51-
inject_to_dense_cminor_batch,
52-
inject_to_dense_cminor_single,
53-
)
54-
55-
# Grid indexing
56-
from ._indexing import index_grid_batch
57-
5813
# Interpolation / splatting
5914
from ._interpolation import (
6015
sample_bezier_batch,
@@ -73,24 +28,12 @@
7328
splat_trilinear_single,
7429
)
7530

76-
# I/O
77-
from ._io import (
78-
grid_names_in_nanovdb,
79-
load_nanovdb,
80-
load_nanovdb_single,
81-
read_nanovdb_metadata,
82-
save_nanovdb,
83-
save_nanovdb_single,
84-
)
85-
86-
# Meshing / TSDF
87-
from ._meshing import (
88-
integrate_tsdf_batch,
89-
integrate_tsdf_single,
90-
integrate_tsdf_with_features_batch,
91-
integrate_tsdf_with_features_single,
92-
marching_cubes_batch,
93-
marching_cubes_single,
31+
# Coordinate transforms
32+
from ._transforms import (
33+
voxel_to_world_batch,
34+
voxel_to_world_single,
35+
world_to_voxel_batch,
36+
world_to_voxel_single,
9437
)
9538

9639
# Pooling / refinement
@@ -103,6 +46,22 @@
10346
refine_single,
10447
)
10548

49+
# Dense <-> sparse I/O and grid-to-grid injection
50+
from ._dense import (
51+
inject_batch,
52+
inject_from_dense_cmajor_batch,
53+
inject_from_dense_cmajor_single,
54+
inject_from_dense_cminor_batch,
55+
inject_from_dense_cminor_single,
56+
inject_from_ijk_batch,
57+
inject_from_ijk_single,
58+
inject_single,
59+
inject_to_dense_cmajor_batch,
60+
inject_to_dense_cmajor_single,
61+
inject_to_dense_cminor_batch,
62+
inject_to_dense_cminor_single,
63+
)
64+
10665
# Spatial queries
10766
from ._query import (
10867
active_grid_coords_batch,
@@ -137,6 +96,27 @@
13796
voxels_along_rays_single,
13897
)
13998

99+
# Meshing / TSDF
100+
from ._meshing import (
101+
compute_esdf_incremental_single,
102+
compute_esdf_single,
103+
integrate_occupancy_from_points_frames_single,
104+
integrate_occupancy_from_points_single,
105+
integrate_tsdf_batch,
106+
integrate_tsdf_frames_single,
107+
integrate_tsdf_frames_with_features_single,
108+
integrate_tsdf_from_points_batch,
109+
integrate_tsdf_from_points_frames_single,
110+
integrate_tsdf_from_points_single,
111+
integrate_tsdf_from_points_with_features_batch,
112+
integrate_tsdf_from_points_with_features_single,
113+
integrate_tsdf_single,
114+
integrate_tsdf_with_features_batch,
115+
integrate_tsdf_with_features_single,
116+
marching_cubes_batch,
117+
marching_cubes_single,
118+
)
119+
140120
# Grid topology
141121
from ._topology import (
142122
clip_batch,
@@ -155,6 +135,7 @@
155135
conv_transpose_grid_single,
156136
dilated_grid_batch,
157137
dilated_grid_single,
138+
dirty_mask_from_sidecars_single,
158139
dual_grid_batch,
159140
dual_grid_single,
160141
edge_network_batch,
@@ -175,12 +156,41 @@
175156
refined_grid_single,
176157
)
177158

178-
# Coordinate transforms
179-
from ._transforms import (
180-
voxel_to_world_batch,
181-
voxel_to_world_single,
182-
world_to_voxel_batch,
183-
world_to_voxel_single,
159+
# Grid indexing
160+
from ._indexing import index_grid_batch
161+
162+
# Grid constructors (batch)
163+
from ._constructors import (
164+
concatenate_grids,
165+
gridbatch_from_dense,
166+
gridbatch_from_dense_axis_aligned_bounds,
167+
gridbatch_from_ijk,
168+
gridbatch_from_mesh,
169+
gridbatch_from_nearest_voxels_to_points,
170+
gridbatch_from_points,
171+
gridbatch_from_zero_grids,
172+
gridbatch_from_zero_voxels,
173+
)
174+
175+
# Grid constructors (single)
176+
from ._constructors import (
177+
grid_from_dense,
178+
grid_from_dense_axis_aligned_bounds,
179+
grid_from_ijk,
180+
grid_from_mesh,
181+
grid_from_nearest_voxels_to_points,
182+
grid_from_points,
183+
grid_from_zero_voxels,
184+
)
185+
186+
# I/O
187+
from ._io import (
188+
grid_names_in_nanovdb,
189+
load_nanovdb,
190+
load_nanovdb_single,
191+
read_nanovdb_metadata,
192+
save_nanovdb,
193+
save_nanovdb_single,
184194
)
185195

186196
__all__ = [
@@ -254,9 +264,20 @@
254264
"ray_implicit_intersection_batch",
255265
"ray_implicit_intersection_single",
256266
# Meshing
267+
"compute_esdf_incremental_single",
268+
"compute_esdf_single",
269+
"integrate_occupancy_from_points_frames_single",
270+
"integrate_occupancy_from_points_single",
257271
"marching_cubes_batch",
258272
"marching_cubes_single",
259273
"integrate_tsdf_batch",
274+
"integrate_tsdf_frames_single",
275+
"integrate_tsdf_frames_with_features_single",
276+
"integrate_tsdf_from_points_batch",
277+
"integrate_tsdf_from_points_frames_single",
278+
"integrate_tsdf_from_points_single",
279+
"integrate_tsdf_from_points_with_features_batch",
280+
"integrate_tsdf_from_points_with_features_single",
260281
"integrate_tsdf_single",
261282
"integrate_tsdf_with_features_batch",
262283
"integrate_tsdf_with_features_single",
@@ -277,6 +298,7 @@
277298
"dual_grid_single",
278299
"dilated_grid_batch",
279300
"dilated_grid_single",
301+
"dirty_mask_from_sidecars_single",
280302
"merged_grid_batch",
281303
"merged_grid_single",
282304
"pruned_grid_batch",

0 commit comments

Comments
 (0)