Prozedurales Modellieren mit MEL-Skripten in Maya - Tag 2

Dieses Tutorial enthält eine Einführung in die Verwendung externer MEL-Dateien und -Prozeduren, Funktionen, Schleifen und Skriptinteraktionen innerhalb des Maya-Arbeitsbereichs. Wir werden die grundlegenden Codierverfahren durchgehen und ein geschicktes geometrisches Objekt zusammenstellen, das ohne Scripting sehr schwer zu erstellen wäre.


Zusätzliche Dateien / Plugins:
  • Laden Sie das Final Script herunter

Prozeduren erstellen

In diesem Lernprogramm erstellen wir eine externe Skriptdatei mit vier "Prozeduren" - in sich abgeschlossenen Skripts, die bestimmte Ziele erreichen sollen. Die erste Prozedur nimmt eine beliebige Anzahl von Objekten, die im Maya-Ansichtsfenster ausgewählt wurden, und erstellt eine verkettete Hierarchie für einfache Doppeltransformationen. Das zweite Skript entfernt die ausgewählten Objekte und das dritte Skript verschiebt die Drehpunkte der ausgewählten Objekte zum Ursprung des Weltraums. Mit diesen drei Skripts können Sie auf einfache Weise einige interessante Effekte mit mehreren Objekten erstellen. Beim vierten Verfahren werden alle ersten drei kombiniert, um eine "Fermat-Spirale" zu erzeugen, ähnlich wie bei den komplexen Sonnenblumenköpfen.


Schritt 1

Maya öffnen. Im Verlauf dieses Tutorials verwende ich Maya 2010, aber die gleichen Befehle sollten für die meisten Maya-Versionen funktionieren. Erstellen Sie zunächst einen Cube in der Mitte des Ansichtsfensters.


Schritt 2

Gehen Sie zu "Bearbeiten> Duplizieren" und klicken Sie auf das Optionsfeld, um dieses Dialogfeld aufzurufen. Erstellen Sie neun Exemplare.


Schritt 3

Gehen Sie zu 'Fenster> Hypergraphhierarchie'. Wir müssen jetzt die Würfel zusammenfügen, um eine "Kette" zu erstellen. Klicken Sie dazu zunächst auf "pCube2" und anschließend auf "pCube1". Klicken Sie anschließend auf der Tastatur auf "p". Dies übergibt das erste ausgewählte Objekt (pCube2) an das zweite ausgewählte Objekt (pCube1)..

Fahren Sie mit diesem Vorgang fort (Auswahl des Kindes, dann des übergeordneten Elements und anschließend 'p', um sie aneinander zu ketten) für jeden unserer Würfel. Nach der Fertigstellung sollte jedes Objekt in der Mitte der Hierarchie einen übergeordneten und einen untergeordneten Cube aufweisen, und die Gesamthierarchie sollte folgendermaßen aussehen:


Schritt 4

Schließen Sie das Fenster "Hypergraph-Hierarchie". Wählen Sie alle Objekte aus, indem Sie mit der rechten Maustaste über die Würfel in der Mitte des Ansichtsfensters ziehen. Lassen Sie dann alle Würfel ausgewählt und verschieben und drehen Sie sie.

Da die Transformationen jedes Würfels nun relativ zu dem Würfel um eine Stufe über der Kette liegen, können Sie mit Hilfe der doppelten Transformation die Würfel auf einzigartige Weise verschieben. Kleine Übersetzungen werden schnell zu großen Änderungen.


Schritt 5

Wenn alle Würfel noch ausgewählt sind, drücken Sie auf Ihrer Tastatur 'Shift-P', um die Würfel aufzuheben. Wir haben jetzt alle wichtigen Schritte durchlaufen, die wir mit unserem Skript automatisieren möchten. Starten Sie also eine neue Maya-Datei und öffnen Sie einen Texteditor. Mein persönlicher Favorit ist Notepad ++, das sogar ein MEL-Plugin zur Verfügung stellt. Fühlen Sie sich frei, den von Ihnen bevorzugten Texteditor zu verwenden, aber jetzt verwende ich den guten alten Microsoft-Editor. Notepad ist einfach, aber es wird erledigt.


Schritt 6

Speichern Sie Ihre Datei. Stellen Sie beim Speichern eines MEL-Dokuments sicher, dass Sie unter "Dateityp" "All Files" wählen. Speichern Sie Ihr Dokument als .mel-Datei in Ihrem Maya-Skriptverzeichnis. Ich verwende EdW_DoubleTransform.mel als Dateinamen.


Schritt 7

Um eine Prozedur erstellen zu können, müssen Sie vorher ein paar Dinge wissen. Zunächst müssen Sie einen "Bereich" für die Prozedur definieren. Der Bereich legt fest, von wo aus auf eine Prozedur zugegriffen werden kann. Ein "lokaler" Bereich bedeutet, dass der Code nur für andere Prozeduren in derselben .mel-Datei verfügbar ist. "Global" bedeutet, dass die Prozedur für andere Skriptdateien und den Benutzer verfügbar ist und auch in den Arbeitsspeicher geladen wird. Im Allgemeinen verwende ich viele globale Verfahren. Dies ist nicht die absolut beste Kodierungsmethode, aber ich möchte, dass meine Prozeduren für mehrere Skripts verfügbar sind. Zweitens müssen Sie einen Namen für Ihre Prozedur wählen. Versuchen Sie im Allgemeinen, etwas Einzigartiges und Beschreibendes auszuwählen. Wenn die Prozedur global ist, möchten Sie nicht, dass der Name mit einer anderen Prozedur in einem anderen Skript in Konflikt steht. Normalerweise baue ich eine Art Initialen in den Namen ein, und da das Skript, das wir schreiben, "DoubleTransform" heißt, gehe ich in diesem Fall mit "dt". Am einfachsten ist dies das Verfahren, das wir erstellen:

 globale Prozedur dt_makeParentChain () // Aktionen des Skripts;

Schritt 8

Das erste, was wir mit unserer Prozedur machen, ist das Definieren einer Variablen, die schließlich eine Liste von Objektnamen enthält. In MEL werden Variablen durch ein Dollarzeichen ($) vor dem Variablennamen gekennzeichnet. Eine Variable kann verschiedene Arten von Daten enthalten - Strings aus Text, Ganzzahlen, Ganzzahlen, Gleitkomma-Dezimalzahlen, Vektorwerte usw. Die Syntax zum Deklarieren einer Variablen lautet wie folgt:

 Datentyp $ Variablenname;

Für den Moment erstellen wir eine leere String-Variable:

 Zeichenfolge $ selectedObjects;

Wenn wir möchten, können wir der Variablen auch Daten in derselben Codezeile zuordnen. Anführungszeichen werden verwendet, um Textzeichenfolgen zu definieren.

 string $ selectedObjects = "Dies ist eine Zeichenfolge aus Text";

Ein einzelnes Gleichheitszeichen bedeutet "setze die Variable auf". Ein doppeltes Gleichheitszeichen bedeutet "ist gleich" und wird beim Vergleich von Variablen verwendet.


Schritt 9

Um unsere neue Variable zu testen, müssen wir einen Druckbefehl hinzufügen. Dadurch wird beim Ausführen des Skripts eine Zeichenfolge an den Skript-Editor ausgegeben. In diesem Fall drucken wir einfach den Inhalt der Variablen '$ selectedObjects'..

 print $ selectedObjects;

Schritt 10

Fügen Sie Ihrer neuen Prozedur einen Kommentar hinzu. Ich neige dazu, vor jeder Prozedur einen Kommentar hinzuzufügen, damit ich sie später schnell finden kann. Einige meiner Skripte haben Dutzende von Prozeduren, und Kommentare erleichtern das Debuggen und Ändern von Code. Der vollständige Code sollte jetzt so aussehen:

 // Übergeordnete Kette für globale Verarbeitung erstellen dt_makeParentChain () string $ selectedObjects = "Dies ist eine Zeichenfolge aus Text"; print $ selectedObjects; ;

Schritt 11

Speichern Sie die Datei und kehren Sie zu Maya zurück. Beim ersten Start von Maya wird das Skriptverzeichnis durchsucht und eine Liste aller Dateien geladen. Wenn Sie dem Verzeichnis ein Skript hinzugefügt haben, während Maya bereits geöffnet ist, weiß das System nicht, dass die Datei vorhanden ist. In diesem Fall haben Sie zwei Möglichkeiten, entweder Maya neu zu starten, oder Sie können den Befehl "rehash" verwenden, um Maya zu zwingen, diese Liste der Dateien zu aktualisieren. Wir verwenden die zweite Methode. Gehen Sie zu "Fenster> Allgemeine Editoren> Skripteditor" und geben Sie Folgendes ein:

 wieder waschen;

Drücken Sie nun 'Strg-Eingabe', um den Befehl auszuführen.


Schritt 12

Um Ihr Skript zu testen, müssen Sie es in Maya "initialisieren". Der Befehl "rehash" teilt Maya mit, dass die Datei existiert, und der Befehl "source" weist Maya an, das Skript in den Arbeitsspeicher zu laden. Geben Sie Folgendes in den Skripteditor ein:

 source EdW_DoubleTransform.mel;

Geben Sie dann den Befehl für die Prozedur ein, die wir im Skript erstellt haben:

 dt_makeParentChain;

Das sollten Sie nach der Ausführung der Prozedur im Skripteditor erhalten:


Schritt 13

Nun, da wir eine funktionierende Prozedur zusammengestellt haben, wollen wir den Pseudocode für das, was wir in unserem letzten Skript tun wollen, herausfinden:

  • Eine Liste der ausgewählten Objekte in eine Variable schreiben
  • Liefert die Anzahl der ausgewählten Objekte
  • übergeordnetes Objekt zu dem vorherigen Objekt in der Liste

Schritt 14

Um eine Liste der Objekte anzuzeigen, die im Maya-Ansichtsfenster ausgewählt sind, verwenden Sie den Listenbefehl "ls". Liste wird normalerweise mit einem Flag verwendet, das den Befehl anweist, das aktuell im Maya-Ansichtsfenster ausgewählte -sl zu übernehmen. Wählen Sie einige Objekte im Maya-Ansichtsfenster aus und geben Sie den vollständigen Befehl (siehe unten) im Skript-Editor ein. Denken Sie daran, die Strg-Eingabetaste zu drücken, um den Befehl auszuführen.

 ls -sl;

Schritt 15

Der Befehl list gibt eine Reihe von Zeichenfolgen aus, die die vollständige Liste der ausgewählten Objekte darstellen. Um diese Informationen für uns nützlich zu machen, müssen wir das Ergebnis des Befehls "list" in eine Variable schreiben. Um dies zu tun, hüllen Sie den Listenbefehl in Häkchen ein (Hinweis: Das Häkchen, auch Backquote genannt, befindet sich normalerweise über der Tabulatortaste der Tastatur. Verwenden Sie nicht das einfache Anführungszeichen neben dem Enter-Taste). Wenn Sie einen Befehl in Häkchen setzen, wird dies als "Ausgabe von" übersetzt. Unser Befehl sollte jetzt so aussehen:

 Zeichenfolge $ selectedObjects = 'ls -sl';

Schritt 16

Die Variable $ selectedObjects ist eine einzelne Textzeichenfolge. Was wir wirklich brauchen, ist ein String-Array - eine geordnete Liste von Strings, die in einer einzelnen Variablen enthalten sind. Um aus unserem String ein String-Array zu machen, verwenden Sie bei der Deklaration der Variablen eckige Klammern:

 Zeichenfolge $ selectedObjects [] = 'ls -sl';

Wann immer wir uns auf die Variable beziehen, können wir entweder das gesamte Array verwenden:

 $ selectedObjects // alle Strings im Array

… Oder eine einzelne Zeichenfolge innerhalb des Arrays, indem Sie einen Index angeben - die Position der gewünschten Zeichenfolge innerhalb des Arrays. Die Indexwerte in MEL beginnen immer bei Null, wie unten gezeigt:

 print $ selectedObjects [0]; // gibt den ersten String im Array zurück print $ selectedObjects [2]; // gibt den dritten String im Array zurück

Schritt 17

Wir benötigen auch einen Weg, um herauszufinden, wie viele Objekte sich im Array befinden. Sie können den Befehl "Größe" verwenden, um genau das zu tun. Erstellen Sie eine neue Variable, um diese Informationen zu speichern. Eine ganze Zahl wird durch eine ganze Zahl dargestellt, die in MEL immer als "int" bezeichnet wird:

 int $ numSelectedObjects = 'size ($ selectedObjects)';

Schritt 18

Jetzt brauchen wir einen Weg, um jedes Objekt entsprechend seiner Position im Array übergeordnet zu machen. Es gibt einige Möglichkeiten, dies zu tun, aber jetzt verwenden wir eine einfache "for" -Schleife. For-Loops werden häufig in der Programmierung verwendet, um eine Aktion mehrmals auszuführen. Die Syntax einer for-Schleife, die zehnmal ausgeführt wird, lautet wie folgt:

 für (int $ i = 0; $ i < 9; $i++) //action to be done ;

Die Schleifenstruktur besteht aus drei Teilen. $ i = 0 definiert eine ganzzahlige Variable, $ i

 für ($ i = 0; $ i < $numSelectedObjects; $i++)  //action to be performed ;

Schritt 19

Wir müssen jetzt einen übergeordneten Befehl zum Erstellen der Hierarchiekette verwenden. Die Syntax für diesen Befehl lautet wie folgt:

 parent childObject parentObject;

In unserem Fall wäre der übergeordnete Befehl also:

 für ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[(i-1)] $selectedObjects[i]; ;

Schritt 20

Wenn unsere Schleife abgeschlossen ist, müssen Sie nun das letzte Objekt in der Auswahl abwählen, indem Sie den Befehl "select" mit dem Flag "deselect" verwenden. Um den Index des zuletzt ausgewählten Objekts zu berechnen, nehmen wir die Gesamtzahl der Objekte und subtrahieren dann 1, da der Index eines Arrays in Maya bei 0 beginnt.

 select -deselect $ selectedObjects [($ numSelectedObjects - 1)] auswählen;

Schritt 21

Damit ist unser erstes Verfahren abgeschlossen:

 // Parent Chain als globale Prozedur definieren dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; für ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ;

Schritt 22

Erstellen Sie unter 'dt_makeParentChain' eine neue Prozedur, um die ausgewählten Objekte zu deaktivieren. Der folgende Code übergibt die ausgewählten Objekte der Welt, was dem Aufheben der Eliminierung der Objekte entspricht.

 globaler Prozess dt_unParentSelected () parent -w; ;

Schritt 23

Unser drittes Verfahren automatisiert den Prozess des Verschiebens eines Drehpunkts eines Objekts an den Ursprung. Wie zuvor beginnen wir mit der Erstellung der Verfahrensübersicht:

 globaler Prozess dt_pivotToOrigin () // Prozeduraktionen;

Schritt 24

Wir verwenden dann dieselbe Technik wie in der ersten Prozedur, um eine Liste der ausgewählten Objekte in eine Variable zu schreiben:

 Zeichenfolge $ selectedObjects [] = 'ls -sl';

Schritt 25

Wir müssen jetzt eine Schleife hinzufügen. Während wir die gleiche Art von for-Schleife wie im ersten Skript verwenden konnten, verwenden wir stattdessen eine for-each-Schleife. Eine "for-each" -Schleife ist eine spezielle Version der for-Schleife, die einmal für jeden Wert in einem Array ausgeführt wird. Außerdem können Sie eine Variable schreiben, die den aktuellen Indexwert darstellt. Die Syntax sieht so aus:

 for ($ each in $ arrayVariable) // diese Aktion mit $ each ausführen;

Die Variable $ each enthält den Wert des aktuellen Index des Arrays. Für unser Skript sollte der Code so aussehen:

 for ($ thisObj in $ selectedObjects) // Verschiebe den Drehpunkt von $ thisObj;

Dieselbe Technik kann verwendet werden, um jeden beliebigen Befehl für eine beliebige Anzahl von ausgewählten Objekten zu automatisieren.


Schritt 26

Mit der $ thisObj-Variablen können wir nun das Objekt auswählen, das gerade von der Schleife betrachtet wird:

 select -r $ thisObj;

Schritt 27

Um den Drehpunkt zum Ursprung zu verschieben, können Sie den Befehl "xform" verwenden und die Flags -rp (RotationsPivot) und -sp (ScalePivot) auf der X-, Y- und Z-Achse auf 0 zurücksetzen:

 xform -ws -rp 0 0 0 -sp 0 0 0;

Schritt 28

Die Hauptkomponenten des Skripts sind jetzt fertig, und Ihr Code, der alle drei Verfahren enthält, sollte folgendermaßen aussehen:

 // Parent Chain als globale Prozedur definieren dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; für ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ; // Un-Parent Objects global proc dt_unParentSelected() parent -w; ; // Move Pivot to Origin global proc dt_pivotToOrigin() string $selectedObjects[] = 'ls -sl'; for($thisObj in $selectedObjects) select -r $thisObj; xform -ws -rp 0 0 0 -sp 0 0 0; ; ;

Schritt 29

Wir werden nun ein viertes Verfahren erstellen, das die vorherigen drei verwendet, um eine interessante geometrische Entwicklung namens "Fermats Spirale" zu erstellen, die auf der Winkelbeziehung des Goldenen Verhältnisses, phi, basiert. Es ist eine Form, die häufig in der Natur vorkommt und allen möglichen interessanten geometrischen Regeln folgt. Beginnen wir mit dem Schreiben des Pseudocodes:

  • Erstellen Sie eine Kugel
  • 1.000 Exemplare erstellen
  • Alle Ketten der Elternkette
  • verschiebe die Objekte in die x-Achse
  • Verschiebe alle Drehpunkte der Kugel zum Ursprung
  • Drehen Sie die Kugeln in Y 137,5 Grad (Goldener Winkel)

Schritt 30

Erstellen wir also zunächst eine neue Prozedurgliederung:

 global proc dt_fermatSpiral () 

Schritt 31

Jetzt erstellen wir eine Kugel mit 8 radialen und 8 Höhenunterschieden und schreiben die resultierenden Transformations- und Formknoten in ein String-Array, damit wir sie nachverfolgen können. Die meisten Befehle, die Geometrie erstellen, geben zwei Zeichenketten aus - den Namen des Transformationsknotens und den Namen des Formknotens. Meistens möchten Sie mit der Transformationsknotenzeichenfolge arbeiten, die im Index [0] in der unten erstellten $ seedSphere-Array-Variablen gespeichert wird:

 Zeichenfolge $ seedSphere [] = 'polySphere -sx 8 -sy 8';

Schritt 32

Wir erstellen jetzt eine leere String-Array-Variable:

 Zeichenfolge $ allSpheres [];

Schritt 33

Dann öffnen Sie eine for-Schleife, die 1.000 mal ausgeführt wird:

 für ($ i = 1; $ i<1000; $i++)

Schritt 34

Wir müssen jetzt unsere neu erstellte Kugel duplizieren und die resultierenden Transformations- und Formknoten in eine Variable schreiben:

 Zeichenfolge $ duplicatedSphere [] = 'duplicate';

Schritt 35

Hier hängen wir den Namen unseres duplizierten Transformationsknotens an das Ende des $ allSpheres-Arrays an. Mit dem Befehl "Größe" können Sie ermitteln, wie viele Objekte sich bereits im Array befinden, und das Ergebnis als Index für unseren neuen Wert verwenden.

 $ allSpheres [Größe ($ allSpheres)] = $ duplicatedSphere [0];

Schritt 36

Hier wählen wir alle erstellten Kugeln aus und führen den zuvor erstellten übergeordneten Kettenbefehl aus:

 select -r $ allSpheres; dt_makeParentChain;

Schritt 37

Nachdem wir die Kugeln zusammengezüchtet haben, wählen wir sie erneut aus und verschieben sie alle .05 in X mit dem Befehl "move":

 select -r $ allSpheres; 0,05 0 0 bewegen;

Schritt 38

Nach dem Zurücksetzen der Ursprungsposition mit unserer zuvor erstellten "pivotToOrigin" -Prozedur wählen wir die Kugeln ein letztes Mal aus und drehen sie um 137,5 Grad in Y. Führen Sie dann unser unparentes Skript aus:

 dt_pivotToOrigin; select -r $ allSpheres; 0 137,5 0 drehen; dt_unParentSelected;

Schritt 39

Damit ist unser abschließendes Verfahren abgeschlossen. Unser vollständiges Skript sollte also so aussehen:

 // Parent Chain als globale Prozedur definieren dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; für ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ; // Un-Parent Objects global proc dt_unParentSelected() parent -w; ; // Move Pivot to Origin global proc dt_pivotToOrigin() string $selectedObjects[] = 'ls -sl'; for($thisObj in $selectedObjects) select -r $thisObj; xform -ws -rotatePivot 0 0 0 -scalePivot 0 0 0; ; ; //Create Fermat's Spiral of Spheres global proc dt_fermatSpiral() string $seedSphere[] = 'polySphere -sx 8 -sy 8'; string $allSpheres[]; for ($i=1; $i<1000; $i++) string $duplicatedSphere[] = 'duplicate'; $allSpheres[size($allSpheres)] = $duplicatedSphere[0]; ; select -r $allSpheres; dt_makeParentChain; select -r $allSpheres; move 0.05 0 0; dt_pivotToOrigin; select -r $allSpheres; rotate 0 137.5 0; dt_unParentSelected; ;

Schritt 40

Und damit sind wir fertig! Speichern Sie das Skript und führen Sie den Vorgang 'rehash' / 'source' wie oben beschrieben erneut aus. Geben Sie dann den folgenden Befehl in den Skripteditor von Maya ein, drücken Sie "Strg-Eingabetaste" und warten Sie einige Sekunden:

 dt_fermatSpiral ();

Und da gibt es Fermats Spirale, die vollständig aus MEL hergestellt wurde. Versuchen Sie, mit verschiedenen Winkeln, Formen und Transformationen im abschließenden Verfahren zu spielen - Sie können alle möglichen interessanten Muster erhalten!


Dieses Tutorial ist Tag 2 in einer Serie - Gehen Sie zu Tag 1.