Questo tutorial è un'introduzione alla costruzione di interfacce utente grafiche (GUI) in MEL per Maya 2010 e versioni successive. Maya 2011 introduce una nuova metodologia per la creazione di GUI che non saranno trattate qui. Discuteremo la corretta codifica per le interfacce utente, la gestione degli errori e creeremo uno script molto utile che ti offre un controllo considerevole sul punto di rotazione di un oggetto.
Se hai intenzione di dare i tuoi script ad un altro artista, allora può essere incredibilmente utile mettere insieme una GUI user-friendly che rende il tuo codice accessibile ai non programmatori. In questi giorni, utilizzo raramente i tasti di scelta rapida personalizzati, affidandosi invece a una manciata di interfacce utente che ho creato in MEL per automatizzare i processi di Maya. Posso portarli con me e non devo modificare alcuna preferenza per lavorare comodamente su più postazioni di lavoro. La possibilità di creare e gestire interfacce utente è uno strumento potente ma a volte frustrante nel toolkit MEL.
Diamo un'occhiata a ciò che creeremo oggi. Inizia salvando il file "EdW_PivotControl.mel" incluso con questo tutorial nella directory degli script. Quindi apri Maya. Userò Maya 2010 per la durata di questo tutorial, ma lo stesso codice dovrebbe funzionare per la maggior parte delle versioni di Maya. Digitare quanto segue nella riga di comando e premere Invio:
fonte EdW_PivotControl; EdW_PivotControl;
Dovremmo avere una finestra aperta con alcuni pulsanti su di essa. Prova a creare geometrie e sperimenta con lo script. L'obiettivo è creare uno script che ti dia il controllo immediato sui punti di pivot degli oggetti.
Definire le procedure di cui avremo bisogno per realizzare questo script:
Sto usando epc_ come prefisso. Come nei tutorial precedenti, si desidera assicurarsi che le procedure abbiano nomi univoci, in modo da non interferire con altri script.
Inizieremo il nostro script aprendo il vecchio standby, Microsoft Notepad. La prima procedura è semplice:
Salva il tuo file. Quando si salva un documento MEL, assicurarsi di selezionare "Tutti i file" sotto "salva come tipo". Salva il documento come file .mel nella directory degli script Maya. Userò EdW_PivotControl.mel come nome del mio file, ma mi sento libero di scegliere quello che ti piace.
Ora arriviamo alla parte difficile. La creazione di interfacce utente in MEL non è mai stata un processo particolarmente elegante, quindi farò del mio meglio per rendere il processo il più semplice possibile. A volte, è meglio disegnare qualcosa su carta prima di iniziare a scrivere il codice, in modo da delineare un layout di base per ciò che si desidera che l'interfaccia utente finale assomigli. Questo script è piuttosto semplice, ma quando inizi a trattare tab, menu, barre di scorrimento, ecc., Devi assicurarti di avere in mente un piano di gioco.
Stiamo andando a guardare tre diversi tipi di comandi dell'interfaccia utente:
Ecco una ripartizione del nostro schizzo in base ai comandi MEL utilizzati per crearli:
Il primo passo per creare l'interfaccia utente è stabilire la finestra. Poiché il nostro oggetto Window avrà un nome univoco, Maya non può avere due della stessa finestra aperta in una volta. La prima parte della nostra procedura controlla se la finestra è già aperta e la chiude se lo è.
// Crea UI global proc pivotControl ()
if ('window -exists PivotControlMain')
deleteUI PivotControlMain;
; // ...;
Ora proviamo a creare una finestra nel codice e vediamo cosa succede:
window -rtf 1 -t "EdW Pivot Control" -mnb 1 -mxb 1 -w 450 -h 300 PivotControlMain;
In questo momento, la finestra è stata creata all'interno dello script, ma è necessario un altro comando per mostrarlo. Questo comando verrà sempre dopo tutti i comandi dell'interfaccia utente per la finestra.
showWindow PivotControlMain;
Il nostro codice completo dovrebbe assomigliare a questo:
// Main Function global proc EdW_PivotControl () pivotControl; ; // Crea l'UI globale 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; ;
Fonte nel nuovo codice ed eseguilo dalla riga di comando di Maya. Questo è ciò che dovresti ottenere:
fonte EdW_PivotControl; EdW_PivotControl;
La finestra è l'oggetto più in alto nella nostra gerarchia dell'interfaccia utente. Tutti i layout e i controlli sono figli di questo oggetto. Il primo layout che useremo è un layout di colonna, per contenere i pulsanti:
columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout;
Ho scoperto che includere alcune istruzioni o chiarimenti all'interno dell'interfaccia utente può rendere lo script più utilizzabile. Aggiungi un controllo di testo allo script:
text -l "Move Pivot To:";
Successivamente, vogliamo aggiungere un layout per contenere i pulsanti nella parte superiore della finestra, per spostare i perni. Un layout che possiamo usare è gridLayout, che crea un insieme di celle equidistanti che contengono un oggetto ciascuna.
gridLayout -cwh 60 24 -nrc 2 5;
Ogni cella nella griglia può contenere un singolo controllo. Questi vengono riempiti automaticamente quando si creano gli oggetti sotto il layout. Nel nostro caso, vogliamo creare nove pulsanti. Utilizzeremo la flag -command in un secondo momento per indicare ai pulsanti quale procedura chiamare:
pulsante -l "Centro"; pulsante -l "Y Min"; pulsante -l "Y Max"; pulsante -l "Origine"; pulsante -l "Selezionato"; pulsante -l "X Min"; pulsante -l "X Max"; pulsante -l "Z Min"; pulsante -l "Z Max";
Ora, abbiamo bisogno di un modo per dire a Maya che abbiamo finito con gridLayout, e vogliamo aggiungere più elementi alla colonnaLayout. Per fare ciò, useremo un comando MEL per impostare il genitore del gridLayout.
setParent ...;
Il… ; indica che si desidera eseguire il padre del layout con un gradino verso l'alto della catena gerarchica. Potremmo anche usare il nome del layout, ma questo è utile solo se tutti i layout hanno nomi espliciti:
setParent EPC_MainColumnLayout;
Il nostro script pivotControl dovrebbe ora assomigliare a questo:
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; columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout; text -l "Move Pivot To:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; pulsante -l "Centro"; pulsante -l "Y Min"; pulsante -l "Y Max"; pulsante -l "Origine"; pulsante -l "Selezionato"; pulsante -l "X Min"; pulsante -l "X Max"; pulsante -l "Z Min"; pulsante -l "Z Max"; setParent ...; showWindow PivotControlMain; ;
Proprio come il gridLayout, il columnLayout deve essere chiuso impostando il suo parent.
setParent ...;
Fonte nella sceneggiatura e vedi cosa ottieni:
La procedura dell'interfaccia utente è stata completata!
// Main Function global proc EdW_PivotControl () pivotControl; ; // Crea l'UI globale proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "EdW Pivot Control" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout; text -l "Move Pivot To:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; pulsante -l "Centro"; pulsante -l "Y Min"; pulsante -l "Y Max"; pulsante -l "Origine"; pulsante -l "Selezionato"; pulsante -l "X Min"; pulsante -l "X Max"; pulsante -l "Z Min"; pulsante -l "Z Max"; setParent ...; setParent ...; showWindow PivotControlMain; ;
Ora dobbiamo creare il codice per spostare effettivamente il punto di rotazione di un oggetto. Per fare ciò, creeremo due procedure che funzioneranno insieme:
Disporre lo pseudo-codice per epc_getBounds:
creare lo scheletro per la procedura, completo di un tipo restituito e un argomento passato.
global proc float [] epc_getBounds (string $ objSel) ;
seleziona l'oggetto passato come argomento e ottieni le informazioni sul riquadro di delimitazione.
global proc float [] epc_getBounds (string $ objSel) select -r $ objSel; float $ getBoundArray [] = 'xform -q -ws -bb'; ;
Il flag -boundingBox restituisce sei valori in un array: x minimo, x massimo, y minimo, y massimo, z minimo e z massimo.
calcolare le medie tra il minimo e il massimo. Ricorda che gli array iniziano sempre con un indice pari a zero.
float $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax plus xmin diviso per due float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax plus ymin diviso per due float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax plus zmin diviso per due
calcolare le medie tra il minimo e il massimo. Ricorda che gli array iniziano sempre con un indice pari a zero.
float $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax plus xmin diviso per due float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax plus ymin diviso per due float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax plus zmin diviso per due
Aggiungere le medie calcolate di recente e restituire l'array finale.
$ getBoundArray [6] = $ bbXAv; $ getBoundArray [7] = $ bbYAv; $ getBoundArray [8] = $ bbZAv; return $ getBoundArray;
La procedura finale dovrebbe assomigliare a questa:
global proc float [] epc_getBounds (string $ objSel) select -r $ objSel; float $ getBoundArray [] = 'xform -q -ws -bb'; float $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); $ getBoundArray [6] = $ bbXAv; $ getBoundArray [7] = $ bbYAv; $ getBoundArray [8] = $ bbZAv; return $ getBoundArray; ;
Ora possiamo far funzionare questo codice all'interno della nostra procedura epc_movePivotLocal. Scrivi lo pseudo-codice:
crea lo scheletro per la procedura. Imposta un ciclo for-in in modo che il codice venga eseguito una volta per ogni oggetto selezionato nella scena.
global proc epc_movePivotLocal (stringa $ mode) string $ sel [] = 'ls -sl'; for ($ thisObj in $ sel) // code goes here; ;
Utilizzare la procedura valore di ritorno da epc_getBounds per scrivere un array float:
float $ pos [] = 'epc_getBounds $ thisObj';
Ora, useremo un'istruzione switch-case per spostare effettivamente il pivot. La struttura di base di un caso di commutazione è questa:
switch ($ variable) // la variabile può essere di qualsiasi tipo, inclusi stringhe e float caso variabileValore: // se la variabile corrisponde a variabileValore // esegue questa interruzione di codice; caso altroValore: // codice qui break; ;
L'istruzione switch-case è un sistema a cascata, il che significa che se non si include il comando "break" dopo ogni caso, verrà eseguito anche il resto dei casi. Per la nostra procedura, vogliamo aggiungere un interruttore che consentirà di utilizzare la stessa procedura per spostare un pivot in molte posizioni diverse. La nostra centralina sarà simile a questa:
switch ($ mode) case "center": CenterPivot $ thisObj; rompere; case "ymin": move -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; ;
Continua ad aggiungere casi allo script, in modo che ciascuno dei nostri pulsanti dell'interfaccia utente abbia un caso corrispondente. La procedura completa dovrebbe assomigliare a questa:
global proc epc_movePivotLocal (stringa $ mode) string $ sel [] = 'ls -sl'; for ($ thisObj in $ sel) float $ pos [] = 'epc_getBounds $ thisObj'; switch ($ mode) case "center": CenterPivot $ thisObj; rompere; case "ymin": move -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; case "ymax": move -a -rpr $ pos [6] $ pos [4] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; caso "origine": move -a -rpr 0 0 0 ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; case "xmin": move -a -rpr $ pos [0] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; case "xmax": move -a -rpr $ pos [3] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; caso "zmin": move -a -rpr $ pos [6] $ pos [7] $ pos [2] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; caso "zmax": move -a -rpr $ pos [6] $ pos [7] $ pos [5] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); rompere; ; ; ;
La nostra ultima procedura segue praticamente la stessa idea.
global proc epc_movePivotToObject () string $ selLast [] = 'ls -sl -tail 1'; stringa $ copyToObj = $ selLast [0]; seleziona -deselect $ copyToObj; string $ selSet [] = 'ls -sl'; float $ pivotSel [] = 'xform -q -piv -ws $ copyToObj'; stampa $ pivotSel; for ($ each in $ selSet) move -a $ pivotSel [0] $ pivotSel [1] $ pivotSel [2] ($ each + ".rotatePivot") ($ each + ".scalePivot"); ; ;
Ci sono solo due nuovi flag in questa procedura:
Ora non resta che rendere i nostri pulsanti nell'interfaccia utente effettivamente chiamate le procedure che abbiamo scritto.
pulsante -l "Centro" -c "epc_movePivotCentro locale"; pulsante -l "Y Min" -c "epc_movePivotLocal ymin"; pulsante -l "Y Max" -c "epc_movePivotLocal ymax"; button -l "Origin" -c "epc_movePivotLocal origin"; button -l "Selected" -c "epc_movePivotToObject"; button -l "X Min" -c "epc_movePivotLocal xmin"; button -l "X Max" -c "epc_movePivotLocal xmax"; pulsante -l "Z Min" -c "epc_movePivotLocal zmin"; pulsante -l "Z Max" -c "epc_movePivotLocal zmax";
E abbiamo finito!