Maya MEL Prosedyremodellering for kunstnere - UIer

Denne opplæringen er en introduksjon til å bygge grafiske brukergrensesnitt (GUI) i MEL for Maya 2010 og under. Maya 2011 introduserer en ny metode for å lage GUIer som ikke vil bli dekket her. Vi skal gå over riktig koding for brukergrensesnitt, feilhåndtering, og vi legger sammen et veldig nyttig skript som gir deg betydelig kontroll over et objekts pivotpunkt.

Brukergrensesnitt

Hvis du planlegger å gi skriptene dine til en annen artist, kan det være utrolig nyttig å sette sammen en brukervennlig GUI som gjør at koden din er tilgjengelig for ikke-programmører. I dag bruker jeg sjelden smarte hurtigtaster, istedenfor å stole på en håndfull brukergrensesnitt som jeg har bygget i MEL for å automatisere Maya-prosesser. Jeg kan bære dem med meg, og trenger ikke å endre noen preferanser for å jobbe komfortabelt på flere arbeidsstasjoner. Evnen til å opprette og vedlikeholde brukergrensesnitt er et kraftig, men noen ganger frustrerende verktøy i MEL-verktøyet.


Trinn 1

La oss se på hva vi skal skape i dag. Start med å lagre filen "EdW_PivotControl.mel" som følger med denne opplæringen til skriptkatalogen. Deretter åpner du Maya. Jeg bruker Maya 2010 i løpet av denne opplæringen, men den samme koden skal fungere for de fleste Maya-versjoner. Skriv inn følgende i kommandolinjen og trykk enter:

kilde EdW_PivotControl; EdW_PivotControl;

Steg 2

Vi burde ha et vindu åpent med noen knapper på den. Prøv å lage litt geometri og eksperimentere med skriptet. Målet er å skape et skript som gir deg kontroll over objektets svingpunkter.


Trinn 3

Legg ut hvilke prosedyrer vi trenger for å gjøre dette skriptet:

  • EdW_PivotControl - lanserer hovedprosedyren for skriptet
  • epc_pivotControl - oppretter brukergrensesnittet
  • epc_getBounds - bruk kommandoen xform for å få grenseboksen til det valgte objektet
  • epc_movePivotLocal - flytter objektets pivot til en lokal posisjon (y min, x min, etc.)
  • epc_movePivotToObject - flytter pivoten til et annet objekts sted

Jeg bruker epc_ som prefiks. Som i tidligere opplæringsprogrammer, vil du sørge for at prosedyrene dine har unike navn, for ikke å forstyrre andre skript.


Trinn 4

Vi starter vårt skript ved å åpne den gamle standbyen, Microsoft Notisblokk. Den første prosedyren er enkel:


Trinn 5

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_PivotControl.mel som filnavn, men gjerne velge hva du vil.


Trinn 6

Nå kommer vi til den harde delen. Opprette brukergrensesnitt i MEL har aldri vært en spesielt elegant prosess, så jeg vil gjøre mitt beste for å gjøre prosessen så smertefri som mulig. Noen ganger er det best å bare tegne noe ut på papiret før vi begynner å skrive ut kode, så skisser ut en grunnleggende layout for hva du vil at den endelige brukergrensesnittet skal se ut. Dette skriptet er ganske enkelt, men når du begynner å håndtere faner, menyer, rullegardiner, etc., vil du sørge for at du har en spillplan i tankene.


Trinn 7

Vi skal se på tre forskjellige typer UI-kommandoer:

  • Windows - toppnivå objekter som har standardknappene til et hvilket som helst OS-vindu, for eksempel minimere, maksimere og lukke.
  • Layouts - forskjellige måter å organisere objektene i en windows på.
  • Kontroller - knapper, glidere, tekstfelter, etc. Dette er de interaktive elementene i brukergrensesnittet.

Her er en oversikt over skissen vår i henhold til MEL-kommandoene som brukes til å lage dem:


Trinn 8

Det første trinnet for å opprette brukergrensesnittet er å etablere vinduet. Fordi vårt Window-objekt vil ha et unikt navn, kan Maya ikke ha to av samme vindu åpne på en gang. Den første delen av prosedyren vår sjekker om vinduet allerede er åpent, og lukker det hvis det er.

 // Opprett UI global proc pivotControl () ) 
hvis ('vinduet eksisterer PivotControlMain')
deleteUI PivotControlMain;
; // ...;

Trinn 9

La oss nå prøve å lage et vindu i koden og se hva som skjer:

 vindu -rtf-1 "EdW Pivot Control" -mnb 1 -mxb 1 -w 450 -h 300 PivotControlMain;
  • -resizeToFitChildren (-rtf) hvis sant, vil vinduet automatisk endre størrelse slik at det passer alle layoutene og kontrollene du lager
  • -tittel (-t) teksten som vises i tittellinjen øverst i vinduet
  • -minimizeButton (-mnb) aktiverer eller deaktiverer minimeringsknappen
  • -Maksimere knapp (-mxb) aktiverer eller deaktiverer maksimeringsknappen
  • -bredde (-w) bredde på vinduet i piksler
  • -høyde (-h) høyde på vinduet i piksler

Trinn 10

Akkurat nå har vinduet blitt opprettet inne i skriptet, men en annen kommando er nødvendig for å vise den. Denne kommandoen kommer alltid etter alle UI-kommandoene for vinduet.

 showWindow PivotControlMain;

Trinn 11

Vår fulle kode skal se slik ut:

 // Hovedfunksjon global proc EdW_PivotControl () pivotControl; ; // Opprett UI global proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "EdW Pivot Control" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; showWindow PivotControlMain; ;

Trinn 12

Kilde i den nye koden og kjør den fra Maya kommandolinjen. Dette er hva du bør få:

 kilde EdW_PivotControl; EdW_PivotControl; 

Trinn 13

Vinduet er det øverste objektet i vårt brukergrensesnitt hierarki. Alle oppsettene og kontrollene er barn av dette objektet. Det første oppsettet vi skal bruke er et kolonnelayout, for å holde knappene:

 kolonneLayout -justerbar Kolonne 1-veiSpace 0 EPC_MainColumnLayout;
  • -justerbar kolonne (-ac) vil kolonnen automatisk endre størrelsen i henhold til bredden på vinduet
  • -rowSpacing (-rs) avstanden i piksler mellom hver rad i kolonnen

Trinn 14

Jeg har funnet ut at inkludert instruksjoner eller avklaringer i brukergrensesnittet kan gjøre skriptet mer brukbart. Legg til en tekstkontroll til skriptet:

 tekst -l "Flytt pivot til:";
  • -etikett (-l) selve teksten til kontrollen


Trinn 15

Deretter vil vi legge til et oppsett for å holde knappene øverst i vinduet, for å flytte pivotene rundt. En layout vi kan bruke er gridLayout, som lager et sett med jevnt fordelte celler som inneholder ett objekt hver.

 gridLayout -cwh 60 24 -nrc 2 5;
  • -cellWidthHeight (-cwh) angir bredden og høyden til hver enkelt celle.
  • -numberOfRowsColumns (-nrc) angir antall horisontale rader og vertikale kolonner i rutenettet


Trinn 16

Hver celle i rutenettet kan inneholde en enkelt kontroll. Disse fylles automatisk når du lager objektene under oppsettet. I vårt tilfelle ønsker vi å lage ni knapper. Vi vil bruke flagg-kommandoen senere for å fortelle knappene hvilken prosedyre som skal ringes:

 knapp -l "Senter"; knapp -l "Y Min"; knapp -l "Y Max"; knapp -l "Opprinnelse"; knapp -l "Utvalgt"; knappen -l "X Min"; knapp -l "X Max"; knapp -l "Z Min"; knapp -l "Z Max";
  • -etikett (-l) teksten som vises på knappen


Trinn 17

Nå trenger vi en måte å fortelle Maya at vi er ferdige med gridLayout, og vi vil legge til flere elementer i kolonnenLayout. For å gjøre det, vil vi bruke en MEL-kommando for å sette foreldren til gridLayout.

 setParent ...;

Den ...; indikerer at du vil overordne til oppsettet ett steg opp hierarkikkjeden. Vi kan også bruke navnet på oppsettet, men dette er bare nyttig hvis alle oppsettene har eksplisitte navn:

 setParent EPC_MainColumnLayout;

Trinn 18

Vårt pivotControl-skript burde nå se slik ut:

 global proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "EdW Pivot Control" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; kolonneLayout -justerbar Kolonne 1-veiSpace 0 EPC_MainColumnLayout; tekst -l "Flytt pivot til:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; knapp -l "Senter"; knapp -l "Y Min"; knapp -l "Y Max"; knapp -l "Opprinnelse"; knapp -l "Utvalgt"; knappen -l "X Min"; knapp -l "X Max"; knapp -l "Z Min"; knapp -l "Z Max"; setParent ...; showWindow PivotControlMain; ;

Trinn 19

På samme måte som gridLayout, må columnLayout lukkes ved å sette sin forelder.

setParent ...;

Trinn 20

Kilde i skriptet og se hva du får:


Trinn 22

UI-prosedyren er ferdig!

 // Hovedfunksjon global proc EdW_PivotControl () pivotControl; ; // Opprett UI global proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "EdW Pivot Control" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; kolonneLayout -justerbar Kolonne 1-veiSpace 0 EPC_MainColumnLayout; tekst -l "Flytt pivot til:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; knapp -l "Senter"; knapp -l "Y Min"; knapp -l "Y Max"; knapp -l "Opprinnelse"; knapp -l "Utvalgt"; knappen -l "X Min"; knapp -l "X Max"; knapp -l "Z Min"; knapp -l "Z Max"; setParent ...; setParent ...; showWindow PivotControlMain; ;

Trinn 23

Nå må vi opprette koden for å flytte objektets pivotpunkt. For å gjøre det, skal vi lage to prosedyrer som vil fungere sammen:

  • epc_getBounds vil bruke en xform-kommando og en liten aritmetikk for å returnere grenseboksen minimum, maksimum og gjennomsnitt.
  • epc_movePivotLocal vil hente grenseboksinformasjonen ved hjelp av epc_getBounds for å flytte pivotposisjonene.

Trinn 24

Legg ut pseudokoden for epc_getBounds:

  • velg objektet som er gått fra epc_movePivotLocal
  • skriv resultatet av en queried xform-kommando til en matrise
  • få gjennomsnittene av x, y og z minimum og maksimum returnert fra xform
  • legg til gjennomsnittet på returarrangementet
  • returnere grenseboksen sammen med gjennomsnittene

Trinn 25

Lag skjelettet for prosedyren, komplett med en returtype og et passert argument.

 global proc float [] epc_getBounds (streng $ objSel) ;

Trinn 26

velg objektet som er bestått som et argument, og få informasjon om avgrensningsboksen.

 global proc float [] epc_getBounds (streng $ objSel) velg -r $ objSel; float $ getBoundArray [] = 'xform -q -ws -bb'; ;
  • -spørre (-q) spørre kommandoen, i stedet for å faktisk omforme noe
  • -worldspace (-ws) sørg for at
  • -boundingBox (-bb) returnerer min- og maxposisjonene til grenseboksen

Flaggen -Bounding-feltet returnerer seks verdier i en matrise: x minimum, x maksimum, y minimum, y maksimum, z minimum og z maksimum.


Trinn 27

beregne gjennomsnittene mellom minimumene og maksimumene. Husk at arrayer alltid starter med en indeks på null.

 flyte $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax pluss xmin delt med to float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax pluss ymin delt med to float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax pluss zmin dividert med to

Trinn 28

beregne gjennomsnittene mellom minimumene og maksimumene. Husk at arrayer alltid starter med en indeks på null.

 flyte $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax pluss xmin delt med to float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax pluss ymin delt med to float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax pluss zmin dividert med to

Trinn 28

Legg til de nylig beregnede gjennomsnittene og returner det endelige systemet.

 $ getBoundArray [6] = $ bbXAv; $ getBoundArray [7] = $ bbYAv; $ getBoundArray [8] = $ bbZAv; returner $ getBoundArray;

Trinn 29

Den endelige prosedyren skal se slik ut:

 global proc float [] epc_getBounds (streng $ objSel) velg -r $ objSel; float $ getBoundArray [] = 'xform -q -ws -bb'; flyte $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); flyte $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); flyte $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); $ getBoundArray [6] = $ bbXAv; $ getBoundArray [7] = $ bbYAv; $ getBoundArray [8] = $ bbZAv; returner $ getBoundArray; ;

Trinn 30

Nå kan vi sette denne koden på jobb i vår epc_movePivotLocal-prosedyre. Skriv ut pseudokoden:

  • skriv en liste over utvalgte objekter i en matrise
  • få begrensingsboksinformasjonen for hvert objekt som er valgt, ved hjelp av epc_getBounds-prosedyren
  • opprett en veske setning for å kontrollere hvor svinget skal flytte til

Trinn 31

lag skjelettet for prosedyren. Konfigurer en in-loop slik at koden utføres en gang for hvert objekt valgt i scenen.

 global proc epc_movePivotLocal (streng $ modus) string $ sel [] = 'ls -sl'; for ($ thisObj i $ sel) // kode går her; ;

Trinn 32

Bruk prosedyrens returverdi fra epc_getBounds til å skrive en float array:

 float $ pos [] = 'epc_getBounds $ thisObj';

Trinn 32

Nå bruker vi en veske-setning for å faktisk flytte pivoten rundt. Den grunnleggende strukturen til et veske er dette:

 switch ($ variable) // variabelen kan være hvilken som helst type, inkludert strenger og floats case variableValue: // hvis variabelen samsvarer med variableValue // kjøre denne kodebruken; tilfelle otherValue: // kode her break; ;

Vekselsettet er et cascading system, noe som betyr at hvis du ikke inkluderer "break" -kommandoen etter hvert tilfelle, vil resten av sakene også utføres. For vår prosedyre, vil vi legge til et veske som lar oss bruke samme fremgangsmåte for å flytte en pivot til mange forskjellige stillinger. Vår veske vil se slik ut:

 bytte ($ modus) case "center": CenterPivot $ thisObj; gå i stykker; tilfelle "ymin": flytt -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; ;

Trinn 33

Fortsett å legge tilfeller til skriptet, slik at hver av våre brukergrensesnittknapper har et tilsvarende tilfelle. Den fullstendige prosedyren bør se slik ut:

 global proc epc_movePivotLocal (streng $ modus) string $ sel [] = 'ls -sl'; for ($ thisObj i $ sel) float $ pos [] = 'epc_getBounds $ thisObj'; bytte ($ modus) case "center": CenterPivot $ thisObj; gå i stykker; tilfelle "ymin": flytt -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "ymax": flytt -a -rpr $ pos [6] $ pos [4] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "opprinnelse": flytt -a -rpr 0 0 0 ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "xmin": flytt -a -rpr $ pos [0] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "xmax": flytt -a -rpr $ pos [3] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "zmin": flytt -a -rpr $ pos [6] $ pos [7] $ pos [2] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; tilfelle "zmax": flytt -a -rpr $ pos [6] $ pos [7] $ pos [5] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); gå i stykker; ; ; ;

Trinn 33

Vår siste prosedyre følger ganske mye den samme ideen.

 global proc epc_movePivotToObject () streng $ selLast [] = 'ls -sl -tail 1'; streng $ copyToObj = $ selLast [0]; velg-velg $ copyToObj; streng $ selSet [] = 'ls -sl'; float $ pivotSel [] = 'xform -q -piv -ws $ copyToObj'; skriv ut $ pivotSel; for $ $ i $ selSet move -a $ pivotSel [0] $ pivotSel [1] $ pivotSel [2] ($ each + ".rotatePivot") ($ hver + ".scalePivot"); ; ;

Det er bare to nye flagg i denne prosedyren:

  • -hale (-tl) skriver bare det siste objektet som er valgt i gruppen (ls-kommandoen)
  • -pivot (-piv) spørrer nåværende posisjon for pivot på en objekt (xform-kommando)

Trinn 35

Nå er alt som gjenstår å få våre knapper i brukergrensesnittet faktisk å ringe til prosedyrene vi har skrevet.

 knapp -l "Senter" -c "epc_movePivotLocal senter"; knapp -l "Y Min" -c "epc_movePivotLocal ymin"; knapp -l "Y Max" -c "epc_movePivotLocal ymax"; knapp -l "Origin" -c "epc_movePivotLocal opprinnelse"; knapp -l "Utvalgt" -c "epc_movePivotToObject"; knapp -l "X Min" -c "epc_movePivotLocal xmin"; knapp -l "X Max" -c "epc_movePivotLocal xmax"; knapp -l "Z Min" -c "epc_movePivotLocal zmin"; knapp -l "Z Max" -c "epc_movePivotLocal zmax";
  • -kommando (-c) kaller en kommando eller liste over kommandoer når knappen trykkes

Trinn 35

Og vi er ferdige!