// MTkeyRoundOff.mel // Written by Markus Tessmann, Rock Farm Animation // ------------------------------------------------------- // // This script will snap keys to integer frame values, // rounding up or down depending on decimal value. // It includes a test so that two close frames don't land on the same frame number. // // NOTE: This script doesn't work that well on negative frames, which always get rounded up. // Also, frames between -1 and 0 get rounded to 1. // global proc MTKeyRoundOff() { string $nodesSelected[]; $nodesSelected = `selectedNodes`; // Gets the number of objects that are selected int $objectsSelected = size($nodesSelected); // Goes through the list of selected objects for ( $x=0 ; $x<$objectsSelected ; $x++ ) { // Clears the selection of all the keys that might be selected; selectKey -cl; // Selects all the keys in the selected object selectKey; float $keyTimes[]; float $keyValue[]; float $keyTest; // Gets all the nodes that have keys in the selected object string $nodes[] = `keyframe -q -name $nodesSelected[$x]`; int $numberOfNodes = size($nodes); for( $y=0 ; $y<$numberOfNodes ; $y++ ) { // Gets the frame number of all the selected keys in the specified node $keyTimes = `keyframe -sl -q -tc $nodes[$y]`; for ($i=0; $i < size($keyTimes); $i++) { int $previous = $i - 1; if ($previous < 0) $previous = 0; int $next = $i + 1; // Gets the integer of the time by truncating any floating point. int $newTime = int($keyTimes[$i]); if ($keyTimes[$i] !=0) { if ($keyTimes[$i] < 0) warning("Negative keyframes found. Will round up, which may not be closest integer value!"); // Checks that there is no floating point. // But first, if keyframe is between one and negative one, // add two before modulo to avoid divide-by-zero error if (($keyTimes[$i] < 1) && ($keyTimes[$i] > -1)) $keyTest = ($keyTimes[$i] + 2) % (int($keyTimes[$i]) + 2); else $keyTest = $keyTimes[$i] % int($keyTimes[$i]); if ($keyTest != 0) { //Moves the key to an interger position. //If the remainder of division is smaller than 0.5 move the key down //if it's bigger, move the key up. if ($keyTest < 0.5) { // test to see if previous keyframe is already using frame $newtime if ($keyTimes[$previous] != $newTime) { keyframe -e -time $keyTimes[$i] -tc $newTime $nodes[$y]; $keyTimes[$i] = $newTime; } // if it is, then check if the next frame can be used else if ($keyTimes[$next] != ($newTime + 1)) { keyframe -e -time $keyTimes[$i] -tc ($newTime+1) $nodes[$y]; $keyTimes[$i] = $newTime + 1; } // otherwise let the user know that the frame cannot be changed else { print("Keyframe at " + $keyTimes[$i] + " is bound by two integer keyframes"); warning("Keyframe will not be rounded"); } } else { keyframe -e -time $keyTimes[$i] -tc ($newTime+1) $nodes[$y]; $keyTimes[$i] = $newTime + 1; } } } } } } }