2012-04-09 189 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); 
} 

該遞歸解決向下鑽取到葉節點和重命名他們的父母之前重命名它們。