Using Sparc3D's paper as a reference.
I was excited about the results of Sparc3D
Part of their paper details a fast method to obtain Sign distance fields (SDF) on a regular grid of size 1024 x 1024 x 1024 voxels, denoted SDF-1024$^3$. They report under 30s so this was my main target. Later I will analyse the additional components they report.
SDF-1024$^3$ in under
I used NVIDIA’s Kaolin libraryscipy.ndimage.label
which despite being CPU bound is VERY performant, and I was very happy with this part! Finally, I had to make modifications to FlexiCubes
as the original implementation calculates the surface sparsely, but relies on evaluating a dense (D,H,W) tensor of floating point SDFs for querying cube neighbours. While fast, it was not memory efficient and I found myself constantly getting OutOfMemory exceptions. This was the painful part.
Insight: why calculate the UDF-1024$^3$ for all 1025$^3$ grid points when almost all are discarded in Marching cubes.\
The algorithm calculates a coarse UDF (at resolution[0]
), then refines only the voxels which have a vertex with a distance at or below the threshold. This can then be repeated an abitrary number of times as long as the next resolution is a multiple of the previous.
args: resolutions [list<int>]
res = Pop(resolutions)
grid = SparseGrid(res, mask=None)
udf = ComputeUDF(grid)
threshold = udf <= sqrt(3) / res
FOR res in resolutions:
mask = udf < threshold
grid = SparseGrid(res, mask=mask)
udf = ComputeUDF(grid)
threshold = udf <= sqrt(3) / res
return udf