Skip to content

Latest commit

 

History

History
158 lines (121 loc) · 3.48 KB

File metadata and controls

158 lines (121 loc) · 3.48 KB

Python API

The Python package is a thin pybind11 layer over the C++/CUDA core. CPU paths use NumPy arrays. CUDA hot paths use a CUDA-owned octree and CUDA Torch tensors.

Public Imports

import svo

svo.Octree
svo.Camera
svo.CameraIntrinsics
svo.CameraConvention
svo.BranchingMode
svo.VolumeRenderer
svo.render_volume
svo.refine_octree
svo.build_voxel_adjacency
svo.voxel_neighbor_loss
svo.sample_trilinear
svo.gather_payload
svo.cuda_enabled
svo.build_info

Build

tree = svo.Octree.from_voxels(coords, max_depth=8, device="cpu")

Optional payload remapping:

tree = svo.Octree.from_voxels(
    coords,
    max_depth=8,
    payload_indices=payload_indices,
)

Branching modes:

octree8 = svo.Octree.from_voxels(coords, max_depth=8, branching="octree8")
wide4 = svo.Octree.from_voxels(coords, max_depth=8, branching="wide4")

wide4 requires an even max_depth.

Adaptive Octree8 construction can use variable-depth leaf specs:

tree = svo.Octree.from_leaf_specs(
    coord_min,
    depths,
    payload_indices,
    max_depth=8,
)

tree.leaf_specs returns (coord_min, depths, payload_indices) in leaf order. For reconstruction experiments, initialize a coarse grid while preserving a deeper split budget:

tree = svo.Octree.full_grid(max_depth=8, leaf_depth=3)

leaf_depth=0 is only supported when max_depth=0 in the current descriptor model; use leaf_depth=1 or deeper for adaptive reconstruction.

Query

leaf_ids = tree.query(points)
payload_indices = tree.query(points, return_payload_indices=True)

Input shape is (N, 3) with dtype float32 or float64.

CUDA-Owned Tree

cuda_tree = tree.to("cuda")

CUDA query with Torch tensors:

points = torch.rand(100_000, 3, device="cuda")
ids = cuda_tree.query(points)

CUDA outputs stay on GPU for Torch input.

Raycast

hit_mask, leaf_ids, t, positions, depths = tree.raycast(origins, directions)

origins and directions can be shaped (N, 3) or (H, W, 3).

Payload Gather

features = torch.randn(tree.num_leaves, 16, device="cuda")
sampled = svo.gather_payload(features, leaf_ids_cuda, fill_value=0.0)

gather_payload supports NumPy and Torch tensors and uses -1 as miss.

Rendering

rgb, depth, opacity = svo.render_volume(
    tree,
    origins,
    directions,
    sigma,
    color,
    render_strategy="direct",
)

CPU rendering uses NumPy. CUDA autograd rendering uses Torch CUDA tensors with a CUDA-owned tree. render_strategy="intervals" is an experimental CUDA Torch path that saves compact interval buffers for backward reuse; CPU interval rendering is not implemented. render_strategy="auto" currently maps to "direct".

Adaptive Refinement

svo.refine_octree(...) performs a discrete rebuild-and-replace topology step:

result = svo.refine_octree(
    tree,
    sigma,
    color,
    split_threshold=1.0,
    prune_threshold=0.01,
    merge_threshold=0.05,
    growth_policy="ranked",
)
tree = result.tree
sigma = result.sigma
color = result.color

CUDA Torch payload remapping stays on CUDA when called with a CUDA-owned tree. The compact topology is rebuilt on CPU from leaf specs and reuploaded. V1 is experimental, Octree8-only, and requires one payload row per leaf. The default growth_policy="error" rejects rebuilds above max_leaf_growth. Use "ranked" to select the highest-scoring splits that fit the limit and defer the remaining candidates.