Geometry Tutorial¶
See also: the concise type catalog in Geometry Types.
This tutorial demonstrates how to create basic geometry types used by WarpConvNet.
Creating Points¶
import torch
from warpconvnet.geometry.types.points import Points
# coordinates and features for two batches.
N1, N2 = 1000, 500 # batch size 2, each batch has N1, N2 points
coords = [torch.rand(N1, 3), torch.rand(N2, 3)]
features = [torch.rand(N1, 7), torch.rand(N2, 7)]
points = Points(coords, features)
print(points.batch_size)
You can also build Points from concatenated tensors and offsets:
# same N1, N2 as above
coords_cat = torch.cat([coords[0], coords[1]], dim=0) # (N1+N2, 3)
feats_cat = torch.cat([features[0], features[1]], dim=0) # (N1+N2, 7)
offsets = torch.tensor([0, N1, N1 + N2], dtype=torch.int32)
points_cat = Points(coords_cat, feats_cat, offsets)
Creating Voxels¶
from warpconvnet.geometry.types.voxels import Voxels
voxel_size = 0.01
N1, N2, C = 1000, 500, 32 # batch size 2, each batch has N1, N2 voxels, C channels
voxel_coords = [
(torch.rand(N1, 3) / voxel_size).int(),
(torch.rand(N2, 3) / voxel_size).int(),
]
voxel_feats = [torch.rand(N1, C), torch.rand(N2, C)]
voxels = Voxels(voxel_coords, voxel_feats)
print(voxels.batch_size)
Or, using concatenation plus offsets (integer coordinates expected):
coords_cat = torch.cat(voxel_coords, dim=0) # (N1+N2, 3) int
feats_cat = torch.cat(voxel_feats, dim=0) # (N1+N2, C)
offsets = torch.tensor([0, N1, N1 + N2], dtype=torch.int32)
voxels_cat = Voxels(coords_cat, feats_cat, offsets)
Conversions¶
Conversions between geometry types live in
warpconvnet.geometry.types.conversion and follow a <src>_to_<dst> naming
convention, each returning a geometry type.
Downsample Points to Voxels (also available as the points.to_voxels(...)
method):
from warpconvnet.geometry.types.conversion.to_voxels import points_to_voxels
voxels = points_to_voxels(points, voxel_size=0.02, reduction="mean")
Rasterize Points or Voxels onto a dense Grid. grid_shape is (H, W, D);
point features are aggregated into cells by a neighbor search (radius, knn,
or voxel):
from warpconvnet.geometry.types.conversion.to_grid import (
points_to_grid,
voxels_to_grid,
)
grid = points_to_grid(points, grid_shape=(64, 64, 64), search_type="radius")
grid = voxels_to_grid(voxels, grid_shape=(64, 64, 64))
Build a factorized multi-plane FactorGrid (one grid per memory format):
from warpconvnet.geometry.types.conversion.to_factor_grid import points_to_factor_grid
factor_grid = points_to_factor_grid(
points,
grid_shapes=[(64, 64, 1), (64, 1, 64), (1, 64, 64)],
memory_formats=["b_zc_x_y", "b_xc_y_z", "b_yc_x_z"],
)
Padded-batch helpers used by attention (
GeometryToPaddedBatch,PaddedBatchToGeometry) are not type conversions — they produce dense padded tensors, not a geometry. See the attention modules inwarpconvnet.nn.modules.attention.