// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // FILE: getNucleusRelated.mel // INPUT: string (node name) // string[] (node types) // int (max display type in Dynamics mode) // // RETURN: string[] (list of related nodes, with the node whose // tab you want to be opened duplicated at the // end of the array) // proc int isNType( string $nType ) // // Description: // Returns true iff this node is a nucleuse related node. // { return( $nType == "nCloth" || $nType == "nRigid" || $nType == "nParticle" || $nType == "nucleus" || $nType == "pointEmitter" || $nType == "hairSystem" || $nType == "dynamicConstraint" || $nType == "nComponent" ); } global proc string[] getNucleusRelated( string $nNode, // Original nucleus node string $nTypes[], // Different types string $prefNode, // preferred node, "" if none. // Usually this should be the same // as $nNode int $optional ) // True iff we also want the // optional types displayed. // // Description: // Given a nucleus type node (eg, nCloth, nucleus), find other related // nucleus (and non-nucleus) nodes, and sort them according to the type array // specified. // { // Add dynamicConstraint whenever we find an nComponent? // string $nType = `nodeType $nNode`; string $retval[]; int $retSize = 0; // Get the default tabs for this node // string $navNodes[]; if( $nType == "nCloth" || $nType == "nParticle" ){ // Default navigation with an nCloth node is over agressive, because of // the two way connections between nCloth & nucleus. So we'll emulate // manually what happens in TdefaultNavigator::relatedNodes, but cut // the history off at a depth of two to avoid pulling in irrelevant // stuff. // // We added nRigid to the above because defaultNavigation no longer finds the // nucleus node now that it is derived from transform. string $hist[] = `listHistory -pdo 1 -lf 0 -il 2 -lv 2 -bf $nNode`; string $future[] = `listHistory -pdo 1 -lf 0 -il 2 -f 1 $nNode`; string $both[] = stringArrayCatenate( $hist, $future ); if($nType == "nParticle") { // add the emitters and shading network stuff explicitly here string $partStuff[] = `AEparticleRelated ($nNode)`; $both = stringArrayCatenate( $both, $partStuff ); } $navNodes = stringArrayRemoveDuplicates( $both ); } else { $navNodes = `defaultNavigation -ren -d $nNode`; } $retSize = size($navNodes); $tmpArray[0] = $nNode; if( $nType != "nucleus"){ // need to pull in nucleus node because now that it derives from transform defaultNavigation and listHistory no longer include it string $nucleusNodes[] = `listConnections -type nucleus $nNode`; if( size($nucleusNodes) > 0 ){ $tmpArray[1] = $nucleusNodes[0]; } } if( $retSize > 0 ){ // Prefix it with the original nucleus node. // $retval = stringArrayCatenate( $tmpArray, $navNodes ); } else { $retval = $tmpArray; } $retSize = size($retval ); string $node; if( $nType == "nCloth" || $nType == "nRigid" || $nType == "nParticle" ){ // For nCloth/nRigid, we only need to add the nodes of type // dynamicConstraint. If we did the whole history thing, we'd bring in // too many nodes (because nCloth & nRigid have two way connections to // the nucleus node). // // Since nodes of type "nComponent" are in the default navigation of an // nCloth/nRigid, we look for those & add the associated // "dynamicConstraint" as an interesting node. // int $lastNode = $retSize; int $index = 0; while( $index < $lastNode ){ $node = $retval[$index]; if( `nodeType $node` == "nComponent" ){ // Add the dynamicConstraint node, if any // string $nodes[] = `listConnections ($node + ".outComponent")`; int $nodeIndex = 0; int $numNodes = size($nodes); while( $nodeIndex < $numNodes ){ string $currNode = $nodes[$nodeIndex]; $nType = `nodeType $currNode`; if( $nType == "transform" ){ string $children[] = `listRelatives $currNode`; int $childIndex = 0; int $numChildren = size($children); while( $childIndex < $numChildren ){ string $child = $children[$childIndex]; $nType = `nodeType $child`; if( $nType == "dynamicConstraint" ){ $retval[$retSize] = $currNode; $retSize++; $retval[$retSize] = $child; $retSize++; } $childIndex++; } } $nodeIndex++; } } $index++; } } else { // Otherwise, check the source connections to the nucleus node for // other "n" nodes. // string $histNodes[] = `listHistory -future false $nNode`; for( $node in $histNodes ) { string $hType = `nodeType $node`; if( isNType( $hType ) ){ string $parents[] = `listRelatives -parent $node`; if( size($parents) > 0 ){ $retval[$retSize] = $parents[0]; $retSize++; } $retval[$retSize] = $node; $retSize++; } } if( $nType == "nComponent" ){ // Dynamic constraint is in the future, so we need to grab more to // be safe. // string $futureNodes[] = `listHistory -future true -lv 2 $nNode`; for( $node in $futureNodes ) { string $hType = `nodeType $node`; if( isNType( $hType ) ){ string $parents[] = `listRelatives -parent $node`; if( size($parents) > 0 ){ $retval[$retSize] = $parents[0]; $retSize++; } $retval[$retSize] = $node; $retSize++; } } } } // Now filter the nodes // string $filteredNodes[] = `filterNucleusNodes $prefNode $retval $nTypes $optional`; return $filteredNodes; }