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" |