voxcity.importer.voxelize

Voxelize a mesh into a VoxCity voxel grid via column z-ray casting.

The mesh is first mapped into voxel-index space (i, j, k) using the caller’s placement transform (e.g. produced by build_placement_transform in transform.py). Occupancy is then determined per (i, j) column by casting a single vertical ray through the column center and pairing up the ray’s hit z-values under the even-odd rule:

sorted hits -> (z0, z1), (z2, z3), … fill voxel k in [floor(z0 + 0.5), floor(z1 + 0.5)) for each pair

A non-watertight mesh can produce an odd number of hits for some column; in that case we fall back to filling the single span from the first to the last hit and log a warning, since this is the best approximation available for a degenerate/open mesh.

Functions

voxelize_mesh(mesh, transform, grid_shape)

Voxelize mesh into occupied (i, j, k) voxel indices.

voxelize_mesh_meshlib(mesh, transform, grid_shape)

Voxelize mesh via the optional MeshLib SDF backend.

Module Contents

voxcity.importer.voxelize.voxelize_mesh(mesh, transform, grid_shape)[source]

Voxelize mesh into occupied (i, j, k) voxel indices.

Parameters:
  • mesh – a trimesh.Trimesh (or compatible) in original model coordinates. Not mutated.

  • transform – 4x4 numpy affine mapping model coordinates -> voxel-index space (i, j, k), as produced by build_placement_transform.

  • grid_shape(nx, ny, nz) voxel grid bounds used to clip results.

Returns:

(N, 3) numpy int64 array of unique, sorted occupied (i, j, k) voxel indices. Empty (0, 3) array if there are no candidate columns or no ray hits anywhere.

voxcity.importer.voxelize.voxelize_mesh_meshlib(mesh, transform, grid_shape)[source]

Voxelize mesh via the optional MeshLib SDF backend.

Warning

Untested / version-sensitive. This function is a best-effort transcription of the MeshLib-based voxelization approach from the design plan. The meshlib package is NOT installed in the environment this was implemented and tested in, so the exact API calls below (mr.meshFromFacesVerts, mr.MeshToVolumeSettings, vol.dims, vol.data.get(...)) could not be empirically verified against a real MeshLib distribution. MeshLib’s Python API is known to vary across versions. A maintainer who adds meshlib as an actual dependency MUST verify/adapt these calls against the installed version before relying on this path, and should run tests/importer/test_voxelize_meshlib.py (which is automatically skipped via pytest.importorskip("meshlib") when the package is absent) to confirm parity with voxelize_mesh().

Parameters:
  • mesh – a trimesh.Trimesh (or compatible) in original model coordinates. Not mutated.

  • transform – 4x4 numpy affine mapping model coordinates -> voxel-index space (i, j, k), as produced by build_placement_transform.

  • grid_shape(nx, ny, nz) voxel grid bounds used to clip results.

Returns:

(N, 3) numpy int64 array of unique, sorted occupied (i, j, k) voxel indices, matching the return contract of voxelize_mesh() exactly. Empty (0, 3) array if there are no occupied voxels.