MEL: Walking Through Hierarchy

I am writing a MEL script that will rename all joints in the merged hierarchy to a known format. The idea is that you select the hip joint and the script rename the hips and go through all the other joints and rename it based on your position in the hierarchy.

How can you walk through the collaborative hierarchy in MEL?

+3


source to share


3 answers


If you assign a $stat_element

name to your top joint in the hierarchy and run the following code, it prefixes "myPrefix_"

all children of that joint.

string $stat_element = "joint1";
select -r $stat_element;
string $nodes[] = `ls -sl -dag`;
for($node in $nodes){
    rename -ignoreShape $node ("myPrefix_" + $node);
}

      



Hope it helps

+4


source


If you need to make detailed decisions along the way, instead of renaming the transitions, the hierarchy is pretty straightforward. Command - "listRelatives"; With the 'c' flag it returns the children of the node, and with the 'p' flag it returns the parent. (Note that -p returns a single object, -c returns an array)

Joint1
    Joint2
        Joint3
        Joint4

listRelatives -p Joint2
// Result: Joint1 //
listRelatives -c Joint2
// Result: Joint3, Joint4

      



The tricky bit is renaming, as Maya won't always give you the name you expect (it will prevent duplicate names at the same level of the hierarchy). You will need to keep track of the renamed objects or you will not be able to find them after renaming them in case the new names do not meet your expectations.

If you need to keep track of them, you can create a set with the set command before renaming; no matter what becomes of the names, all objects will still be in the set. Plus, you can navigate the hierarchy by selecting objects and renaming the current selection - this won't record the changes, but you won't have problems with objects changing names in the middle of your operation and messing up your commands.

0


source


In MEL it can be messy if you have unique names because the descriptor you have for an object is the name itself. After renaming a parent node with a unique name, the child name is different. If you kept a list of all names before you started renaming, you will get errors because the rename command will try to rename nodes that do not exist. There are two solutions I know about using MEL. But firstly, the pyMel solution here is much simpler and I recommend you use it.

PyMel solution:

import pymel.core as pm
objects = pm.ls(selection=True, dag=True, type="joint")
pfx = 'my_prefix_'
for o in objects:
    o.rename(pfx + o.name().split('|')[-1])

      

As it pm.ls

returns a list of real objects, not just names, you can safely rename the parent node and still have a valid handle to your children.

If you really want to do this in MEL, you need to either rename from bottom to top or recurse so that you don't ask for child names before dealing with the parent.

The first MEL solution is to get a list of long object names and sort them based on their depth, deepest first. This way you can never rename a parent in front of his children. The sorting bit is too confusing to worry about here, and the recursive solution is better anyway.

Recursive MEL solution:

global proc renameHi(string $o, string $prefix) {

    string $children[] = `listRelatives -f -c -type "joint $o`;
    for ($c in $children) {
        renameHi( $c ,$prefix ) ;
    }

    string $buff[];
    int $numToks = tokenize($o, "|", $buff);
    string $newName = $buff[( $numToks - 1)];

    $newName = ($prefix + $newName);
    rename($o,$newName);
}

string $prefix = "my_prefix_";
string $sel[] = `ls -sl -type "joint"`;
for ($o in $sel) {
    renameHi($o, $prefix);
}

      

This recursive solution drills down to leaf nodes and renames them before renaming their parents.

0


source







All Articles