Debugging Your Compiled Custom Operator
Due to the configurations of the operator stack there are several resulting quirks:
• Transform Connection Configurations
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.
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.
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.
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.
The XSI core provides several tools for debugging:
• Muting Sections of the Stack
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.
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.
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.
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.
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". |