and instanced multiple times. Objects are also given
priorities, which allow CSG-like operations and control the treatment of overlapping regions. (If two or more objects cover
the same voxel, that voxel is assigned to the object with a
higher priority value.)
4. 2. Surface phase
In the first stage of the pipeline, the surface of the input
objects is discretized via tessellation to match the desired
output resolution. Tessellation generates micropolygon
primitives—the common surface representation throughout the pipeline—with user-defined attributes interpolated
from the input object.
Next, the surface stage of the user’s fablet program is
evaluated over these micropolygons. The surface fablet
stage is conceptually similar to a vertex shader: it evaluates
point-wise, given a vertex position and interpolated attributes as input, and performs arbitrary computation, such
as sampling from textures, to produce a (potentially displaced) output position and some number of output attributes. Procedural displacement provides a mechanism for
describing surface microgeometry in arbitrary detail that
would be infeasible to explicitly model in the input objects.
4. 3. Volume phase
The next stage discretizes the volume enclosed by objects
via voxelization. It is critical to use consistent, crack-free
rules for voxelization. We follow the rules of 26-separating
voxelization. 7 Consider a multipart assembly where parts are
printed separately. To ensure the assembly fits together, each
voxel overlapping the shared geometry along part boundaries must be consistently assigned to exactly one part.
After voxelization, the volume stage of the fablet is evaluated
over each voxel. This stage receives interpolated attributes
as input and performs arbitrary computation to produce a
floating point-valued mixture of the available printing mate-
rials. In addition to standard arithmetic, control flow, and
texture sampling functionality, the volume fablet stage also
allows querying the distance to the nearest point on the sur-
face, and any surface attributes at that point. When defining
materials volumetrically, it is often useful to be able to deter-
mine the relative position of a given voxel with respect to the
object boundary. 12 Consider the scenario where we would
like to print a textured object. Unlike rendering, we cannot
assign colors simply to the infinitesimal outermost layer of
the surface; rather, the printer needs to deposit a certain vol-
ume of layered material in order to achieve a particular color,
reflectance, and scattering behavior.
Finally, the dither stage performs volumetric quantization and discretization of material quantities to match the
capability of the target printer before handing the result to a
specific printer driver. Our initial implementation included
a streaming raster slice backend that is appropriate for a
drop-on-demand 3D printers and a legacy backend that
generates per-material STL meshes for use with traditional
commercial printer software.
4. 4. Fablets and OpenFL
Fablets are written in OpenFL, a C-like programming language similar to shader languages such as HLSL. 5 Unlike
most shader languages, OpenFL describes both surface
and volume functionality together as methods on a single
fablet object. Uniform parameters, such as texture and
material IDs, are also declared in the object. OpenFL includes
standard functions for common math, texturing, and other
routines. Unique to our domain, it also includes functions to
query the distance to the nearest point on the surface, as well
as any interpolated mesh attributes at that point.
To understand how fablets can be used to define proce-
dural surface detail and continuous volumetric material
variation, consider the example as shown in Figure 2. One
side is flat and texture mapped with the foreground image,
whereas the other side is displaced according to the desired
brightness of the shadow background image. This object is
defined by the following fablet:
Material and texture handles are declared as attributes
of the fablet, along with parameters for the dimensions of
the rectangular border, maximum thickness, and the depth
into the volume to which the texture should be deposited on
the front face.
The surface phase takes as arguments the position, normal, and texture coordinates defined over the mesh, as well
as a per-vertex flag indicating the face of the cube (front,
back, or side). If the currently processed vertex is on the back
fab world tessellate surface fablet voxelize volume fablet output dither
surface phase volume phase
Figure 1. The OpenFab pipeline defines a programming model for synthesizing continuous volumetric material mixtures for 3D printing.
As an input (blue), it takes a scene graph describing a set of object boundary representations, textures, printer materials, and user-programmable fablets—similar to shaders. From this input, it generates a discrete volumetric material definition that is device specific.
Some stages are fixed function (gray), controlled by high-level parameters and printer characteristics, although fablet stages (red) are
programmable by the user.