B.4 Adding New Object Implementations
We will briefly review the overall process that pbrt uses to create instances of implementations of the various abstract interface classes like Shapes, Cameras, Integrators, etc., at run time. We will focus on the details for the Shape class, since the other types are handled similarly.
When the API needs to create a shape, it has the string name of the shape and the ParamSet that represents the corresponding information in the input file. These need to be used together to create a specific instance of the named shape. MakeShapes() has a series of if tests to determine which shape creation function to call; the one for Spheres, CreateSphereShape(), is shown here:
The appropriate named parameter values are extracted from the parameter list, sensible defaults are used for ones not present, and the appropriate values are passed to the Sphere constructor. As another alternative, we could have written the Sphere constructor to just take a ParamSet as a parameter and extracted the parameters there. We followed this approach instead in order to make it easier to create spheres for other uses without having to create a full ParamSet to specify the parameters to it.
Thus, adding a new implementation to pbrt requires adding the new source files to the build process so they are compiled and linked to the executable, modifying the appropriate creation function (MakeShapes(), MakeLight(), etc.) in core/api.cpp to look for the new type’s name and call its creation function, in addition to implementing the creation function (like CreateSphereShape()) that extracts parameters and calls the object’s constructor, returning a new instance of the object.