Debugging Your Compiled Custom Operator

What Could be Wrong?

Due to the configurations of the operator stack there are several resulting quirks:

Transform Connection Configurations

Multiple Constraint Blends

Local Transform Cycles

Operator on an Operator

Transform Connection Configurations

Due to the connection ordering on the global and local transforms, constraints are connected above fcurves, scripted operators and expressions. As a result, constraints override these animation sources. The mixer also overrides these sources both on the global and local transform.

Multiple Constraint Blends

Constraint blending is iterative: if one is moved all must be recalculated. Currently, the port structure is defined based on the stacking structure, so as one object constraint is modified only the other blended constraints above that one have the dirty notification propagated through. As a result, only the constraints that are connected above are recalculated if a constraint is dirty.

Local Transform Cycles

A Read/Write connection to a scripted operator or expression on the local transform will result in a cycle. This cycle will prove to be problematic if there are animated sources below this Read/Write connection (such as an fcurve). This cycle will be broken during evaluation and the resulting data may be incorrect, depending on the resolution point for the graph traversal.

Operator on an Operator

A Read/Write connection on an operator results in undesired behavior; however, a Write connection is fine. To work around this, use an intermediate file to communicate between the operators.

Tools for Debugging

The XSI core provides several tools for debugging:

Stack Order Manipulation

Muting Sections of the Stack

Debugging Graph Cycles

Stack Order Manipulation

You can move operators within a region using drag and drop in the Explorer or by using the MoveOperatorAfter and MoveOperatorBefore commands. However, XSI blocks the command if the movement would cause a cycle or if the requested connection position is prior to the generation of the data it is manipulating.

Muting Sections of the Stack

You can temporarily disable the evaluation of sub-graphs using the Disable from Here option on the right mouse button menu in the Explorer. Subsequent operators are added below the disabled point. This is especially useful for editing a surface or mesh after an envelope is applied, and ensuring that the new edits are included in the envelope.

Debugging Graph Cycles

The CycleChecking command determines if there is a cycle in a specified hierarchy and outputs to the script window the operators that are within the cycle, or are accessing the data within the cycle. Within each cycle traversed, the script window outputs a name of a operator as Cycle Breaking Point and outputs many operator names labeled as Cycle through operators.

Cycle Breaking Point

The Cycle Breaking Point operator is the graph location where the evaluation check is terminated. This is dependent on where the evaluation was initiated from and may slightly vary. This is the critical location for scene evaluation differences, odd results, or odd behavior users see with problematic cycles in their graph. The reason is that to avoid an infinite loop, the data used to honour this evaluation request is the evaluation up to that point in the operator stack.

Cycle through

The Cycle through operators are the contributors to the cycle and breaking one of these key dependencies will break the dependency cycle.

 

There are also other operators that will access the cycle and, during a scene evaluation, may end up with skewed cyclical results. However, these are not key contributors and so removing one of these operators does not break the cycle.

To fix a cycle users should look for, narrow down and remove key contributors within the cycle. These are the suggested approaches for this:

• First, narrow down a cycle within a hierarchy by isolating the breaking point and rerunning the CycleChecking command on its data owner or other hierarchies within its cycled operators. This allows you to get a handle on the depth and width of the cycle.

• Second, look for key contributors labeled within the cycle. You can start with the Cycle Breaking Point and trace down the output through the Cycle through operators until the same Cycle Breaking Point operator is found and labeled as a Cycle through operator. These are your contributors.

Then look through the contributors for familiar cycle creators such as "Expression", "ScriptedOp" or "kine.Constraints". A key contributor for a problematic cycle will not be of the forms below:

       kine.local.PoseCompensatorOp
       kine.global.ParentPoseCns_E
       kine.local.ParentPoseAndPoseCns_D
       kine.global.SkeletonCtrlOpProp

 

The operators labeled *_D's and *_E's are definers and enforcers of the "kine.Constraints".