View Full Version : MEL-query custom Attributes?

02-03-2010, 01:37 PM
Hi there!
just came around this. I want to Melscript all my custom attributes to zero.
so instead of having to type them all in explicit like this with the setAttr Cmd

setAttr "LtLegCTRL.kneePVCnstrt" 0;
setAttr "RtLegCTRL.kneePVCnstrt" 0;
setAttr "LtLegCTRL.footRoll" 0;
setAttr "RtLegCTRL.footRoll" 0;
... and so on

i am wondering if anyone knew a more savvy attempt. Maybe by query all custom attributes into a list and then set the output list (array(?) all to zero.
But with querying i just can see the addAttr with -dv flag (default values). hmm...

02-05-2010, 10:48 AM
Here you go.

//Get which control is selected
string $sel[] = `ls -sl`;
string $nodeName = $sel[0];
//Get all the custom atributes on this control
string $customAttr[] = `listAttr -ud`;
string $udAnimName = "";

//Loop through the custom attributes and put all the animatable attributes in a string.
for ($each in $customAttr)
string $udAnim[] = `listAnimatable ($nodeName + "." + $each)`;
string $buffer[0];
tokenize $udAnim[0] "|" $buffer;
string $niceName = $buffer[0];

int $match = `gmatch $niceName ($nodeName + "." + $each)`;
if ($match == 1)
$udAnimName += ($each + " ");
//We need to tokenize(break apart) the string and store each attribute in the $attrArray
string $attrArray[];
tokenize $udAnimName " " $attrArray;

print $attrArray;

This queries all user defined(custom) attributes and sort out any that are non animatable (keyable) such as message attr etc. Then with this array called $attrArray you can just put in a loop and use the setAttr command like so:

//Loop through to eval the setAttr command on each custom attribute
for ($each in $attrArray)

//See if the attribute has a min or a max value
int $minEx = `attributeQuery -node $nodeName -minExists $each`;
int $maxEx = `attributeQuery -node $nodeName -maxExists $each`;

//Then for each option you must query and set appropriate value

if ($minEx == 1 && $maxEx == 1)
float $min[] = `attributeQuery -node $nodeName -min $each`;
float $max[] = `attributeQuery -node $nodeName -max $each`;
if ($value <= $min[0])
setAttr ($nodeName + "." + $each) $min[0];
if ($value > =$max[0])
setAttr ($nodeName + "." + $each) $max[0];
if ($value > =$min[0] && $value <= $max[0])
setAttr ($nodeName + "." + $each) $value;

if ($minEx == 1 && $maxEx == 0)
float $min[] = `attributeQuery -node $nodeName -min $each`;
if ($value < =$min[0])
setAttr ($nodeName + "." + $each) $min[0];
setAttr ($nodeName + "." + $each) $value;

if ($minEx == 0 && $maxEx == 1)
float $max[] = `attributeQuery -node $nodeName -max $each`;
if ($value >=$max[0])
setAttr ($nodeName + "." + $each) $max[0];
setAttr ($nodeName + "." + $each) $value;

if ($minEx == 0 && $maxEx == 0)
setAttr ($nodeName + "." + $each) $value;


If there are other types of attributes except for floats such as enum or boolean you could sort them out to only allow floats in the array otherwise it will break =/ or perhaps a better choie is to query it's min or max and match to what settings you chose. IE if you set 2 and it's max is 1 then set 1.

I mistyped some and then added some more so this should work for all attributes in the channelbox. However, this also means that every custom attribute values are set to what you specified which most often is not desireable. I hope the idea is clear and you can alter it to suit your needs.

Also had to comment. often slips my mind.

02-09-2010, 12:16 PM
I've been using one of the zooToolbox scripts for this. I dont think Hamish would mind me posting the code here. This one has the ability to reset all keyable attributes (including custom attributes) and in addition will return joints to their bind pose rather than zeroing them. It deals with the attribute limits too (by ignoring them quietly).

//simply resets all keyable attributes on a given object to its default value
//great for running on a large selection such as all character controls...
global proc zooResetAttrs( string $obj ) {
string $attrs[] = `listAttr -k -s -m $obj`;

//if the transform is a joint, see if its part of a bindpose, and if so, restore to
//the bindpose, not zero, as this is generally the preferred behaviour
string $poses[] = `listConnections -s 0 -type dagPose $obj`;
string $bindPoses[] = {};

$poses = `stringArrayRemoveDuplicates $poses`;
for( $pose in $poses ) if( `getAttr ( $pose +".bindPose" )`) $bindPoses[`size $bindPoses`] = $pose;

if( `size $bindPoses` ) dagPose -r -bp $obj;
else for( $attr in $attrs ) {
float $default[] = {0.0};

if( !catch(`attributeQuery -n $obj -listDefault $attr`)) $default = `attributeQuery -n $obj -listDefault $attr`;
if( !`getAttr -se ( $obj +"."+ $attr )` ) continue;

//need to catch because maya will let the default value lie outside an attribute's
//valid range (ie maya will let you creat an attrib with a default of 0, min 5, max 10)
catchQuiet( `setAttr ( $obj +"."+ $attr ) $default[0]` );

You could run it for each object like this

string $all[] = `ls -sl`;
for( $a in $all ) zooResetAttrs $a;

-- David

CGTalk Moderation
02-09-2010, 12:16 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.