v3.5
Checks the Graph For Operator Evaluation Cycles. An evaluation cycle is a looped graph dependency where
an operation is dependent on itself.
This function 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 operators 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 evalution differences/odd results/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 upto that point in the connection stack. So in fact the result is not a re-evaluation of itself.
The 'Cycle through' operators are the contributers to the cycle and breaking one of these key dependencies
will break the dependency cycle. Note: there are also other operators that will access the cycle and during
a scene evaluation may end up with skewed cyclical results, but are not key contributers
and as such removing one of these operators will not break the cycle.
To fix a cycle users should look for, narrow down and remove key contributers within the cycle.
There are suggested approches for this. First to narrow down a cycle within a hierarchy isolating
the breaking point and rerunning the cycle checking on it's data owner or other hierarchy's within it's
cycled operators to get a handle on the depth and width of the cycle. Second, look for key contributers
labeled within the cycle. To do this 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 labled as a 'Cycle through' operator. These are your contributers. Then look through
the contributers for familiar cycle creators such as "Expression", "ScriptedOp" or "kine.Constraints".
A key contributor for a problamatic cycle will not be of the form "kine.local.PoseCompensatorOp"or
"kine.global.ParentPoseCns_E" or "kine.local.ParentPoseAndPoseCns_D" or "kine.global.SkeletonCtrlOpProp".
Note: the operators labeled "*_D"'s and "*_E"'s are definers and enforcers of the "kine.Constraints".
You can customize cycle checking in several ways:
Tip 1: If you want to check only the current frame for cycles, set the Check Current Frame parameter to true.
This is especially useful when one of the constraints participating in the cycle the activeness of a cycle
is animated.
Tip 2: If you are running this command from scripting, running the Refresh command prior to
running the CycleChecking command will ensure the values are current for the timeframe.
Tip 3: You can also maximize performance by enabling the 'Disable cycle checking when applying animation
operators' User Preference and then specifying true for the FollowCycleCheckUserPref parameter. Note that if
you leave the default value (false), this command will proceed with cycle checking regardless of what your
user preference says.
Tip 4: By default the cycle checker checks the entire nested hierarchy, beginning with the scene element
specified by the StartingGraphPt parameter. To check only the StartingGraphPt element, set the CheckFullNestedHier
flag to false.
Note: This command uses output arguments. C# and some
scripting languages (such as JScript, PerlScript and Python) don't support arguments passed by reference. Normally
you can get the output arguments via either XSIApplication.ExecuteCommand method (C#) or the
ISIVTCollection (scripting languages), but this command
already returns a value.
The only available workaround in this case is to create a VBScript custom command which returns both the output
arguments and the return value in one array. For details, see
What Happens when the Function Already Returns a Value?.
oBoolean = CycleChecking( [StartingGraphPt], [Check Current Frame], IsCycle, [DisableCycleCheck], [CheckFullNestedHier], [OutputObjs] ); |
Returns the result of the cycle check as a Boolean (true if there is a cycle).
Parameter | Type | Description |
---|---|---|
StartingGraphPt | String |
Object where the cycle checking will begin (the starting point). Default Value: Current selection |
Check Current Frame | Boolean |
True to check only the current frame for cycles. Default Value: false |
IsCycle | Boolean | True if there is a cycle. |
DisableCycleCheck | Boolean |
Check the User Prefs to see if cycle checking is enabled. Default Value: false |
CheckFullNestedHier | Boolean |
Checks the entire nested hierarchy when enabled. Checks the specified object only when disabled. Default Value: true |
OutputObjs | XSICollection of Operator objects | The Ops in the cycle(s). |
' Example: A cyclical expression NewScene CreatePrim "Sphere", "MeshSurface" Translate , -7.20756310877914, 2.07707676083662, -0.207707676083662, siRelative, siView, siObj, siXYZ GetPrim "Null" Translate , 3.82040230356053, 0.744612423696161, -7.44612423696161E-02, siRelative, siView, siObj, siXYZ SelectObj "sphere", , True InspectObj "sphere.kine.local" AddExpr "sphere.kine.local.posy" SelectObj "null", , True SetExpr "sphere.kine.local.posy", "null.kine.posy" Translate , 0.118156772275078, 0.235140765377718, -2.35140765377718E-02, siRelative, siView, siObj, siXYZ AddExpr "null.kine.local.posy" SetExpr "null.kine.local.posy", "sphere.kine.posy" Translate , 0.669555043461009, 1.01894331750266, -0.101894331750266, siRelative, siView, siObj, siXYZ Translate , -0.712516724951656, 1.96939066659309, -0.196939066659309, siRelative, siView, siObj, siXYZ Dim bCycle bCycle = CycleChecking( "Scene_Root" ) Logmessage bCycle ' The output is: 'WARNING : "3000 - Cycle Breaking Point sphere.kine.local.pos.posy.Expression" 'WARNING : "3000 - Cycle through sphere.kine.global.ParentPoseCns_E" 'WARNING : "3000 - Cycle through sphere.kine.local.PoseCompensatorOp" 'WARNING : "3000 - Cycle through null.kine.local.pos.posy.Expression" 'WARNING : "3000 - Cycle through null.kine.global.ParentPoseCns_E" 'WARNING : "3000 - Cycle through null.kine.local.PoseCompensatorOp" 'WARNING : "3000 - Cycle through sphere.kine.local.pos.posy.Expression" 'WARNING : "3000 - PROBLAMATIC EVALUATION CYCLES ARE IN THE SPECIFIED GRAPH" 'CycleChecking "Scene_Root" 'INFO : "True" |
' Example: A cyclical constraint NewScene CreatePrim "Cube", "MeshSurface" Translate , -7.75896137939607, -0.235140765377774, 2.35140765377774E-02, siRelative, siView, siObj, siXYZ CreatePrim "Sphere", "MeshSurface" Translate , 8.12409703994715, -0.284640094775458, 2.84640094775458E-02, siRelative, siView, siObj, siXYZ ApplyCns "Pose", "sphere", "cube" SelectObj "cube", , True ApplyCns "Position", "cube", "sphere" SelectObj "Scene_Root" Dim bCycle bCycle = CycleChecking( "Scene_Root" ) Logmessage bCycle ' The output is: 'WARNING : "3000 - Cycle Breaking Point cube.kine.global.IndpCns_E" 'WARNING : "3000 - Cycle through sphere.kine.Constraints.posecns.blends.PosePoseCns_D" 'WARNING : "3000 - Cycle through sphere.kine.global.PoseCns_E" 'WARNING : "3000 - Cycle through cube.kine.Constraints.poscns.blends.PosePoseCns_D" 'WARNING : "3000 - Cycle through cube.kine.global.IndpCns_E" 'WARNING : "3000 - Cycle through cube.kine.local.PoseCompensatorOp" 'WARNING : "3000 - Cycle through sphere.kine.local.PoseCompensatorOp" 'WARNING : "3000 - PROBLAMATIC EVALUATION CYCLES ARE IN THE SPECIFIED GRAPH" 'CycleChecking "Scene_Root" 'INFO : "True" |