With the rendering of implicit functions into the voxel field, we have created the ability to work with lattices and complex infills. There is one foundational way to build things in a voxel field missing, and that’s simply the ability to describe objects using a triangle mesh. This may be surprising to some, as mesh has become a bit of a dirty word, thanks to the messy geometries that many of the CAD packages output. But we will be generating meshes using a clean computational approach, and don’t have to be afraid of them. Because they are generated by algorithms, we can also adapt the resolution to what we need in the voxel field, and will not create triangle artifacts.
Of course rendering a mesh into our signed-distance voxel field, is simple. As long as we can find the distance to the surface of the mesh (in other words, the distance to the nearest triangle), and detect whether we are inside or not, we can transform the mesh into voxels.
Mesh geometry at very low resolution for illustrative purposes
That’s all we need to create geometry: implicits, and triangle meshes. And, as a function built on implicits: lattice structures. You can build sophisticated Computational Engineering Models (CEM), which output anything from advanced rocket engines or electric motors, based on these simple geometry generators, which always go back and render into the voxel field. The voxel field is a single source of truth. There is no ambiguity or potential instability; you can always look at it, at any step of the way and say: this is how it’s going to look like when I produce the object.
Intricate geometry created for a heat exchanger, based on a computational model that produces triangular meshes which are then transformed into voxels. Image source LEAP 71
There’s only a few more things that the geometry kernel needs, in order to be useful.
First of all, we need a way to combine multiple parts, using so-called Boolean functions. There are three functions: Add (adding all the voxels together), Subtract (cutting away the voxels that are present in another voxel field), and Intersect, which creates an intersection between two voxel fields, leaving only the voxels there, that are contained in both voxel fields.
Boolean operations: Boolean Intersect (left), Boolean Subtract (center), Boolean Add (right)
This allows us to, for example, cut a screw hole, when you have the shape of a screw, by subtracting the screw from the object that needs the hole. The good news is, Boolean operations are extremely simple in a voxel field, you just check the values for every voxel and its counterpart, and combine them according to one of the three functions (Add, Subtract, Intersect).
Why don’t we do it the way CAD does it, by combining things directly in the geometric formula, or through mesh math? Because Boolean operations using vectors are messy and complex. There are so many edge cases that vector-based Booleans frequently don’t work.
If you just wanted to pick one fundamental reason to use voxels as base geometry representation, it is that Boolean operations, some of the messiest and hardest operations in vector math, always work in voxels and never fail. This is exactly what we want when we build a geometry kernel that supports complex engineering models. Booleans allow you to fuse the individual base geometries of your object — they are fundamental operations of modeling computationally, and they must never fail. Period.
Implicit geometry (pipes made up of lattices which are merged using Boolean Add), which is then offset to produce the outer shell, which is then combined further using Boolean operations (subtracting the inside and adding support structures, etc.) Video courtesy of LEAP 71
There is one more extremely important base function left from our kernel that we need for Computational Engineering, and that’s offsetting.
A shell of a cube, created through offsetting and Boolean Subtract
Offsetting vector geometry is very hard, because of complex edge cases. Offsetting a voxel field is straightforward, because, again, you can just look at the voxels one by one, look at their neighborhood and perform a few operations. These operations are always local to that one voxel, and they never fail.
Let’ say you want to create a shell of an object: You first create the inside as a mesh, lattice or implicit. It can be a complex object, or a simple one. In voxel geometry complexity is irrelevant. Next you perform the offset operation, to create a larger version. Then you simply subtract the smaller object from the larger one, to hollow it. The result is your shell. Try doing something like this in CAD for even a moderately simple object!
3D-printed rocket injector head. Lots of offsetting (manifold wall for example), and of course many Boolean operations. Image curtesy of Aconity3D/LEAP 71
So there we go, this is basically all we need from a tiny, pico-size Computational Engineering kernel:
- a voxel field (narrow-band signed distance field, SDF)
- a way to render implicits (to create infills, lattices, and other formula-based volumetric objects)
- a way to render triangle meshes
- Boolean operations to combine voxel fields
- an offset operation that allows for negatively and positively offsetting the voxels
If we have a robust implementation of such a kernel, we can do everything else on a higher tier, and never ever worry about these base operations breaking our geometry. Unless there is an actual bug in our code, such a kernel will never fail, because the math behind it is trivial.
Last year, Josefine created arguably the most complex 3D printed object ever built, all possible because voxels never fail.