MEL:遍历层次结构

MEL:遍历层次结构,mel,Mel,我正在编写一个MEL脚本,将关节层次中的所有关节重命名为已知格式。这样做的目的是选择髋关节,脚本将重命名髋关节,然后遍历其他每个关节,并根据其在层次中的位置对其进行重命名 如何遍历MEL中的关节层次结构?如果将层次结构中顶部关节的名称指定给$stat\u元素并运行以下代码,它将向该关节的所有子元素添加前缀myPrefix\u string $stat_element = "joint1"; select -r $stat_element; string $nodes[] = `ls -sl -d

我正在编写一个MEL脚本,将关节层次中的所有关节重命名为已知格式。这样做的目的是选择髋关节,脚本将重命名髋关节,然后遍历其他每个关节,并根据其在层次中的位置对其进行重命名

如何遍历MEL中的关节层次结构?

如果将层次结构中顶部关节的名称指定给$stat\u元素并运行以下代码,它将向该关节的所有子元素添加前缀myPrefix\u

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

如果您需要在执行过程中做出详细的决策,希望这对您有所帮助,而不是批量重命名,遍历层次结构非常简单。命令为“listRelatives”;使用“c”标志返回节点的子节点,使用“p”标志返回父节点。注意,-p返回单个对象,-c返回一个数组

Joint1
    Joint2
        Joint3
        Joint4

listRelatives -p Joint2
// Result: Joint1 //
listRelatives -c Joint2
// Result: Joint3, Joint4
棘手的一点是重命名,因为maya不会始终为您提供您期望的名称,它不允许在层次的同一级别上重复名称。您需要跟踪重命名的对象,否则在重命名后将无法找到它们,以防新名称与您的期望不符


如果需要跟踪它们,可以在重命名之前使用set命令创建集合;无论名称变成什么,所有对象都将仍然在集合中。或者,您可以通过选择对象并重命名当前的选择来遍历层次结构,这不会记录更改,但是在操作过程中更改对象名称并弄乱您的命令不会有问题。

< P>如果您有对象的句柄,则在MEL中如果有非唯一名称,可能会很难做到这一点。就是名字本身。使用非唯一名称重命名节点的父节点后,子节点的名称将不同。如果在开始重命名之前存储了所有名称的列表,则会出现错误,因为rename命令将尝试重命名不存在的节点。我知道使用MEL有两种解决方案。但首先,这里是pyMel解决方案,它更简单,我建议您使用它

PyMel解决方案:

由于pm.ls返回的是真实对象的列表,而不仅仅是名称,因此您可以安全地重命名父节点,并且对其子节点仍然具有有效的句柄

如果您真的想在MEL中执行此操作,则需要从下到上重命名,或者递归,以便在处理父对象之前不会询问子对象的名称

第一个MEL解决方案是获取一个长对象名称列表,并根据深度对其排序,最深优先。通过这种方式,您可以保证不会在其子级之前重命名父级。排序位太复杂了,这里不需要麻烦,递归解决方案无论如何都更好

递归MEL解决方案:


此递归解决方案深入到叶节点,并在重命名它们的父节点之前重命名它们。

如果某些名称不唯一,则ls将返回最短的唯一路径,例如左髋膝。在膝盖前面加上say fred_u和你的方法不会给fred_u膝盖。它将试图让弗雷德左膝,但那将是一个错误没有与名称匹配的对象//
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])
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);
}