All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Local Variables in SOPs

A common convention in SOPs is to have local variables. These are expressions like $CR or $PT that refer to the current point or primitive being processed. They allow the artist to easily vary the expressions behavior across the geometry.

There are two types of local variables you can add to a SOP. The first type are entirely custom local variables. These are often useful for generators. To implement these you need to override the SOP_Node::evalVariableValue methods and when instantiating your SOP with OP_Operator constructor (inside newSopOperator) include your static CH_LocalVariable list. An example of this approach is in SOP_Star.C and SOP_Star.h.

The second type of local variable is one operates per point, vertex, or primitive, and binds the standard attributes to local variables. This creates the $PT, $PRIM, $NPT, $CR, etc, variables that artists expect with SOPs that iterate over points or primitives. This also includes the bindings specified by the varmap attribute created by the Attrib Create SOP.

To bind the standard local variables you first inform Houdini of what precedence the variables should have. If you have both primitive and point Cd attributes, Houdini needs to know which one gets bound to $CR. This is done with the SOP_Node::setVariableOrder.

Next the geometry to use for the binding is passed to SOP_Node::setCurGdh. This can bind two different geometries using the input parameter. Input 0 would be bound to $CR and input 1 to $CR2. Which GU_DetailHandle to use affects the behavior. You can either use SOP_Node::myGdpHandle to use the same GU_Detail as your SOP's gdp pointer, or you can use one of your input's geometry fetched by SOP_Node::inputGeoHandle.

After your precedence is set and GU_Detail specified you need to actually bind the local variables. Until this point a reference to $CR would fail in an expression. This is done by calling SOP_Node::setupLocalVars.

During your cook you may now evaluate parameters (with OP_Node::evalInt or similar) and have the appropriate local variables present. However, you still need to specify what the currently processed point, vertex, and/or primitive is. This is done by writing to SOP_Node::myCurPtOff, SOP_Node::myCurVtxOff, SOP_Node::myCurVtxNum, and SOP_Node::myCurPrimOff. The point, primitive, or vertex offsets set must be from the same GU_Detail that you bound with the SOP_Node::setCurGdh.

It is important you do not leave dangling component references in the local variable code or it might be picked up in UI evaluation when the GU_Detail no longer exists. To guard against this, after completing your cook you should invoke SOP_Node::resetLocalVarRefs.

An example of how to bind the automatic variables can be found in SOP/SOP_Flatten.C and SOP/SOP_Flatten.h.