Implicit Representations & Signed Distances in the Metafold API
Unlike discrete, tessellated surface representations—e.g. triangle meshes, the Metafold geometry kernel represents shapes implicitly through shape functions. These implicit shape functions give us the signed distance to the surface (or zero level set) of the shape from a given point position in . By querying the surface distance at a sufficient number of varied point positions (often referred to as “sampling the shape”), we are able to build an approximate picture of the implicit shape. The detail of this “picture” depends on the number of points we use to sample the shape, and the strategy we use to vary the point positions. The higher the shape’s complexity, the more points are needed to capture the surface in sufficient detail, and vice versa.
Sampling implicit shapes using a 3D grid of uniformly distributed points is a naive, yet effective strategy to capture detail without knowing more about the shape upfront. As implicit shapes have no bounding box per se, choosing an appropriate position and size for the uniform grid can be challenging. If the shape is as simple as an ellipsoid, then grid placement is trivial provided you know the ellipsoid center and size. If the shape is a lattice however, our implementation repeats the lattice unit cell infinitely in all directions in , so there is no obvious grid placement!
It’s a little like shining a torch into a dark room full of objects, without first scanning the room once with the light, it’s hard to know where to focus the torch light to get more detail on the object you care about.
Things get more complex when the shape function is composed of multiple shapes, and even more tricky when coordinate transforms are involved. We therefore leave grid placement up to the designer of the shape function, who is the most informed to make this decision.
We could store results using a sparse data structure, but this turns out to have little-to-no (or worse) space savings for highly complex microstructures, e.g. a design space filled with a dense lattice, which are a key benefit of using implicit shapes. The current binary output format is also incredibly fast and simple to read and write, allowing our customers to get going quickly without any special decoders needed.
We could do better, but we could also do much worse in terms of storage.
Tip: You can use the export_vdb
job to output sparse level set data in OpenVDB format if desired.
With signed distances sampled onto a grid (referred to as a volume), we can render the shape by further sampling the grid values. Depending on how far apart the grid points are, some interpolation of grid values may be required to approximate distances between the available points. We can also use this method to sample volumes in other shape functions (TODO: Link). Interpolating grid values is computationally cheap and fast, this is particularly convenient for us as it allows us to cache the results of comparatively slow and expensive shape functions, e.g. sampling a triangle mesh (TODO: Link), and use the cached volume in subsequent shape functions—trading precision for processing speed.