User guide

197
Use the cook() function to determine what should happen for given locations, and delegate the logic for those
locations to other static functions. This makes code more readable.
If using CEL, check if the CEL statement can match any child locations. If not, stop child traversal. Doing this results
in increased performance by not running this Op on any of the child locations.
If you wish to pass data to child locations, the best way to do this is through their OpArgs. The
interface.getOpArg() function gives you all args as a GroupAttr that can be selectively updated using a
GroupBuilder.
If you need to pass more complex data down to children that aren't representable as attributes, then you can
additionally use the private data pointer.
If you would like to using static caching for data, the AttributeKeyedCache is a thread-safe cache included in the
distribution.
For complex Ops, you may find a mix of static caching and blind data is needed to get the right balance between
cache key count and cost of access. The AlembicOp illustrates this kind of split approach.
The more nodes in the node graph and Op slots in the Op tree, the greater the overhead of evaluating the scene. If,
for example, you have a layout format, consider creating an Op that can read and traverse this format, substituting
suitable Ops at child locations for cache reading, rather than using a SuperTool to configure many instances of
smaller/leaf ops in the node graph.
Many sequential Ops can greatly reduce cache re-usability and increase re-cooking compared to merged
independent branches. Consider omitting inputs from ‘generator’ ops to encourage wider trees.
Use the NodeTypeBuilder to register custom nodes for your Ops.
Use CamelCase for OpArg names, with the first letter lowercase, for exmaple, myOpArg”.
Use an underscore to prefix the name of any OpArg that is not intended as a top-level public’ option, for example,
“_internalArg”.
24 OP API | OP BEST PRACTICES CHEAT SHEET