// Copyright (C) 1997-2004 Alias Systems Corp. // // The information in this file is provided for the exclusive use of the // licensees of Alias. Such users have the right to use, modify, // and incorporate this code into other products for purposes authorized // by the Alias license agreement, without fee. // // ALIAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, // INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO // EVENT SHALL ALIAS BE LIABLE FOR ANY SPECIAL, INDIRECT OR // CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, // DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER // TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. // // Alias Script File // MODIFY THIS AT YOUR OWN RISK // // Creation Date: July 30, 1997 // // // // // // // advanceToNextDrivenKey (string $advanceFlag, string $attribute) // // // None // // // Script for going to the next, previous, first or last // driven keyframe. Driven keyframes are set using Set Driven Key. // // // string $advanceFlag if true, go to next key, else go to previous key // // string $attribute the driven attribute or "" to use selected item // // // Say you have a lattice point keyed against a joint's rotation. // Select the lattice point and to go to the previous key enter: // advanceNextDrivenKey -previous ""; // // To go to the next driven key enter: // advanceToNextDrivenKey -next ""; // // To go to the first driven key enter: // advanceToNextDrivenKey -first ""; // // To go to the last driven key enter: // advanceToNextDrivenKey -last ""; // // If the object has more than one driven-key relationship defined, and // the "" argument is used, we advance ALL the drivers that // affect that object. // // Therefore, if you have many driven attributes on a node, you may want // to specify the attribute directly, for example: // advanceToNextDrivenKey -previous nurbSphere1.tx; // // Via the UI, you can specify an attribute to be advanced using the // setDrivenKey window menu item: Key->Go To Next, Key->Go To Previous. // // ///////////////////////////////////////////////////////////////////////// // Method: getAnimCurve // // Description: // Return the animCurve that connects $driver to $driven. // If such an animCurve cannot be found, returns an empty string. // global proc string getAnimCurve(string $driver, string $driven) { int $ii; string $result = ""; // First we will do the most simple thing ... look for a single // animCurve connected out of the driver. // string $conns[] = `listConnections -scn true -s false $driver`; int $count = size($conns); if (0 == $count) { error(("Could not locate downstream connections on "+$driven)); return $result; } int $animCurveCount = 0; for ($ii = 0; $ii < $count; $ii++) { string $isAnimCurve[] = `ls -type animCurve $conns[$ii]`; if (size($isAnimCurve)) { $result = $conns[$ii]; $animCurveCount++; } } if (1 == $animCurveCount ) { return $result; } // If the simple test done first does not work we need to try to // find the proper animCurve in a more complicated way: look in the // upstream history of the driven item for animCurves, and then // for each animCurve determine if its driver is $driver. // // First convert the driven item into an attribute name. // This is necessary for selection items such as CVs, where // the node name to plug name conversion is non-trivial. // string $drivenItems[] = `setDrivenKeyframe -q -dn $driven`; if (0 == size($drivenItems)) { error(("Could not locate upstream connections on "+$driven)); return $result; } string $hist[] = `listHistory -lf false $drivenItems[0]`; int $count = size($hist); for ($ii = 0 ; $ii < $count; $ii++) { string $isAnimCurve[] = `ls -type animCurve $hist[$ii]`; if (size($isAnimCurve)) { $conns = `listConnections -d false -p true -scn true ($hist[$ii]+".i")`; if (1 == size($conns)) { if ($conns[0] == $driver) { $result = $hist[$ii]; break; } } } } return $result; } // // Method: nextDrivenAdvance // // Description: // Given an animCurve with a non-time input, determine and perform // the setAttr command that will cause the input to move to the next // keyed value. // // Returns: // nothing // global proc nextDrivenAdvance(string $advanceFlag, string $animCrv) { float $tolerance = 0.0000005; string $conns[] = `listConnections -d false -p true -scn true ($animCrv+".i")`; if (1 != size($conns)) { error("nextDrivenAdvance: animCurve did not have an input."); return; } $attrToSet = $conns[0]; float $currentValue = `getAttr $attrToSet`; // tolerance is used to prevent the advance from getting stopped // up by precision errors // if ($advanceFlag == "-next" || $advanceFlag == "-n") { $currentValue += $tolerance; } else { $currentValue -= $tolerance; } // get current keys // float $values[] = `keyframe -q -fc $animCrv`; int $valueCount = size($values); if (0 == $valueCount) { error(("No keyframes found for "+$attrToSet)); return; } // find the next keyframe and advance to it using setAttr // string $cmd; if ($advanceFlag == "-next" || $advanceFlag == "-n") { for ($jj = 0; $jj < $valueCount; $jj++) { if ($currentValue < $values[$jj]) { $cmd = "setAttr "+$attrToSet+" "+$values[$jj]; break; } $cmd = "setAttr "+$attrToSet+" "+$values[0]; } } else if ($advanceFlag == "-previous" || $advanceFlag == "-p") { for ($jj = $valueCount-1; $jj >= 0; $jj--) { if ($currentValue > $values[$jj]) { $cmd = "setAttr "+$attrToSet+" "+$values[$jj]; break; } $cmd = "setAttr "+$attrToSet+" "+$values[$valueCount-1]; } } else if ($advanceFlag == "-first" || $advanceFlag == "-f") { $cmd = "setAttr "+$attrToSet+" "+$values[0]; } else if ($advanceFlag == "-last" || $advanceFlag == "-l") { $cmd = "setAttr "+$attrToSet+" "+$values[$valueCount-1]; } evalEcho $cmd; } // // Procedure Name: // advanceToNextDrivenKey // // Description: // Go to the next or previous driven key. // // Advance the driver of $attribute to its next or prior setDrivenKey // position. If $attribute == "", look at the selection list and // use the selected object as $attribute. If $attribute is not // a driven object, the command will give an error message and do // nothing. // // Input Arguments: // $advanceFlag: if true, go to next key, else go to previous key // $attribute: the driven attribute or "" to use selected item // // Return Value: // none // global proc advanceToNextDrivenKey(string $advanceFlag, string $attribute) { if ($attribute == "") { // if no attribute was specified, then try to use the // selection list // string $sel[] = `ls -sl`; if (1 != size($sel)) { error("Must select or supply exactly one driven item."); return; } $attribute = $sel[0]; } if ($advanceFlag != "-next" && $advanceFlag != "-n" && $advanceFlag != "-previous" && $advanceFlag != "-p" && $advanceFlag != "-last" && $advanceFlag != "-l" && $advanceFlag != "-first" && $advanceFlag != "-f") { error("Invalid flag: "+ $advanceFlag+ " used on advanceToNextDrivenKey."); } // find the driver(s) // string $drivers[] = `setDrivenKeyframe -q -dr $attribute`; if ($drivers[0] == "No drivers.") { error("No driver found for "+$attribute); return; } string $cmd; int $ii; int $driverCount = size($drivers); for ($ii = 0; $ii < $driverCount; $ii++) { string $animCurve = getAnimCurve($drivers[$ii],$attribute); if ("" != $animCurve) { nextDrivenAdvance($advanceFlag,$animCurve); } } }