1
0
Fork
You've already forked LabGeomVoxSplat
0
A library of tools and utilities for Geometry, Voxels, and Splats.
  • C++ 71.2%
  • C 15%
  • Objective-C++ 4.3%
  • Metal 4%
  • CMake 3.1%
  • Other 2.4%
2026年06月08日 00:39:14 -07:00
docs Make the library dynamic and relocatable 2026年06月06日 12:13:37 -07:00
examples Finish texture resampling 2026年05月20日 23:59:43 -07:00
geodesic Add Geodesics 2026年06月01日 12:49:12 -07:00
include/ovoxel Include depth and pick renders for splat 2026年06月08日 00:39:14 -07:00
src Include depth and pick renders for splat 2026年06月08日 00:39:14 -07:00
tests Add USD conversion utilities 2026年05月22日 18:39:16 -07:00
third_party Finish texture resampling 2026年05月20日 23:59:43 -07:00
tools Fix CMakeLists 2026年06月01日 20:53:10 -07:00
.gitignore Add Geodesics 2026年06月01日 12:49:12 -07:00
CMakeLists.txt Make the library dynamic and relocatable 2026年06月06日 12:13:37 -07:00
README.md Add Geodesics 2026年06月01日 12:49:12 -07:00

LabGeomVoxSplat

A standalone C++ library for sparse voxel octree (SVO) construction, ray tracing, and mesh LOD generation.

Combines a QEF-based mesh voxelizer with the Laine-Karras SVO ray traversal algorithm for fast GPU rendering on Metal (macOS/Silicon) and CUDA (Linux/Windows). This implementation follows the ovoxel algorithm from Trellis (see Provenance below).

Features

  • Mesh → Voxels: Quadratic Error Function (QEF) voxelization with surface-preserving dual vertices
  • SVO Ray Tracing: Stackless octree traversal (Laine & Karras 2010) on CPU, Metal, and CUDA
  • Mesh Reconstruction: Dual contouring with coplanarity-aware quad splitting
  • UV Unwrapping: Automatic atlas generation via xatlas
  • Texture Baking: Rasterize surface colors onto UV atlas with dilation padding
  • Material System: Extensible channel-based descriptors from "compact" (4 bytes) to "bananas" (32 bytes PBR)
  • Surface Sampling: Pluggable interface for flat color, texture, MaterialX, or Gaussian splat sources
  • LOD Pipeline: Voxelize at any resolution → reconstruct → unwrap → bake → export oct or ply

Geodesics

The optional geodesic subsystem (-DOVOXEL_BUILD_GEODESIC=ON, on by default) adds geodesic and planetary geometry, consolidated from the AridPlanet teaching technology. See geodesic/.

  • goldberg: Geodesic-polyhedron sphere grids (icosahedral / Goldberg hex tessellations) with cell addressing, hex-frustum culling, and radial layers.
  • Frames & precision: Floating-origin world frames and sphere-of-influence handover for planet-scale coordinates without precision loss.
  • Spatial acceleration: Morton-key hex trees and Barnes–Hut for large-N queries; on-sphere pathfinding and nearest-neighbor search (gflann).
  • Physics: Symplectic integration, Lorentz transforms, causality, and temporal epochs.
  • orbital_mechanics: Keplerian orbits, bodies, forces, phases, and state propagation.
  • planet_building: Procedural planet generation (C99).
  • topomancy: Graph-topology toolkit (C99).
  • OpenSubdiv bridge (optional, -DGEODESIC_OPENSUBDIV_BRIDGE=ON): limit-surface evaluation over the grid.

Quick Start

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .

Convert a mesh to SVO and render:

./ovoxel_convert -i model.ply -o model.oct -r 256
./ovoxel_viewer model.oct

Generate an LOD mesh with baked texture:

./ovoxel_convert -i model.ply -m lod.ply -r 128 --bake lod_texture.png

Build Options

Option Default Description
OVOXEL_BUILD_TOOLS ON Build ovoxel_convert CLI
OVOXEL_BUILD_TESTS ON Build test suite
OVOXEL_BUILD_EXAMPLES OFF Build viewer (requires LabGL)
OVOXEL_BACKEND auto GPU backend: metal or cuda

Library API

#include <ovoxel/ovoxel.h>
// Load a mesh
ovoxel::Mesh mesh = ovoxel::load_ply("input.ply");
// Voxelize
ovoxel::ConvertParams params;
params.voxel_size = {0.01f, 0.01f, 0.01f};
params.grid_min = {0, 0, 0};
params.grid_max = {256, 256, 256};
ovoxel::FlatColorSampler sampler(mesh.face_colors.data());
ovoxel::VoxelizeResult voxels = ovoxel::mesh_to_voxels(
 vertices, num_verts, faces, num_faces, params, &sampler);
// Build SVO
ovoxel::VoxelGrid grid(256);
grid.populate(voxels, params);
ovoxel::SVO svo(grid);
grid.transfer_materials(svo);
svo.save("output.oct");
// Reconstruct mesh
ovoxel::ReconstructResult recon = ovoxel::voxels_to_mesh(voxels, params);
// UV unwrap + bake
ovoxel::UnwrapResult unwrapped = ovoxel::unwrap_mesh(recon, 1024);
ovoxel::BakeResult texture = ovoxel::bake_texture(unwrapped, vertex_colors, 1024);
ovoxel::dilate_texture(texture, 16);
ovoxel::write_texture_png("texture.png", texture);

Material Formats

The SVO leaf payload uses a descriptor-based channel system. Predefined presets:

Preset Stride Channels Use Case
compact() 0 (inline) 32-bit packed normal+shade CAD, 3D printing, maximum speed
colored() 8 bytes RGBA8 color + octahedral normal General rendering
pbr() 16 bytes Color + normal + roughness + metallic Production PBR
bananas() 32 bytes Full float precision everything Maximum quality

The traversal kernel reads only the compact node array. Material data lives in a separate attribute buffer — one extra read on leaf hit, zero cost during traversal.

Surface Samplers

Pluggable color sources for voxelization:

// Per-face constant color (fastest)
ovoxel::FlatColorSampler flat(face_colors_ptr);
// UV-mapped texture lookup
ovoxel::TextureSampler tex;
tex.uvs = uv_data;
tex.faces = face_indices;
tex.pixels = rgba8_texture;
tex.tex_w = 1024; tex.tex_h = 1024;
// Pass to voxelizer
ovoxel::mesh_to_voxels(..., &tex);

Future samplers (interface defined, implementation pending):

  • MaterialXSampler — evaluate shader graphs at surface points
  • SplatSampler — gather from Gaussian splat fields
  • CompositeSampler — layer/blend multiple sources

Architecture

include/ovoxel/
├── ovoxel.h umbrella header
├── types.h linalg.h aliases, bit utilities
├── material.h channel descriptors, oct-normal encoding
├── svo.h SVO node format, build, traverse, serialize
├── sampler.h SurfaceSampler interface
├── qef.h mesh-to-voxel API
├── convert.h full pipeline: load, reconstruct, unwrap, bake
├── serialize.h Morton/Hilbert space-filling curves
└── render.h Metal/CUDA renderer interface
src/
├── svo.cpp SVO build + LZ4 IO + CPU ray traversal
├── qef.cpp QEF accumulation + constrained solve
├── sampler.cpp TextureSampler implementation
├── convert.cpp PLY loader, VoxelGrid, reconstruction, pipeline
├── unwrap.cpp xatlas integration
├── bake.cpp texture rasterization + dilation + PNG export
├── serialize.cpp Morton/Hilbert encode/decode
├── metal/ Metal compute traversal kernel + host dispatch
└── cuda/ CUDA compute traversal kernel

Dependencies

  • linalg.h — linear algebra (bundled)
  • LZ4 — SVO compression (bundled)
  • xatlas — UV unwrapping (bundled)
  • stb_image_write — PNG export (bundled)
  • LabGL — viewer only (optional, for OVOXEL_BUILD_EXAMPLES)

No external dependencies for the core library. C++17, CMake 3.21+.

Acknowledgements:

Voxelation algorithm and reconstruction follows TRELLIS' QEF-based voxelation, but differs significantly in details:

  • TRELLIS/o-voxel — QEF voxelization (ported from Eigen/CUDA/Python to linalg.h/C++)

Bitterli's sparse-voxel-octrees teaches how to create and raycast very, very fast SVO structures. His data structures are used instead of TRELLIS'. The representation has been extensively modified to allow for material properties in voxels.

Gorsten & Diakopolous' linalg is used for math instead of Eigen:

  • linalg.h — single-header linear algebra

XAtlas is used for batteries-included texture atlasing in order to resample textures for meshes reconstructed from voxel data:

  • xatlas — automatic UV atlas generation

License

MIT

Copyright (c) 2026 Nick Porcino