Skip to content

NanoVDB: CUDA connected-components labeling for ValueOnIndex grids - #2261

Draft
sifakis wants to merge 2 commits into
AcademySoftwareFoundation:masterfrom
sifakis:connected-components
Draft

NanoVDB: CUDA connected-components labeling for ValueOnIndex grids#2261
sifakis wants to merge 2 commits into
AcademySoftwareFoundation:masterfrom
sifakis:connected-components

Conversation

@sifakis

@sifakis sifakis commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds nanovdb::tools::cuda::ConnectedComponents — a CUDA connected-components labeling of the
active voxels of a NanoVDB ValueOnIndex grid (6-connectivity). Two active voxels share a label
iff they are connected through a path of adjacent active voxels. The public
getVoxelLabelsAndCount() returns a per-active-voxel dense component id in [0, N) plus the
component count N.

Algorithm

Hierarchical, exploiting the 8³ leaf structure:

  • Per-leaf Shiloach–Vishkin union-find in shared memory (one block per leaf), producing each
    leaf-local component's voxel Mask<3> and six face bitmasks.
  • Cross-leaf edge detection by intersecting the touching face masks over each leaf's +X/+Y/+Z
    neighbours (each undirected boundary visited once).
  • Global lock-free union-find over the resulting component graph; the representative is each
    class's minimum slot, so the result is order-independent.

Also included

  • ex_connected_components_cuda — rasterizes an .obj to a narrow band (MeshToGrid), drops the
    √3/2-voxel surface shell (PruneGrid), then labels; a CPU union-find oracle independently
    verifies the GPU component count and per-voxel partition.
  • ConnectedComponentsMultiSphere unit test (analytic ground truth: N separated spheres → 2N
    shells; overlapping pair → 2).
  • A pendingchanges/ entry.

Notes

  • Depends only on existing NanoVDB CUDA tools (MeshToGrid, PruneGrid, voxelsToGrid) + CUB;
    no new third-party dependencies, no OpenVDB requirement for the example.
  • Branch is based on current master.

Opening as a draft to run CI and for review.

🤖 Generated with Claude Code

Add nanovdb::tools::cuda::ConnectedComponents, which labels the active voxels
of a NanoVDB ValueOnIndex grid by 6-connectivity: two active voxels share a
label iff they are connected through a path of adjacent active voxels. The
public getVoxelLabelsAndCount() returns a per-active-voxel dense component id
in [0,N) plus the component count N.

The implementation is hierarchical:
  - per-leaf Shiloach-Vishkin union-find in shared memory (one block per leaf),
    yielding each leaf-local component's voxel Mask<3> and six face bitmasks;
  - cross-leaf edge detection by intersecting touching face masks over +X/+Y/+Z
    neighbours;
  - a global lock-free union-find over the resulting component graph.

Also add the ex_connected_components_cuda example (rasterize an .obj to a
narrow band via MeshToGrid, drop the sqrt(3)/2-voxel surface shell via
PruneGrid, then label; a CPU union-find oracle verifies the result) and a
ConnectedComponentsMultiSphere unit test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Efty Sifakis <esifakis@nvidia.com>
…-voxels

Accept one or more .obj files (concatenated into a single mesh) and add a
--discard-surface-voxels switch: by default label the full narrow band (one
component per closed surface), or prune the sqrt(3)/2-voxel barrier shell first
when the switch is given. --voxel-size / --band-width replace the old positional args.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: JaeHyun Lee <jaehlee@nvidia.com>
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 24, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: JaeHyunLee94 / name: JaeHyun Lee (0bcbb46)
  • ✅ login: sifakis / name: Efty Sifakis (a2e1c20)

@swahtz swahtz assigned sifakis and unassigned sifakis Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants