Prosedyremodellering med MEL-skript i Maya - Dag 2

Denne opplæringen er en introduksjon til bruk av eksterne MEL-filer og prosedyrer, funksjoner, looper og scripted interaksjon i Maya-arbeidsområdet. Vi skal gå over grunnleggende kodingspraksis, og sette sammen et greit geometrisk objekt som ville være svært vanskelig å lage uten skripting.


Ekstra filer / plugins:
  • Last ned sluttskriptet

Opprette prosedyrer

I denne opplæringen oppretter vi en ekstern skriptfil med fire "prosedyrer" - selvstendige skript som er ment å oppnå bestemte mål. Den første prosedyren tar et hvilket som helst antall objekter som er valgt i Maya-visningsporten og oppretter et kjedet hierarki for enkle dobbelttransformasjoner. Det andre skriptet vil ikke-forordne utvalgte objekter, og det tredje vil flytte pivotpunktene til utvalgte objekter til verdensroms opprinnelse. Disse tre skriptene lar deg enkelt lage noen interessante effekter med flere objekter. Den fjerde prosedyren vil kombinere alle de tre første til å lage en 'Fermat's Spiral', som ligner på komplekse whorl funnet på solsikkehoder.


Trinn 1

Åpne Maya. I løpet av denne opplæringen bruker jeg Maya 2010, men de samme kommandoene skal fungere for de fleste versjoner av Maya. Start med å lage en terning i midten av visningsporten.


Steg 2

Gå til "Rediger> Kopier spesielle" og klikk på alternativboksen for å få frem denne dialogboksen. Lag ni eksemplarer.


Trinn 3

Gå til 'Vindue> Hypergraph hierarki'. Vi må nå forberede kubene sammen for å skape en "kjede". For å gjøre dette, klikker du først på 'pCube2' og deretter klikker du 'pCube1', og klikker 'p' på tastaturet. Dette foreldrene det første valgte objektet (pCube2) til det andre valgte (pCube1).

Fortsett denne prosessen (velg barnet, deretter foreldrene og deretter treffer 'p' for å kjede dem sammen, for hver av våre kuber. Når du er ferdig, skal hvert objekt i midten av hierarkiet ha en foreldre og en barnekube, og det overordnede hierarkiet skal se slik ut:


Trinn 4

Lukk vinduet "Hypergraph Hierarchy". Velg alle objektene ved å markere - dra over kubene i midten av visningsporten. Deretter holder alle kubene valgt, prøver å bevege seg og rotere dem.

Fordi hver kubes transformasjoner nå er i forhold til kuben ett trinn over i kjeden, gir den resulterende dobbelttransformasjonen deg muligheten til å flytte kubene på en svært unik måte - små oversettelser blir raskt store endringer.


Trinn 5

Med alle de kuber som fremdeles er valgt, treffer du 'Shift-P' på tastaturet til un-parent kubene. Vi har nå gått gjennom alle de store trinnene som vi ønsker å automatisere med vårt skript. Så start en ny Maya-fil, og åpne en tekstredigerer. Min personlige favoritt er Notepad ++, som til og med har et MEL språk plugin tilgjengelig. Ta gjerne med det som helst tekstredigeringsprogram du foretrekker, men for nå skal jeg bruke god, gammel Microsoft Notisblokk. Notisblokk er enkelt, men det blir jobben gjort.


Trinn 6

Gå videre og lagre filen din. Når du lagrer et MEL-dokument, må du sørge for å velge "Alle filer" under "Lagre som type". Lagre dokumentet som en .mel-fil i mappen Maya-skript. Jeg bruker EdW_DoubleTransform.mel som filnavn.


Trinn 7

For å opprette en prosedyre må du vite et par ting på forhånd. Først må du definere et "omfang" for prosedyren. Omfanget etablerer hvor en prosedyre kan nås fra. Et "lokalt" omfang betyr at koden bare er tilgjengelig for andre prosedyrer innenfor samme .mel-fil. "Global" betyr at prosedyren er tilgjengelig for andre skriptfiler og brukeren, og er også lastet inn i minnet. Generelt bruker jeg mange globale prosedyrer. Dette er ikke den absolutt beste kodingspraksis, men jeg liker å ha prosedyrene mine tilgjengelige på flere skript. For det andre må du velge et navn for prosedyren din. Generelt, prøv å velge noe unikt og beskrivende - hvis prosedyren er global, vil du ikke at navnet skal være i konflikt med noen annen prosedyre i et annet skript. Jeg jobber vanligvis med noen form for initialer i navnet, og fordi skriptet vi skriver kalles "DoubleTransform", vil jeg gå med "dt" i dette tilfellet. På det mest grunnleggende er dette prosedyren vi bygger:

 global proc dt_makeParentChain () // handlinger av skriptet;

Trinn 8

Det første vi gjør med prosedyren vår er å definere en variabel som til slutt vil gi en liste over objektnavn. I MEL angis variabler med et dollar-tegn ($) før variabelenavnet. Det finnes flere forskjellige typer data som en variabel kan inneholde - tekststrenger, hele tall som kalles heltall, flytende punkt desimaltall, vektorverdier etc. Syntaxen for å erklære en variabel er dette:

 dataType $ variableName;

For nå lager vi en tom strengvariabel:

 streng $ selectedObjects;

Hvis vi vil, kan vi også tildele data til variabelen i samme linje med kode. Doble sitater brukes til å definere tekststrenger.

 string $ selectedObjects = "dette er en streng med tekst";

et enkelt like-tegn betyr "sette variabelen til". Et dobbelt like-tegn betyr "er lik", og brukes når man sammenligner variabler.


Trinn 9

For å teste vår nye variabel, må vi legge til en utskriftskommando. Dette vil sende en streng til Script Editor når skriptet kjøres. I dette tilfellet skriver vi bare innholdet i variabelen '$ selectedObjects'.

 skriv ut $ selectedObjects;

Trinn 10

Legg til en kommentar til den nye prosedyren din. Jeg pleier å legge til en kommentar før hver prosedyre, slik at jeg raskt kan finne dem senere. Noen av mine skript har dusinvis av prosedyrer, og kommentarer gjør prosessen med feilsøking og endring av kode mye enklere. Den fulle koden skal nå se slik ut:

 // Gjør Parent Chain Global proc dt_makeParentChain () string $ selectedObjects = "dette er en streng med tekst"; skriv ut $ selectedObjects; ;

Trinn 11

Lagre filen og gå tilbake til Maya. Når Maya først starter opp, skanner det skriptkatalogen og laster en liste over alle filene der. Hvis du har lagt til et skript i katalogen mens Maya allerede er åpent, vet systemet ikke at filen eksisterer. I dette tilfellet har du to alternativer, enten du starter Maya på nytt, eller du kan bruke kommandoen "rehash" for å tvinge Maya til å oppdatere den listen over filer. Vi bruker den andre metoden, så gå til "Vindu> Generelle redaktører> Skripteditor", skriv inn følgende:

 rehash;

Klikk nå 'Ctrl-Enter' for å kjøre kommandoen.


Trinn 12

For å teste ut skriptet ditt, må du "initialisere" det i Maya. Kommandoen "rehash" forteller kanskje at filen eksisterer, og "kilde" -kommandoen forteller Maya å laste skriptet i minnet. Skriv inn følgende i skripteditoren:

 kilde EdW_DoubleTransform.mel;

Skriv deretter kommandoen for prosedyren vi opprettet inne i skriptet:

 dt_makeParentChain;

Dette er hva du bør få i skripteditoren etter å ha utført prosedyren:


Trinn 13

Nå som vi har satt sammen en fungerende prosedyre, la oss finne ut pseudokoden for hva vi vil ha den prosedyren å gjøre i vårt siste skript:

  • skriv en liste over utvalgte objekter til en variabel
  • få antall utvalgte objekter
  • forelder hvert objekt til den forrige i listen

Trinn 14

For å få en liste over objektene som er valgt i Maya-visningsporten, bruk listekommandoen, "ls". Liste brukes vanligvis med et flagg som forteller kommandoen å ta tak i det som nå er valgt i maya-visningsporten, -sl. Prøv å velge noen objekter i maya-visningsporten, og skriv inn full kommando (vist nedenfor) i skripteditoren, husk å trykke 'Ctrl-Enter' for å kjøre kommandoen.

 ls -sl;

Trinn 15

Listen kommandoen gir ut en mengde strenger som representerer hele listen over utvalgte objekter. For å gjøre denne informasjonen nyttig for oss, må vi skrive resultatet av "listekommandoen" til en variabel. For å gjøre dette, sett inn listekommandoen i tick-merkene (Merk, tick-markeringen, også kalt en backquote, ligger vanligvis over tabulatortasten på tastaturet ... pass på at du ikke bruker single quote-merket ved siden av skriv inn nøkkel). Wrapping en kommando i tick-merker oversettes som "utgangen av". Vår kommando bør nå se slik ut:

 streng $ selectedObjects = 'ls -sl';

Trinn 16

Variabel $ selectedObjects er en enkelt tekststreng. Det vi virkelig trenger er noe som kalles en strengoppstilling - en ordnet liste over strenger som finnes i en enkelt variabel. For å lage vår streng i en strengrekkefølge, bruk firkantede parenteser når deklarerer variabelen:

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

Nå, når vi refererer til variabelen, kan vi enten bruke hele oppstillingen:

 $ selectedObjects // alle strengene i arrayet

... Eller en individuell streng inne i arrayet ved å levere en indeks - posisjonen til strengen vi vil ha innenfor selve arrayet. Indeksverdiene i MEL starter alltid med null som vist nedenfor:

 skriv ut $ selectedObjects [0]; // returnerer den første strengen i array utskriften $ selectedObjects [2]; // returnerer den tredje strengen i matrisen

Trinn 17

Vi vil også trenge en måte å finne ut hvor mange objekter er i gruppen. Du kan bruke kommandoen "størrelse" til å gjøre nettopp det. La oss lage en ny variabel for å lagre denne informasjonen. Et helt tall representeres av et heltall, som alltid refereres til i MEL som en "int":

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

Trinn 18

Nå trenger vi en måte å foreldre hvert objekt etter sin plass i matrisen. Det er en rekke måter å gjøre dette på, men for nå bruker vi en grunnleggende "for" -løkke. For-loops er vanlige i programmering som en måte å gjøre en handling flere ganger på. Syntaxen til en for-loop som går ti ganger er dette:

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

Sløyfestrukturen har tre deler. $ i = 0 definerer en heltallvariabel, $ i

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

Trinn 19

Vi trenger nå å bruke en "overordnet" -kommando for å lage hierarkikkjeden. Syntaxen for denne kommandoen er som følger:

 foreldrebarnObject parentObject;

Så i vårt tilfelle vil overordnet kommandoen være:

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

Trinn 20

Med vår sløyfe fullført, må vi avvelge det siste objektet i valget, ved å bruke kommandoen "velg" med "avmarker" -flagget. For å beregne indeksen for det siste objektet som er valgt, tar vi det totale antall objekter, og da indeksen for en hvilken som helst gruppe i Maya begynner med 0, trekker 1.

 velg-velg $ selectedObjects [($ numSelectedObjects - 1)];

Trinn 21

Og med det er vår første prosedyre nå fullført:

 // Gjør Parent Chain global proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; for ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ;

Trinn 22

Under "dt_makeParentChain", opprett en ny prosedyre for å deaktivere de valgte objekter. Koden nedenfor forelder de valgte objektene til verden, noe som er det samme som for foreldre.

 global proc dt_unParentSelected () foreldre -w; ;

Trinn 23

Vår tredje prosedyre vil automatisere prosessen med å flytte et objekts pivotpunkt til opprinnelsen. Akkurat som før begynner vi med å opprette prosedyren:

 global proc dt_pivotToOrigin () // prosedyrehandlinger;

Trinn 24

Vi bruker deretter den samme teknikken som i den første prosedyren til å skrive en liste over de valgte objektene til en variabel:

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

Trinn 25

Vi må nå legge til en løkke. Mens vi kunne bruke samme type for-loop som i det første skriptet, la oss bruke en for-hver-loop i stedet. En "for-hver" -sløyfe er en spesialisert versjon av for-loop som utfører en gang for hver verdi i en matrise. Det lar deg også skrive en variabel som representerer gjeldende indeks verdi. Syntaxen ser slik ut:

 for ($ hver i $ arrayVariable) // gjør denne handlingen med $ each;

$ Hver variabel inneholder verdien av den nåværende indeksen for arrayet. For vårt skript, dette er hva koden skal se ut som:

 for ($ thisObj i $ selectedObjects) // flytt pivoten til $ thisObj;

Denne samme teknikken kan brukes til å automatisere en maya-kommando for et hvilket som helst antall utvalgte objekter.


Trinn 26

Ved å bruke variabelen $ thisObj kan vi nå velge objektet som nå blir sett på ved sløyfen:

 velg -r $ thisObj;

Trinn 27

For å flytte pivoten til opprinnelsen kan vi bruke kommandoen "xform" og tilbakestille flaggene -rp (rotatePivot) og -sp (scalePivot) til 0 på X-, Y- og Z-aksen:

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

Trinn 28

Hovedkomponentene i skriptet er nå ferdig, og koden din, som inneholder alle tre prosedyrene, bør se slik ut:

 // Gjør Parent Chain global proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; for ($ 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; ; ;

Trinn 29

Vi skal nå lage en fjerde prosedyre som vil bruke de forrige tre til å skape en interessant geometrisk progresjon kalt "Fermat's Spiral", som er basert på det vinkelformede forholdet mellom Golden Ratio, phi. Det er en form som ofte finnes i naturen, og følger alle slags interessante geometriske regler. La oss starte med å skrive ut pseudokoden:

  • skape en sfære
  • lag 1000 eksemplarer
  • foreldre-kjeden alle kulene
  • flytt objektene i x-aksen
  • flytt alle sfærens svingpunkter til opprinnelsen
  • roter sfærene i y 137,5 grader (den gyldne vinkelen)

Trinn 30

Så til å begynne med la oss lage en ny prosedyre disposisjon:

 global proc dt_fermatSpiral () 

Trinn 31

Nå skal vi lage en sfære med 8 radial og 8 høydedivisjoner, og skriv de resulterende transformasjonene og formknutene til en strengmatrise slik at vi kan holde styr på dem. De fleste kommandoer som lager geometri, produserer to strenger - navnet på transformasjonsnoden, og navnet på formenoden. For det meste vil du arbeide med transformasjonsnøkkelstrengen, som vil bli lagret i [0] indeksen i $ seedSphere array-variabelen som er opprettet nedenfor:

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

Trinn 32

Vi skal nå lage en tom streng-variabel:

 streng $ allSpheres [];

Trinn 33

Åpne deretter en forløp som løper 1000 ganger:

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

Trinn 34

Vi trenger nå å duplisere vår nyopprettede sfære, og skriv de resulterende transformasjonene og formknutene til en variabel:

 streng $ duplicatedSphere [] = 'duplicate';

Trinn 35

Her legger vi navnet på vår dupliserte transformasjonskode til slutten av $ allSpheres-arrayet. Du kan bruke kommandoen "størrelse" til å bestemme hvor mange objekter som allerede er i arrayet, og bruk resultatet som indeksen for vår nye verdi.

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

Trinn 36

Her velger vi alle de opprettede sfærene og kjører kommandoen for overordnet kjede som vi tidligere har opprettet:

 velg -r $ allSpheres; dt_makeParentChain;

Trinn 37

Etter å ha foreldret sfærene sammen, velger vi dem igjen og flytter dem alle .05 i X ved hjelp av "move" -kommandoen:

 velg -r $ allSpheres; flytte 0,05 0 0;

Trinn 38

Etter å ha tilbakestilt opprinnelsesposisjonen ved hjelp av vår tidligere opprettede "pivotToOrigin" -prosedyre, velger vi sfærene en sluttid, og roterer dem 137,5 grader i Y. Med det som er gjort, kjør vårt unparent script:

 dt_pivotToOrigin; velg -r $ allSpheres; roter 0 137,5 0; dt_unParentSelected;

Trinn 39

Og det fullfører vår endelige prosedyre. Så, vårt fulle skript burde se slik ut:

 // Gjør Parent Chain global proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'size ($ selectedObjects)'; for ($ 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; ;

Trinn 40

Og med det er vi ferdige! Lagre skriptet, og kjør kjøreprosessen 'rehash' / 'source' som beskrevet ovenfor. Skriv deretter inn følgende kommando i Mayas skripteditor, trykk 'Ctrl-Enter' og vent noen sekunder:

 dt_fermatSpiral ();

Og der har du Fermat's Spiral, konstruert helt med MEL. Prøv å spille med forskjellige vinkler, former og transformasjoner i den endelige prosedyren - du kan få alle slags interessante mønstre!


Denne opplæringen er Dag 2 i en serie - Gå til Dag 1.