Using External SDF Libraries

Any library that evaluates a field at 3D points can feed isoext. One option is sdf by Michael Fogleman, a Python library for building complex SDFs, installed with:

pip install git+https://github.com/fogleman/sdf
import sdf
import isoext
import torch
from isoext import viewer

Example

This example recreates the weave demo from the sdf library.

# The following example is taken from https://github.com/fogleman/sdf/blob/main/examples/weave.py

f = sdf.rounded_box([3.2, 1, 0.25], 0.1).translate((1.5, 0, 0.0625))
f = f.bend_linear(sdf.X * 0.75, sdf.X * 2.25, sdf.Z * -0.1875, sdf.ease.in_out_quad)
f = f.circular_array(3, 0)

f = f.repeat((2.7, 5.4, 0), padding=1)
f |= f.translate((2.7 / 2, 2.7, 0))

f &= sdf.cylinder(10)
f |= (sdf.cylinder(12) - sdf.cylinder(10)) & sdf.slab(z0=-0.5, z1=0.5).k(0.25)

Sample the SDF on a grid. Since the sdf library operates on NumPy arrays, we convert between PyTorch and NumPy:

shape = [256, 256, 256]
aabb_min = [-13, -13, -13]
aabb_max = [13, 13, 13]
grid = isoext.UniformGrid(shape, aabb_min, aabb_max)
points = grid.get_points().cpu().numpy()
points = points.reshape(-1, 3)
values = f(points).reshape(shape)
values = torch.from_numpy(values).cuda()
grid.set_values(values)

Extract the mesh with marching cubes:

vertices, faces = isoext.marching_cubes(grid)

print(f"Vertices: {vertices.shape}")  # (N, 3) float32
print(f"Faces: {faces.shape}")  # (M, 3) uint32

viewer.embed(vertices, faces)
Vertices: torch.Size([110818, 3])
Faces: torch.Size([222000, 3])