我正在编写一个MEL脚本,它将联合层次结构中的所有关节重命名为已知格式。我们的想法是你要选择Hip关节,脚本会重命名Hips,并遍历其他所有关节并根据它在层次结构中的位置重命名。
如何遍历MEL中的联合层次结构?
答案 0 :(得分:4)
如果您在层次结构中为$stat_element
指定了顶部关节的名称并运行以下代码,则会为该关节的所有子元素添加前缀"myPrefix_"
。
string $stat_element = "joint1";
select -r $stat_element;
string $nodes[] = `ls -sl -dag`;
for($node in $nodes){
rename -ignoreShape $node ("myPrefix_" + $node);
}
希望这有帮助
答案 1 :(得分:0)
如果您需要在进行详细决策时,而不是批量重命名,则遍历层次结构非常简单。命令是'listRelatives';使用'c'标志返回节点的子节点,并使用'p'标志返回父节点。 (注意-p返回单个对象,-c返回一个数组)
Joint1
Joint2
Joint3
Joint4
listRelatives -p Joint2
// Result: Joint1 //
listRelatives -c Joint2
// Result: Joint3, Joint4
棘手的一点是重命名,因为maya不会总是给你你想要的名字(它不允许在层次结构的同一级别重复名称)。您需要跟踪重命名的对象,否则在重新命名后,如果新名称与您的期望不符,您将无法找到它们。
如果需要跟踪它们,可以在重命名之前使用set命令创建一个集合;无论名称变成什么,所有对象仍将在集合中。或者,您可以通过选择对象并重命名当前选择来遍历层次结构 - 这不会记录更改,但是您不会遇到在操作过程中更改名称并弄乱命令的对象问题。
答案 2 :(得分:0)
如果您有非唯一名称,在MEL中执行此操作可能会很麻烦,因为您对该对象的句柄是名称本身。使用非唯一名称重命名节点的父节点后,子节点的名称会有所不同。如果在开始重命名之前存储了所有名称的列表,则会出现错误,因为重命名命令将尝试重命名不存在的节点。我知道使用MEL有两种解决方案。但首先,这是pyMel解决方案,它更容易,我建议你使用它。
PyMel解决方案:
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])
由于pm.ls
返回真实对象的列表,而不仅仅是名称,因此您可以安全地重命名父节点,并且仍然具有其子节点的有效句柄。
如果你真的想在MEL中这样做,你需要从下往上重命名,或者递归,以便你在与父母交往之前不要求孩子的名字。
第一个MEL解决方案是获取一个长对象名称列表,并根据它们的深度对它们进行排序,最先深入。通过这种方式,您可以保证永远不会在其子项之前重命名父项。排序位太复杂,不能在这里打扰,无论如何递归解决方案都更好。
递归MEL解决方案:
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);
}
这个递归解决方案向下钻取到叶节点,并在重命名父节点之前重命名它们。