Published using Google Docs
na_connect.txt
Updated automatically every 5 minutes

/**@file na_connect.mel v1.0.0

@brief Tools for quickly retreiving node connection information

@author Nathaniel O. Anozie (ogbonnawork at gmail dot com)

@bug all functions no assert checks

@note date created: Apr 4 2012

@note date last modified: Apr 30 2012

@note source na_connect.mel

@note source naGeneral.mel

@note Modify at your own risk

@note -- added some multiply divide tools, added some constraint tools

*/

/**return 1 if from has output to to, 0 otherwise

@param $to where we want connection to lead to,

@param $toPlug where we want connection to lead to

@param $from where we check connection coming from

@param $fromPlug where we check connection coming from

@bug not used in practice

*/

global proc int

na_isPlugConnected(string $to, string $toPlug, string $from, string $fromPlug)

{

    int $result = 0;

   

    string $toName  = "";

    $toName = $to+"."+$toPlug;

    na_assertObjectExist( {$toName} );

   

    string $fromName = "";

    $fromName = $from+"."+$fromPlug;

    na_assertObjectExist( {$fromName} );

   

    string $start[] = {};

    $start = `connectionInfo -destinationFromSource $toName`;

    if(size($start) == 1){  

        if( `strcmp $fromName $start[0]` == 0){$result = 1;}

    }

    return $result;

}

/**

create a multiply divide node of this name

@param string $name name for node

@pre name doesn't exist

@bug no error checking

*/

proc na_makeMultiplyDivide_assert(string $name)

{

        if(`objExists $name` == 1){ error("object exists");}

}

global proc na_makeMultiplyDivide(string $name)

{

    na_makeMultiplyDivide_assert($name);

        createNode multiplyDivide -n $name;

}

/**

connect these two inputs to the X or Y or Z plug of multiply divide

@param string $node name of multiply divide node

@param string $plugLetter   letter for where to set input

@param string $input1 control for first input  

@param string $input2   control for second input

@param string $input1Plug   control attr for first input

@param string $input2Plug  control attr for second input

@pre plug not used already

@post connections created

@bug no error checking

*/

global proc na_setAllInputToMDByPlugLetter(string $node, string $plugLetter, string $input1, string $input2, string $input1Plug, string $input2Plug)

{

        na_setInputToMDByPlugLetter($node, $plugLetter, $input1, $input1Plug, "input1");

         na_setInputToMDByPlugLetter($node, $plugLetter, $input2, $input2Plug, "input2");

}

/**

connect this inputs to the X or Y or Z plug of multiply divide

@param string $node name of multiply divide node

@param string $plugLetter   letter for where to set input

@param string $input1 control for first input  

@param string $input1Plug   control attr for first input

@param string  $inputStr either input1 or input2

@pre plug not used already

@post in connection created

@bug no plug connection exist checks

*/

global proc na_setInputToMDByPlugLetter(string $node, string $plugLetter, string $input1, string $input1Plug, string $inputStr)

{

    na_setInputToMDByPlugLetter_assert($node, $plugLetter, $input1, $input1Plug, $inputStr);

    string $in1 = $inputStr+$plugLetter;

    string $in1Plug = $input1+"."+$input1Plug;

       

    connectAttr -f $in1Plug ($node+"."+$in1);

}

global proc na_setInputToMDByPlugLetter_assert(string $node, string $plugLetter, string $input1, string $input1Plug, string $inputStr)

{

    na_assertTypeInList( {$node}, {"multiplyDivide"} );

    na_assertObjectExist( {$node,($input1+"."+$input1Plug)} );

    na_assertAllInList( {$plugLetter}, {"X","Y","Z"} );

    na_assertAllInList( {$inputStr}, {"input1","input2"} );

}

global proc na_setInputToMDByPlugLetter_unitTest_1()

{

    spaceLocator -p 0 0 0;

    move -r -os -wd -4.227784 0 0 ;

    createNode multiplyDivide  -n node_md;

    na_setInputToMDByPlugLetter("node_md","X","locator1","scaleX","input1");

}

/**set output of X or Y or Z plug of multiply divide to a second arg and plug

@param string $node name of multiply divide node

@param string $plugLetter   letter for where to set input

@param string $anim control

@param string $animPlug   control attr

@pre capitalized plug letter of X or Y or Z,md exists, md out plug exists, second arg plug exists, second arg plug has no input connections

@post out connection created

@bug no plug connection exist checks

*/

global proc na_setOuputToMDByPlugLetter(string $node, string $plugLetter, string $anim, string $animPlug)

{

    na_setOuputToMDByPlugLetter_assert($node, $plugLetter, $anim, $animPlug);

    string $out = "output"+$plugLetter;

    connectAttr -f ($node+"."+$out) ($anim+"."+$animPlug);

}

global proc na_setOuputToMDByPlugLetter_assert(string $node, string $plugLetter, string $anim, string $animPlug)

{

    na_assertTypeInList( {$node}, {"multiplyDivide"} );

    na_assertObjectExist( {$node,($anim+"."+$animPlug)} );

    na_assertAllInList( {$plugLetter}, {"X","Y","Z"} );

}

global proc na_setOuputToMDByPlugLetter_unitTest_1()

{

    spaceLocator -p 0 0 0;

    move -r -os -wd -4.227784 0 0 ;

    createNode multiplyDivide  -n node_md;

    na_setOuputToMDByPlugLetter( "node_md", "X", "locator1","scaleX" );

}

/**get multiply divide output letter from attribute with a multiplydivide connected to it

@pre animator plug exists,  one multiply divide out is connected to input plug

@post exactly 1 string returned either X or Y or Z

@bug no plug connection exist , not already connected checks

*/

global proc string

na_getPlugLetterByConnectedAttribute(string $anim, string $animPlug)

{

        string $outArray[] = {};

        $outArray = `listConnections -plugs true -source true ($anim+"."+$animPlug)`;

        string $out = "";

        $out = $outArray[0];//no size checking

        

        string $plugLetter = "";

        

        //for multiply divide node the last letter is important and tells us the different inputs and outputs

        //

        $plugLetter = endString($out,1); //no checking if X,Y,Z

        

        return $plugLetter;

}

/**given a node and plug give me the multiply divide whose ouptut leads to plug

@param string $anim an animator control with a plug that is connected to exactly 1 md node

@param string $animPlug plug connected to exactly 1 md node

@post could be more than one md so a different proc should check number of mds

*/

global proc string[]

na_getMultiplyDivideNodeFromPlug(string $anim, string $animPlug)

{

    string $mdArray[] = {};

        string $mdNode="";

        $mdArray = `listConnections -source true ($anim+"."+$animPlug)`;

        

        na_assertSizeGreaterEqualTo( $mdArray, 1 );

        $mdNode = $mdArray[0];

        

        //very important otherwise not sure if plugs exist on node

        na_assertTypeInList( {$mdNode}, {"multiplyDivide"} );

        

    return $mdArray;

}

/**given a plug whose input is a multiply divide node, give the input to md node at specified plugletter and plug input

@param  string $anim name object that has a plug whose input is one multiply divide node

@param  string $naAttr name of plug on on $anim whose input is one multiply divide node

@param  string $plugLetter either X, Y or Z

@param  string $plugInput either input1, or input2

@note not tested in practice

@bug not tested in practice, not asserting type is md node

*/

global proc string[]

na_getInputFromSingleMDNodeFromAnim(string $anim, string $naAttr, string $plugLetter, string $plugInput)

{

    na_assertObjectExist({$anim,($anim+"."+$naAttr)});

        string $result[] = {};

        

        //find data node from animator control

        string $mdArray[] = {};

        $mdArray = na_getMultiplyDivideNodeFromPlug( $anim, $naAttr );

        na_assertSizeEqualArg($mdArray,1);

        string $node = "";

        $node = $mdArray[0];

        

        string $plug = "";

        $plug = $plugInput+$plugLetter;

        

        $result = `listConnections -source true ($node+"."+$plug)`;

        

        return $result;

}

/**

@bug not tested, no asserting type is multiply divide

*/

global proc string[]

na_getPlugInputFromMultiMDNodeFromAnim(string $anim, string $naAttr, string $plugLetter, string $plugInput)

{

    na_assertObjectExist({$anim,($anim+"."+$naAttr)});

        string $result[] = {};

        

        //find data node from animator control

        string $mdArray[] = {};

        $mdArray = na_getMultiplyDivideNodeFromPlug( $anim, $naAttr );

        

        

        

        string $node = "";

        string $plug = "";

        string $inConnect[] = {};

        

        for($i = 0; $i < size($mdArray); $i++)

        {

            $node = $mdArray[$i];

            $plug = $plugInput+$plugLetter;

           

            $inConnect = `listConnections -plugs true -source true ($node+"."+$plug)`;

           

            if(size($inConnect) > 0){

                $result = stringArrayCatenate($result,$inConnect);

            }

        }

                

        return $result;

}

/**get both inputs with same out plug of multiply divide and all from same multiply divide node

@param string $anim an animator control with a plug that is connected to exactly 1 md node

@param string $animPlug plug connected to exactly 1 md node

@pre plug exists, md exists, md out plug exists

@post exactly 2 string returned correspond to input1 and input2 respectively, or empty list returned, all outputs are to same md node

@bug no checking for existing plugs of multiply divide node...

@see na_getPlugLetterByConnectedAttribute

*/

global proc string[]

na_getAllInputsByConnectedAttribute(string $anim, string $animPlug)

{

    na_assertObjectExist( { ($anim+"."+$animPlug) } );

   

        string $result[] = {};

        

        string $plugLetter = "";

        $plugLetter = na_getPlugLetterByConnectedAttribute($anim, $animPlug); //no way to know if cannot use

        

        string $in1 = "";

        $in1 = "input1"+$plugLetter;

        string $in2 = "";

        $in2 = "input2"+$plugLetter;

        

        //based on the multiply divide's out connection to animator control we can tell

        //what are all the inputs that effect this out on the md node

        //those inputs give the location, rotation scale to be used for snapping rig

        //

        string $mdArray[] = {};

        $mdArray = na_getMultiplyDivideNodeFromPlug($anim, $animPlug);

        if(size($mdArray) != 1){error("expecting single multiply divide node output to--"+$animPlug);}

        string $mdNode = "";

        $mdNode = $mdArray[0];

                

        string $input1NodeArray[] = {};

        $input1NodeArray = `listConnections -source true ($mdNode+"."+$in1)`; //no checking exactly 1 input to multiply divide node at input1X

        

        //if there is a place to snap to we save it,

        //its world transformation,roatation, scale we have access to

        //

        if(size($input1NodeArray) > 0 ){    

            string $input1Node = "";

            $input1Node = $input1NodeArray[0];

            $result[size($result)] = $input1Node;

        }

        

        string $input2NodeArray[] = {};

        $input2NodeArray = `listConnections -source true ($mdNode+"."+$in2)`;

        //no checking exactly 1 input to multiply divide node at input1X

        if(size($input2NodeArray) > 0 ){    

            string $input2Node = "";

            $input2Node = $input2NodeArray[0];

            $result[size($result)] = $input2Node;

        }

        

        

        return $result;

}

/**gives array at most 3 elements, where each is either 1, 2 or 3 depending on whether

input1X , input1Y, or input1Z has any incoming connection

@param string $anim an animator control with a plug that is connected to exactly 1 md node

@param string $animPlug plug connected to exactly 1 md node

@pre plug exists, md exists, md out plug exists

*/

global proc int[]

na_representInputMultiplyDivideAsAnInteger(string $anim, string $animPlug)

{

    int $result[];

   

    string $mdArray[] = {};

        $mdArray = na_getMultiplyDivideNodeFromPlug($anim, $animPlug);

        if(size($mdArray) != 1){error("expecting single multiply divide node output to--"+$animPlug);}

        

        string $mdNode = "";

        $mdNode = $mdArray[0];

        

        //note its not checking input2

        if(size( `listConnections -source true ($mdNode+"."+"input1X")` ) == 1){ $result[size($result)] = 1; }

        if(size( `listConnections -source true ($mdNode+"."+"input1Y")`) == 1){ $result[size($result)] = 2; }

        if(size( `listConnections -source true ($mdNode+"."+"input1Z")`) == 1){ $result[size($result)] = 3; }

        

        return $result;

}

/**get the start node name that lead to goal via connection

@note if two or more starts leads to goal returns one that is closet from goal in connections

@result string list of the thing in $possibleStart that can lead to $goal via connections

@param string $goal    goal node name

@param string $possibleStart[]  possible starting node names

@param string $supportedTypes[] possible node types it can traverse to find goal

@note not asserted

@supports finding a joint by way of joint, animCurve, unitedConversion or blendWeighted nodes

@see na_listRelativeConnection("locator1",{"transform"},30));

*/

global proc string[]

na_findStartToGoal( string $goal, string $possibleStart[], string $supportedTypes[] )

{

    //starts -- na_getOutConnect( "finger_controls.scrunch", "animCurve");

    string $result[] = {};

    //loop starting point find its connections down hierarchy

    string $start ="";//hold each possible start

    string $all[] = {}; //holds relative connection per start

    string $intersect[] = {};  //holds intersection with goal per start

   

    int $maxLevel = 1000;//we want the start that is closest to goal so this is helpful

    //this default value is the most possible number levels to connection to expect

    int $curLevel = 0;

    string $possible[]={};//hold possible starts including ones far

   

    //loop starts

    //break as soon as goal found in one of the possible starts and

    //return that possible start

    for( $i = 0; $i < size($possibleStart); $i++)

    {

        $start = $possibleStart[$i];

        $all = na_listRelativeConnection($start,$supportedTypes,30);

        $curLevel = size($all);//note may not lead to goal

        $intersect = na_getStringArrayIntersectWithOption( $all, {$goal} );//arg, options

        //if found goal save start curve that worked

        if(size($intersect) > 0 ){

            //only save this start if it has least most number of levels to goal

            if( $curLevel <= $maxLevel )

            {

                $maxLevel = $curLevel;//have a new maxLevel

                $possible = stringArrayCatenate($possible,{$start});

            }

        }

    }

    if(size($possible) > 0){

        $result = stringArrayCatenate($result,{$possible[size($possible)-1]});

    }

    else{

         print("sorry could not find path to --"+$goal+" please check input");

    }

    return $result;

}

/**assumes empty scene

*/

global proc

na_findStartToGoal_unitTest_1()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_findStartToGoal("locator5",{"locator1","locator2"},{"transform"}));

    print("\n");

    print(na_findStartToGoal("locator5",{"locator1","locator4"},{"transform"}));

}

/**assumes empty scene

*/

global proc

na_findStartToGoal_unitTest_2()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

    connectAttr -f locator3.translateX locator4.translateX;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_findStartToGoal("locator5",{"locator1","locator3"},{"transform"}));

    print("\n");

}

/**listRelativeConnections

@note it needs access to all support types down list so should be as large as possible

@param int $maxIterations what is the most number of times allowed to try searching for outs, i'm guessing 30 would

most likely work for most cases could make it higher

*/

global proc string[]

na_listRelativeConnection(string $node,string $supportedTypes[], int $maxIterations)

{

    string $result[]={};

    string $next[] = {};//keeps each level of connections and is refreshed each time

    string $prev[] = {};

   

    //gives all nodes going out

    $next = na_getOutConnectArray( {$node}, $supportedTypes );

    $result = stringArrayCatenate($result, $next);

    $prev = stringArrayCatenate($prev, $next);

   

    //figure out a kind of listRelative, but for listRelativeConnection

    //gives all outputs and we can support certain out types

    for( $i = 0; $i < $maxIterations; $i ++ ){

         

        $next = na_getOutConnectArray( $prev, $supportedTypes );

        //if size next ==  zero save have found all outs we exit

        if(size($next) == 0 ){

            break;

        }

        $result = stringArrayCatenate($result, $next);

        clear($prev);

        $prev = $next;

        clear($next);

   

        if($i >= $maxIterations){print("warning -- reached maxIterations");}

    }

    return $result;

   

}

/**assumes empty scene

*/

global proc

na_listRelativeConnection_unitTest_1()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

    connectAttr -f locator3.translateX locator4.translateX;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_listRelativeConnection("locator1",{"transform"},30));

}

/**assumes empty scene

*/

global proc

na_listRelativeConnection_unitTest_2()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

   

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_listRelativeConnection("locator1",{"transform"},30));

}

/**get all out connections from all input nodes of supported types

@resul string list all out connections from all input nodes of supported types

@param string list $array nodes of interest

@param string list $supportedTypes kinds of nodes we can consider finding out connections

*/

global proc string[]

na_getOutConnectArray(string $array[], string $supportedTypes[])

{

    string $result[]= {};

    string $next[] = {};

    string $node = "";

    for($i = 0; $i < size($array) ; $i ++ ){

       

        $node = $array[$i];

        //gives all nodes going out

        $all = na_getOutConnectAll( $node );

        //gives all nodes going out of this type

        //we may have no nodes going out so we should skip

        //this if is important otherwise run into problems

        if(size($all) > 0){

            $next = na_getSupported($all, $supportedTypes);

            //it may skip alot of nodes so its expected if we rarely enter this condition

            if(size($next) > 0){

                $result = stringArrayCatenate($result, $next);

            }

            clear($next);

        }

    }    

    $result = stringArrayRemoveDuplicates($result);

    return $result;

}

/**assumes empty scene

*/

global proc

na_getOutConnectArray_unitTest_1()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

    connectAttr -f locator3.translateX locator4.translateX;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_getOutConnectArray({"locator5"},{"transform"}));

}

/**assumes empty scene

*/

global proc

na_getOutConnectArray_unitTest_2()

{

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    spaceLocator -p 0 0 0;

    connectAttr -f locator1.translateX locator2.translateX;

    connectAttr -f locator2.translateX locator3.translateX;

    connectAttr -f locator3.translateX locator4.translateX;

    connectAttr -f locator4.translateX locator5.translateX;

    print(na_getOutConnectArray({"locator1","locator3"},{"transform"}));

}

/**give me the source(s) of constraint scene objects

@param string $constraint name of constraint on scene

@note can be any type of consraint

@pre assumes constraint command same as type

@post

@bug no error checking

*/

global proc string[]

na_getInConstraint(string $constraint){

   

    na_assertObjectExist( {$constraint} );

    string $supportedType[] = {"pointConstraint","orientConstraint","scaleConstraint"};

    na_assertTypeInList( {$constraint}, $supportedType );

   

    string $result[]={};

   

    string $flag = "-q -tl";

   

    $result = na_getConstraintByFlag( $constraint, $flag );

   

    return $result;

}

/**give me the source(s) of constraint scene objects with plug

@param string $constraint name of constraint on scene

@note can be any type of consraint

@pre assumes constraint command same as type

@post

@bug no error checking

@see na_getInConstraint

@see na_getPlugByAttributeArray

*/

global proc string[]

na_getInConstraintPlug(string $constraint){

   

    na_assertObjectExist( {$constraint} );

    string $supportedType[] = {"pointConstraint","orientConstraint","scaleConstraint"};

    na_assertTypeInList( {$constraint}, $supportedType );

   

    string $result[]={};

   

    string $flagWeight = "-q -wal";

    string $plug[] = na_getConstraintByFlag( $constraint,  $flagWeight );

   

    $result = na_getPlugByAttributeArray( $constraint , $plug );

   

    return $result;

}

/**get constraint according to flag advantage works with different kinds of constraints

@param string $constraint name of constraint on scene

@param string $flag that is valid for all supported types of constraint, no spaces at end

@note example flag "-q -tl" or "-q -wal"

@pre

@post

@bug no checking flag argument supported by constraint command

*/

global proc string[]

na_getConstraintByFlag(string $constraint, string $flag){

   

    na_assertObjectExist( {$constraint} );

   

    string $supportedType[] = {"pointConstraint","orientConstraint","scaleConstraint"};

    na_assertTypeInList( {$constraint}, $supportedType );

   

    string $result[]={};

   

    string $type = `objectType $constraint`;

     

    //assert object

   

    $result = eval( $type+" "+$flag+" "+$constraint);

   

    return $result;

}

/**get what is leading into this node of this type

@result what is leading into these nodes of this type

@param string $node node

@param string $type type

*/

global proc string[]

na_getInConnect( string $node, string $type )

{

    string $result[];

    $result = `listConnections -destination false -type $type -source true $node`;

    return $result;

}

/**get what is leading into these nodes of this type

@result noduplicates string list what is leading into these nodes of this type

@param string $node[] node

@param string $type type

*/

global proc string[]

na_getInConnectArray( string $node[], string $type )

{

    string $result[];

    for( $i = 0; $i < size($node) ; $i++ ){

        $result = stringArrayCatenate($result, na_getInConnect( $node[$i], $type ));

    }

    $result = stringArrayRemoveDuplicates($result);

   

    return $result;

}

/**get whats going out of this node of this type

@param string $node node

@param string $type type

*/

global proc string[]

na_getOutConnect( string $node, string $type )

{

    string $result[];

    $result = `listConnections -destination true -type $type -source false $node`;

    return $result;

}

global proc string[]

na_getOutConnectAll( string $node )

{

    string $result[];

    $result = `listConnections -destination true -source false $node`;

    return $result;

}