Script: Delete Flat Keys

Script: Delete Flat Keys

When you’re working with animation you eventually end up with a lot of extra keys, by that I mean flat keys, keys we don’t need.

See the image below, I’ve marked the flat keys with red dots:

 

With the script you just select all of the objects that you want to clean the keyframes on, then you define the angle threshold, and the script will go through and delete all of the keys with a lower angle threshold than defined.

When run on the example above, we end up with this:

 

jh_delFlatKeys (Delete Flat Keys)

//*************************************************************************************************************
// Title: jh_delFlatKeys.mel
// Author: Jørn-Harald Paulsen
// Created: September 08, 2010
// Last Update: May 28, 2011
// Description: Utility to remove key’s with a lower value-difference than specified.
//*************************************************************************************************************
// MAIN WINDOW
//*************************************************************************************************************
global proc jh_delFlatKeys()
{
//Close window if it already exists
if (`window -q -ex jh_delFlatKeys`) deleteUI jh_delFlatKeys;

//Main Window
window -topEdge 30 -title “Keyframe cleanup”
-mxb false -s true -rtf false -mb false -mbv false -w 412 -h 268 jh_delFlatKeys;

//Window content
columnLayout -adjustableColumn true;
text -label “\nUtility to remove key’s with a lower value-difference than specified.\n” -fn boldLabelFont;
separator -w 240 -h 40;
text -label “- Select the object(s) that you want to clean keyframes on”;
text -label “- Define the angle/value tolerance (keys with values lower than these will be deleted)\n”;
floatSliderGrp -label “Angle tolerance” -f true -min 0.001 -max 5.000 -fmn 0.001 -fmx 100.000 -v 0.001 -s 0.001 sliderAngleTol;
floatSliderGrp -label “Value tolerance” -f true -min 0.001 -max 5.000 -fmn 0.001 -fmx 100.000 -v 0.001 -s 0.001 sliderValueTol;
separator -w 240 -h 40;
button -label “Clean keyframes” -c jh_deleteKeys;
separator -w 240 -h 40;
window -e -w 412 -h 268 jh_delFlatKeys;
showWindow jh_delFlatKeys;
}

global proc jh_deleteKeys()
{
//Get the selected object(s)
string $selObj[] = `ls -sl`;
//Create a variable to store the number of keys deleted
int $keysDeleted = 0;
//For each selected object
for($object in $selObj)
{
//Get the animation curves
string $animCurve[] = `keyframe -query -name $object`;
//If the object have animation curves
if (size($animCurve) > 0)
{
//Tangents with angles below this value will be considered flat
float $angleTol = `floatSliderGrp -q -v sliderAngleTol`;
//Neighboring values that fall within this tolerance will be considered matching
float $valueTol = `floatSliderGrp -q -v sliderValueTol`;

//Define the variables
string $keyedAttrs[], $outTanType[], $evalStr, $plural;
float $keyedValues[], $inAngle[], $outAngle[], $keyedFrames[], $prevValDif, $nextValDif;
int $deleteIndex[], $stepped, $i;
int $counter = 0;

//For each animation curve
for ($curve in $animCurve)
{
clear($inAngle);
clear($outAngle);
clear($deleteIndex);
clear($keyedValues);

//Get all of the keyed attributes
$keyedAttrs = `listConnections -plugs yes -source no $curve`;

//Go through the keyframes on the current animation-curve and get inAngle and outAngle
float $inAngle[] = `keyTangent -query -inAngle $curve`;
float $outAngle[] = `keyTangent -query -outAngle $curve`;
string $outTanType[] = `keyTangent -query -outTangentType $curve`;

//Make $inAngle and $outAngle absolute values, for less work on the comparison
for ($i=0;$ifor ($i=0;$i

//Get each keyed frame, and get the value of each keyed frame
$keyedFrames = `keyframe -query -timeChange $curve`;
$keyedValues = `keyframe -query -valueChange $curve`;

//For each keyeframe on the current animation-curve, find deleteable keys
for ($i=0;$i {
//As long as the current keyeframe is between 0, and less than the number of keyframes, continue
if ($i == 0 || $i == (`size $keyedFrames`-1)) continue;

//Get the outTangentType of the previus frame, the current frame, and the next frame.
//The result of this command will go to $stepped. If true, $stepped = 1, if false, $stepped = 0
$stepped = ($outTanType[$i] == “step” && $outTanType[$i-1] == “step” && $outTanType[$i+1] == “step”);

//If one of the following conditions (1 or 2) is true, rund the script inside of the if-brackets:
// 1) $stepped is true (1)
// 2) outAngle of the previous frame is less than angleTol
// & inAngle of the current frame is less than angleTol
// & outAngle of the current frame is less than angleTol
// & inAngle of the next frame is less than angleTol
if ($stepped || ($outAngle[$i-1] < $angleTol && $inAngle[$i] < $angleTol && $outAngle[$i] < $angleTol && $inAngle[$i+1] < $angleTol))
{
//Get the difference of the value of the current attribute between the previous frame and the current frame
$prevValDif = abs($keyedValues[$i-1] – $keyedValues[$i]);
//Get the difference of the value of the current attribute between the current frame and the next frame
$nextValDif = abs($keyedValues[$i+1] – $keyedValues[$i]);

//If one of the following (1 or 2) conditions is true, set $deleteIndex:
// 1) $stepped is true (1)
// & $prevValDif is less than valueTol
// 2) $stepped is false (0)
// & $prevValDif is larger than valueTol
// & $nextValDif is larger than $valueTol
if ($stepped && $prevValDif < $valueTol || !$stepped && $prevValDif < $valueTol && $nextValDif < $valueTol) $deleteIndex = $i; } } //Make the string to delete the keys if (size($deleteIndex) > 0)
{
//The first command of the delete -string
$evalStr = “cutKey -clear”;
//Add the indexes to the string
for ($i in $deleteIndex) $evalStr += ” -index ” + $i;
//Add the animation-curve to the string
$evalStr += ” ” + $curve;
//Execute the generated cutKey -string
eval($evalStr);
//Get the number of keys deleted
$counter += size($deleteIndex);
}
}

//If more than one key has been deleted, set the $plural to true
$plural = ($counter > 1 || $counter == 0) ? “s” : “”;
//Put the number of deleted keys on the current attribute to the total deleted keys -variable
$keysDeleted = $keysDeleted + $counter;
//Print information
print ($counter + ” keyframe” + $plural + ” removed from ” + $object + “.\n”);
}
}
//Print number of keys deleted in total
print (“Deleted keyframes in total: ” + $keysDeleted + “.\n”);
}

jh_delFlatKeys;

Download Script

 

3 comments

  1. pmac says:

    Thanks for that.

  2. This is excellent! Spent some time looking for this. Thanks a lot!

  3. Marthinus says:

    That hit the spot. I always wanted a script for this to help with my obsessive compulsive disorder when animating 😉 Thanks man.

Leave a Reply

Your email address will not be published. Required fields are marked *