Modelarea procesuală cu scripturi MEL din Maya - Ziua 2

Acest tutorial este o introducere în utilizarea fișierelor MEL externe și a procedurilor, funcțiilor, buclelor și interacțiunii scripted în spațiul de lucru Maya. Vom trece peste practicile de codare de bază și vom pune împreună un obiect geometric care ar fi foarte dificil de creat fără scripting.


Fișiere / pluginuri suplimentare:
  • Descărcați Scriptul final

Crearea procedurilor

În acest tutorial, vom crea un fișier de script extern cu patru "proceduri" - scripturi autonome care sunt menite să atingă obiective specifice. Prima procedură va lua orice număr de obiecte selectate în fereastra de vizualizare Maya și va crea o ierarhie înlănțuită pentru transformări ușoare în două. Cel de-al doilea script va selecta obiecte selectate, iar cel de-al treilea va muta punctele pivot ale obiectelor selectate la originea spațiului mondial. Aceste trei scripturi vă vor permite să creați cu ușurință câteva efecte interesante cu obiecte multiple. A patra procedură va combina toate primele trei pentru a crea o "spirală a lui Fermat", similară cu complexul care se găsește pe capetele de floarea-soarelui.


Pasul 1

Deschideți Maya. Pentru cursul acestui tutorial, voi folosi Maya 2010, dar aceleași comenzi ar trebui să funcționeze pentru majoritatea versiunilor Maya. Începeți prin a crea un cub în centrul portului de vizualizare.


Pasul 2

Accesați "Editare> Duplicat special" și faceți clic pe caseta de opțiuni pentru a afișa acest dialog. Creați nouă copii.


Pasul 3

Mergeți la "Window> Hypergraph Ierarchy". Acum trebuie să părăsim împreună cuburile pentru a crea un "lanț". Pentru a face acest lucru, faceți clic mai întâi pe "pCube2" apoi faceți clic pe "pCube1" și apăsați "p" de pe tastatură. Acest părinți este primul obiect selectat (pCube2) celui de-al doilea (pCube1).

Continuați acest proces (selectând copilul, apoi părintele și apoi lovind "p" pentru a le alătura împreună) pentru fiecare dintre cuburile noastre. Odată terminat, fiecare obiect din mijlocul ierarhiei ar trebui să aibă un cub părinte și un copil, iar ierarhia generală ar trebui să arate astfel:


Pasul 4

Închideți fereastra "Ierarhia hipergrafiei". Selectați toate obiectele prin marcaj - glisând peste cuburile din mijlocul ferestrei de vizualizare. Apoi, păstrând toate cuburile selectate, încercați să le deplasați și să le rotiți.

Deoarece transformările fiecărui cub sunt acum relative la cub cu un pas mai sus în lanț, transformarea dublă rezultată vă permite să mutați cuburile într-un mod foarte unic - traducerile mici devin rapid schimbări mari.


Pasul 5

Cu toate cuburile încă selectate, apăsați "Shift-P" de pe tastatură pentru a nu părăsi cuburile. Am trecut prin toate etapele majore pe care vrem să le automatizăm cu scenariul nostru. Deci, începe un nou fișier Maya și deschide un editor de text. Favoritul meu personal este Notepad ++, care are chiar și un plugin de limba MEL disponibil. Simțiți-vă liber să folosiți editorul de text pe care îl preferați, dar pentru moment voi folosi vechiul Microsoft Notepad. Notepad-ul este simplu, dar se face treaba.


Pasul 6

Mergeți mai departe și salvați fișierul. Când salvați un document MEL, asigurați-vă că alegeți "Toate fișierele" sub "salvați ca tip". Salvați documentul ca fișier .mel în directorul de scripturi Maya. Voi folosi EdW_DoubleTransform.mel drept nume de fișier.


Pasul 7

Pentru a crea o procedură, trebuie să știți câteva lucruri în prealabil. În primul rând, trebuie să definiți un "domeniu" pentru procedură. Domeniul de aplicare stabilește de unde poate fi accesată o procedură. Un domeniu de aplicare "local" înseamnă că codul este accesibil numai altor proceduri din interiorul aceluiași fișier .mel. "Global" înseamnă că procedura este disponibilă pentru alte fișiere de script și pentru utilizator și este, de asemenea, încărcată în memorie. În general, folosesc o mulțime de proceduri globale. Aceasta nu este cea mai bună practică de codare absolută, dar îmi place să am procedurile mele disponibile în mai multe scenarii. În al doilea rând, trebuie să alegeți un nume pentru procedura dvs. În general, încercați să alegeți ceva unic și descriptiv - dacă procedura este globală, nu doriți ca numele să fie în conflict cu orice altă procedură din orice alt script. De obicei, lucrez la inițiere în nume, și pentru că scenariul pe care-l scriem se numește "DoubleTransform", voi merge cu "dt" în acest caz. La aceasta este cea mai de bază, aceasta este procedura pe care o construim:

 proc global dt_makeParentChain () // acțiunile scriptului;

Pasul 8

Primul lucru pe care îl vom face cu procedura noastră este definirea unei variabile care va găzdui în cele din urmă o listă de nume de obiecte. În MEL, variabilele sunt notate cu un semn de dolar ($) înainte de numele variabilei. Există mai multe tipuri diferite de date pe care o variabilă poate conține - șiruri de text, numere întregi numite numere întregi, numere zecimale în virgulă mobilă, valori vectoriale etc. Sintaxa pentru declararea unei variabile este următoarea:

 dataType $ variableName;

Pentru moment, vom face o variabilă de șir gol:

 string $ selectedObjects;

Dacă vrem, putem atribui și date variabilei în aceeași linie de cod. Citatele duble sunt folosite pentru a defini șiruri de text.

 string $ selectedObjects = "acesta este un șir de text";

un singur semnal egal înseamnă "setați variabila la". Un dublu egal înseamnă înseamnă "este egal cu" și este folosit atunci când se compară variabilele.


Pasul 9

Pentru a testa noua noastră variabilă, trebuie să adăugăm o comandă de tipărire. Aceasta va trimite un șir editorului Script când scriptul este rulat. În acest caz, pur și simplu tipărim conținutul variabilei '$ selectedObjects'.

 print $ selectedObjects;

Pasul 10

Adăugați un comentariu la noua dvs. procedură. Am tendința de a adăuga un comentariu înainte de fiecare procedură, astfel încât să le pot găsi rapid mai târziu. Unele dintre scenariile mele au zeci de proceduri, iar comentariile fac mult mai ușor procesul de depanare și schimbare a codului. Codul complet ar trebui să arate astfel:

 // Faceți lanțul parent global global proc dt_makeParentChain () string $ selectedObjects = "acesta este un șir de text"; print $ selectedObjects; ;

Pasul 11

Salvați fișierul și reveniți la Maya. Ori de câte ori pornește mai întâi Maya, scanează directorul de scripturi și încarcă o listă a tuturor fișierelor de acolo. Dacă ați adăugat un script în director în timp ce Maya este deja deschis, atunci sistemul nu știe că fișierul există. În acest caz, aveți două opțiuni, fie reporniți Maya, fie puteți folosi comanda "rehash" pentru a forța Maya să actualizeze lista de fișiere. Vom folosi a doua metodă, așa că du-te la "Fereastră> Editorii generali> Script Editor", tastați următoarele:

 rehash;

Acum, apăsați "Ctrl-Enter" pentru a rula comanda.


Pasul 12

Pentru a testa scriptul, va trebui să-l inițializați în Maya. Comanda "rehash" îi spune lui Maya că fișierul există și comanda "sursă" îi spune lui Maya să încarce scriptul în memorie. Introduceți următoarele în editorul de script:

 sursă EdW_DoubleTransform.mel;

Apoi tastați comanda pentru procedura creată în interiorul scriptului:

 dt_makeParentChain;

Aceasta este ceea ce ar trebui să obțineți în editorul de script după executarea procedurii:


Pasul 13

Acum, că am pus împreună o procedură de funcționare, să ne dăm seama de pseudocodul pentru ceea ce vrem ca procedura să facă în scriptul nostru final:

  • scrie o listă de obiecte selectate la o variabilă
  • obțineți numărul de obiecte selectate
  • părinte fiecare obiect la cel anterior din listă

Pasul 14

Pentru a obține o listă a obiectelor selectate în fereastra de vizualizare Maya, folosiți comanda list, "ls". Lista este de obicei folosită cu un steguleț care spune comenzii să apuce orice este selectat în prezent în fereastra de vizualizare maya, -sl. Încercați să selectați unele obiecte din fereastra de vizualizare Maya și tastați comanda completă (prezentată mai jos) în editorul de script, nu uitați să apăsați "Ctrl-Enter" pentru a rula comanda.

 ls -sl;

Pasul 15

Comanda de listă emite o mulțime de șiruri care reprezintă lista completă a obiectelor selectate. Pentru a face ca aceste informații să fie utile pentru noi, trebuie să scriem rezultatul comenzii "list" la o variabilă. Pentru a face acest lucru, împachetați comanda de listă în marcaje (Notă, bifați, de asemenea, numit un backquote, este situat, de obicei, deasupra tastei tabul de pe tastatură ... asigurați-vă că nu utilizați un singur cota-marcaj de lângă introduce cheia). Împachetarea unei comenzi în marcajele de marcă se traduce ca "ieșirea". Comanda noastră ar trebui să arate astfel:

 șirul $ selectObjects = 'ls -sl';

Pasul 16

Variabila $ selectedObjects este un singur șir de text. Ceea ce avem cu adevărat nevoie este ceva numit matrice de șir - o listă ordonată de șiruri care sunt conținute într-o singură variabilă. Pentru a transforma stringul într-o matrice de șir, utilizați paranteze pătrate atunci când declarați variabila:

 șirul $ selectObjects [] = 'ls -sl';

Acum, ori de câte ori ne referim la variabila, putem folosi întreaga matrice:

 $ selectedObjects // toate șirurile din matrice

... Sau un șir individual în interiorul matricei, furnizând un index - poziția șirului dorit în matrice. Valorile indexului din MEL încep întotdeauna la zero, după cum se arată mai jos:

 print $ selectedObjects [0]; // returnează primul șir din matricea printout $ selectedObjects [2]; // returnează cel de-al treilea șir din matrice

Pasul 17

De asemenea, vom avea nevoie de o modalitate de a ne da seama câte obiecte sunt în matrice. Puteți folosi comanda "dimensiune" pentru a face exact acest lucru. Să creăm o nouă variabilă pentru a stoca aceste informații. Un număr întreg este reprezentat de un număr întreg, care este întotdeauna menționat în MEL ca un "int":

 int $ numSelectedObjects = 'dimensiunea ($ selectObjects)';

Pasul 18

Acum avem nevoie de o modalitate de a părăsi fiecare obiect în funcție de locul său în matrice. Există o mulțime de moduri de a face acest lucru, dar pentru moment vom folosi o bucla de bază "pentru". For-buclele sunt comune în programare ca o modalitate de a face o acțiune de mai multe ori. Sintaxa unei for-buclă care rulează de zece ori este următoarea:

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

Structura buclă are trei părți. $ i = 0 definește o variabilă întreg, $ i

 pentru ($ i = 0; $ i < $numSelectedObjects; $i++)  //action to be performed ;

Pasul 19

Acum trebuie să folosim o comandă "părinte" pentru a crea un lanț de ierarhie. Sintaxa pentru această comandă este după cum urmează:

 copilul părinte Obiect parentObject;

Deci, în cazul nostru, comanda părinte ar fi:

 pentru ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[(i-1)] $selectedObjects[i]; ;

Pasul 20

Cu bucla noastră finalizată, trebuie să deselectăm ultimul obiect din selecție, folosind comanda "select" cu steagul "deselectați". Pentru a calcula indexul ultimului obiect selectat, luăm numărul total de obiecte și apoi, deoarece indicele oricărui matrice din Maya începe la 0, se scade 1.

 selectați-selectați $ selectedObjects [($ numSelectedObjects - 1)];

Pasul 21

Și cu asta, prima noastră procedură este acum completă:

 // Faceți lanțul părinte global proc proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'dimensiunea ($ selectObjects)'; pentru ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ;

Pasul 22

Sub "dt_makeParentChain", creați o nouă procedură pentru a nu părăsi obiectele selectate. Codul de mai jos părăsesc obiectele selectate în lume, ceea ce este același lucru cu cel al nepedepsării acestora.

 proc global dt_unParentSelected () parent -w; ;

Pasul 23

A treia procedură va automatiza procesul de mutare a punctului de pivot al unui obiect la origine. La fel ca înainte, începem prin crearea schiței procedurii:

 global proc dt_pivotToOrigin () // acțiuni de procedură;

Pasul 24

Apoi folosim aceeași tehnică ca și în prima procedură pentru a scrie o listă a obiectelor selectate unei variabile:

 șirul $ selectObjects [] = 'ls -sl';

Pasul 25

Acum trebuie să adăugăm o buclă. În timp ce am putea folosi același tip de buclă ca în primul script, să folosim o buclă pentru fiecare. O buclă "pentru fiecare" este o versiune specializată a for-buclă care se execută o dată pentru fiecare valoare într-o matrice. De asemenea, vă permite să scrieți o variabilă care reprezintă valoarea indexului curent. Sintaxa arată astfel:

 pentru ($ fiecare în $ arrayVariable) // face această acțiune cu $ each;

Variabila $ fiecare conține valoarea indexului curent al matricei. Pentru scriptul nostru, acesta ar trebui să arate după cum urmează:

 pentru ($ thisObj în $ selectObjects) // mutați pivotul $ thisObj;

Aceeași tehnică poate fi folosită pentru a automatiza orice comandă maya pentru orice număr de obiecte selectate.


Pasul 26

Folosind variabila $ thisObj putem selecta acum obiectul care este in prezent privit de bucla:

 selectați -r $ thisObj;

Pasul 27

Pentru a deplasa pivotul la origine, putem folosi comanda "xform" și resetați parametrii -rp (rotatePivot) și -sp (scalePivot) la 0 pe axele X, Y și Z:

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

Pasul 28

Principalele componente ale scriptului sunt acum terminate, iar codul dvs., care conține toate cele trei proceduri, ar trebui să arate astfel:

 // Faceți lanțul părinte global proc proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'dimensiunea ($ selectObjects)'; pentru ($ 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; ; ;

Pasul 29

Acum vom crea o a patra procedură care va folosi cele trei anterioare pentru a crea o progresie geometrică interesantă numită "Spiralul Fermat", care se bazează pe relația unghiulară a Raportului de Aur, Phi. Este o formă care se găsește în mod obișnuit în natură, urmând tot felul de reguli geometrice interesante. Să începem prin scrierea pseudocodului:

  • creați o sferă
  • creați 1.000 de exemplare
  • părinte-lanț toate sferele
  • mutați obiectele în axa x
  • mutați toate punctele pivotului sferei la origine
  • rotiți sferele în Y 137.5 grade (Anglul de Aur)

Pasul 30

Deci, ca să începem să creăm un nou procedeu:

 global proc dt_fermatSpiral () 

Pasul 31

Acum vom crea o sferă cu 8 diviziuni radiale și 8 înălțimi și vom scrie nodurile de transformare și formă care rezultă într-o matrice de șir, astfel încât să le putem urmări. Cele mai multe comenzi care creează ieșirea geometriei două șiruri - numele nodului de transformare și numele nodului de formă. În cea mai mare parte, doriți să lucrați cu șirul de noduri de transformare, care va fi stocat în indexul [0] din variabila $ seedSphere array creată mai jos:

 șirul $ seedSphere [] = 'poliSphere -sx 8 -sy 8';

Pasul 32

Acum vom crea o variabilă matrică de șir de șir:

 șirul $ allSpheres [];

Pasul 33

Apoi deschideți o buclă de buzunar care rulează de 1.000 de ori:

 pentru ($ i = 1; $ i<1000; $i++)

Pasul 34

Acum trebuie să duplicăm sfera nouă creată și să scriem transformările și nodurile rezultate într-o variabilă:

 șirul $ duplicatedSphere [] = 'duplicat';

Pasul 35

Aici, adăugăm numele nodului nostru de transformare duplicat la sfârșitul matricei $ allSpheres. Puteți utiliza comanda "dimensiune" pentru a determina cât de multe obiecte sunt deja în matrice și utilizați rezultatul ca indice pentru noua noastră valoare.

 $ allSpheres [dimensiune ($ allSpheres)] = $ duplicatedSphere [0];

Pasul 36

Aici selectăm toate sferele create și execută comanda lanțului părinte pe care am creat-o anterior:

 selectați -r $ allSpheres; dt_makeParentChain;

Pasul 37

După parcurgerea sferelor împreună, le selectăm din nou și le mutați pe toate .05 în X folosind comanda "mut":

 selectați -r $ allSpheres; mișcare 0,05 0 0;

Pasul 38

După resetarea poziției de origine folosind procedura "pivotToOrigin" creată anterior, vom selecta sferele pentru ultima oară și le vom roti la 137.5 grade în Y. Cu acest lucru, executați scriptul nostru neapărat:

 dt_pivotToOrigin; selectați -r $ allSpheres; roti 0 137,5 0; dt_unParentSelected;

Pasul 39

Și asta ne completează procedura finală. Deci, scenariul nostru complet ar trebui să arate astfel:

 // Faceți lanțul părinte global proc proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'dimensiunea ($ selectObjects)'; pentru ($ 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; ;

Pasul 40

Și cu asta am terminat! Salvați scriptul și reporniți procesul "rehash" / "source" așa cum este detaliat mai sus. Apoi introduceți următoarea comandă în editorul de scenarii Maya, apăsați "Ctrl-Enter" și așteptați câteva secunde:

 dt_fermatSpiral ();

Și acolo aveți Spiralul lui Fermat, construit în întregime folosind MEL. Încercați să jucați cu diferite unghiuri, forme și transformări în procedura finală - puteți obține tot felul de modele interesante!


Acest tutorial este Ziua 2 într-o serie - Du-te la Ziua 1.