2012-04-09 212 views
3

我正在编写一个MEL脚本,将联合层次结构中的所有关节重命名为已知格式。这个想法是,你会选择髋关节,脚本会重命名臀部,并通过其他关节并根据其在层次结构中的位置对其进行重命名。MEL:遍历层次结构

如何遍历MEL中的联合层次结构?

回答

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); 
} 

希望这有助于

+0

如果某些名称不是唯一的,则ls将返回最短的唯一路径 - 例如left_hip | knee。用你的方法在前面加上说“fred_”的膝盖不会给予fred_knee。它会尝试给予fred_left_hip |膝盖,但这将是一个错误。 //没有对象匹配名称// – 2013-06-07 22:41:17

0

如果你需要,你走进行详细的决策,而不是批量重命名,遍历层级结构是非常简单的。该命令是'listRelatives';用'c'标志返回一个节点的子节点,并用'p'标志返回父节点。 (请注意,-p返回一个对象,-c返回数组)

Joint1 
    Joint2 
     Joint3 
     Joint4 

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

棘手位是重命名,因为玛雅人不会总是给你希望的名字(它不会允许在名称重复层次结构的相同级别)。您需要跟踪重命名的对象,否则在新名称与您的期望不符时,您将无法在重命名对象后找到它们。

如果您需要跟踪它们,您可以在重命名之前使用set命令创建一个集合;不管这些名字是什么,所有的对象都会在这个集合中。或者,您可以通过选择对象并重命名当前选择来遍历层次结构 - 这不会记录更改,但在对象更改操作过程中的名称和搞乱命令时不会出现问题。

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); 
} 

该递归解决向下钻取到叶节点和重命名他们的父母之前重命名它们。