2012-04-09 17 views
3

Ich schreibe ein MEL-Skript, das alle Gelenke in einer gemeinsamen Hierarchie in ein bekanntes Format umbenennen wird. Die Idee ist, dass Sie den Hip-Joint auswählen würden und das Script die Hips umbenennen und jeden anderen Joint durchlaufen und ihn basierend auf seiner Position in der Hierarchie umbenennen würde.MEL: Traverse durch Hierarchie

Wie können Sie eine gemeinsame Hierarchie in MEL durchlaufen?

Antwort

4

Wenn Sie $stat_element den Namen Ihres obersten Gelenks in der Hierarchie zuweisen und den folgenden Code ausführen, fügt er allen untergeordneten Elementen dieses Gelenks das Präfix "myPrefix_" hinzu.

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

this helps

+0

Wenn einige Namen nicht eindeutig sind, gibt ls den kürzesten eindeutigen Pfad zurück - z. B. left_hip | knee. Wenn du Knie mit "fred_" sagst, erhältst du fred_knee nicht. Es wird versuchen, fred_left_hip | knee zu geben, aber das wird ein Fehler sein. // Kein Objekt stimmt mit name überein // –

0

Wenn Sie detaillierte Entscheidungen zu treffen, wie Sie gehen, statt Bulk-Umbenennung, die Hierarchie durchlaufen ist ziemlich einfach. Der Befehl ist 'listRelatives'; Mit dem 'c' Flag gibt es Kinder eines Knotens zurück und mit dem 'p' Flag gibt es den Eltern zurück. (Beachten Sie, dass -p eine einzelne Objekte zurückgibt, -c ein Array zurückgibt)

Joint1 
    Joint2 
     Joint3 
     Joint4 

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

Der schwierige Bit der Umbenennung ist, da maya nicht immer geben Sie den Namen, den Sie erwarten (es wird nicht zulassen, doppelte Namen an die gleiche Ebene der Hierarchie). Sie müssen die umbenannten Objekte verfolgen, sonst können Sie sie nach der Umbenennung nicht finden, falls die neuen Namen nicht Ihren Erwartungen entsprechen.

Wenn Sie sie verfolgen müssen, können Sie vor dem Umbenennen einen Satz mit dem Befehl set erstellen; Egal, was aus den Namen wird, alle Objekte sind immer noch im Set. Alternativ können Sie die Hierarchie durchlaufen, indem Sie Objekte auswählen und die aktuelle Auswahl umbenennen. Dadurch werden die Änderungen nicht aufgezeichnet, aber Sie haben keine Probleme mit Objekten, die während der Operation Namen ändern und Ihre Befehle durcheinander bringen.

0

Es kann unordentlich sein, dies in MEL zu tun, wenn Sie nicht eindeutige Namen haben, weil das Handle, das Sie für das Objekt haben, der Name selbst ist. Sobald Sie ein Elternelement eines Knotens mit einem nicht eindeutigen Namen umbenennen, unterscheidet sich der Name des Kindes. Wenn Sie die Liste aller Namen vor dem Umbenennen gespeichert haben, erhalten Sie Fehler, da der Umbenennungsbefehl versucht, Knoten umzubenennen, die nicht vorhanden sind. Es gibt 2 Lösungen, die ich mit MEL kenne. Aber zuerst, hier ist die pyMel-Lösung, die viel einfacher ist und ich empfehle Ihnen, sie zu verwenden.

PyMel Lösung:

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]) 

Als pm.ls gibt eine Liste der realen Objekte, und nicht nur die Namen, können Sie sicher einen übergeordneten Knoten umbenennen und haben noch einen gültigen Handle auf seine Kinder.

Wenn Sie es wirklich in MEL machen wollen, müssen Sie entweder von unten nach oben umbenennen, oder recurse, so dass Sie nicht nach den Namen der Kinder fragen, bevor Sie sich mit dem Elternteil beschäftigen.

Die erste MEL-Lösung besteht darin, eine Liste langer Objektnamen zu erhalten und sie nach ihrer Tiefe zu sortieren, der tiefsten zuerst. Auf diese Weise wird garantiert, dass ein Elternteil nie vor seinen Kindern umbenannt wird. Das Sortierbit ist zu verschachtelt, um hier gestört zu werden, und die rekursive Lösung ist sowieso besser.

rekursive MEL Lösung:

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

Diese rekursive Lösung Bohrer bis zu den Blattknoten und benennt sie vor ihren Eltern umbenennen.