HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Primitive Patterns

Being able to efficiently specify the target primitives for any LOP node's operation is central to what LOPs can do. Being able to use information from the stage to control this targeting is the basis for much of the procedural nature of LOPs. As such, Houdini has a very powerful and flexible primitive pattern mechanism. See https://www.sidefx.com/docs/houdini/solaris/pattern.html for information about using these patterns.

Most of the interesting capabilities of Houdini's primitive patterns is provided by "auto-collections". These are referred to in patterns using this syntax:

%name(arg1, arg2, ..., kwarg1=value1, kwargs2=value2)

or

%name:arg

These auto-collections can be thought of as functions that can be run on any primitive on the stage and return a true/false value as to whether the primitive satisfies the condition defined by the auto-collection. It is possible to use the HDK to write custom auto-collections that extend the capabilities of Houdini's primitive patterns. The simplest possible auto-collection which simply accepts all primitives is provided as a sample in $HFS/toolkit/samples/LOP. Many more complex implementations (the ones that ship with Houdini) can be found in the Houdini USD Bridge github repository (https://github.com/sideeffects/HoudiniUsdBridge) in the file src/houdini/lib/H_USD/HUSD/XUSD_AutoCollection.C.

On important consideration is that subclasses of XUSD_SimpleAutoCollection and XUSD_RandomAccessAutoCollection will be queried from multiple threads simultaneously, so thread local storage should be used for any data cached between queries. The difference between a random access and simple auto-collection is that simple traversals will always traverse the whole stage to generate a set of results, and queries against this auto collection then just check for membership in the result set. Random access collections are only ever queried about primitives that match the other conditions in the pattern.

Direct subclasses of XUSD_AutoCollection override the virtual XUSD_AutoCollection::matchPrimtives() method, and can populate the result set using any approach. But it is important to make these evaluations as efficient as possible. If a significant number of prims need to be tested, consider using multithreaded algorithms such as those provided by XUSD_FindPrimsTask.

For all styles of auto-collection it is very important to prune branches whenever possible, as the fastest test is one that is never run. Setting the prune_branch output parameter to true avoids the testing of any descendants of the current primitive.