In questo tutorial spiegherò come creare un'interfaccia che permetta di interagire con Maya.
Per creare le interfacce con Maya bisogna utilizzare una serie di comandi MEL, che vanno sotto il nome di ELF (extension layer framework). ELF permette di creare finestre, bottoni, slider, e tutto ciò che serve per creare un'interfaccia.
Faccio notare che i comandi ELF sono cross-platform, quindi lo stesso script per creare una finestra funzionerà con Maya sotto qualsiasi OS, anche se ovviamente darà un output visualmente diverso a seconda dell'OS utilizzato.
Una nota personale: creare le interfacce in Maya può diventare un processo piuttosto lungo. Prima di imbarcarvi a creare una cosa complicatissima conviene sempre pensare se effettivamente un'interfaccia per il vostro script sia utile o se forse facendo le cose a mano si perda meno tempo!

Benissimo, cominciamo forse con il comando più importante di ELF: window
Questo comando crea una finestra, ad es.:

$win = `window -t "Titolo della finestra" -w 600 -h 400`;
showWindow $win;

creerà una finestra 600x400 con titolo "Titolo della finestra". La funzione window, così come tutte le varie funzioni che creano i componenti di un'interfaccia (bottoni, edit box, sliders etc etc), restituisce un valore che essenzialmente è una stringa che identifica la finestra. E` buona norma salvare questo valore in una variabile, così nel momento in cui volessimo andare a modificare quel particolare componente ne conosceremo già il nome e questo ci semplificherà molto la vita!
Il comando showWindow usato nella seconda riga serve per mostrare la finestra, che altrimenti non sarebbe visualizzata.
E` anche possibile specificare il nome che vogliamo dare alla finestra ad es:

window -t "Titolo della finestra" -w 600 -h 400 Prova;
showWindow Prova;

In questo modo quando vorremo riferirci a quella finestra ci basterà usare Prova.
Nota: Maya tiene in memoria la posizione e la dimensione delle finestre durante ciascuna sessione di lavoro. Se provate a cambiare il codice di sopra e creare ad es. una finestra 600x200 a meno che non le diate un altro nome vedrete che Maya ve la crea sempre 600x400. Per resettare i parametri della finestra usare:

windowPref -remove $win;
dove $win è il nome della finestra.

Benissimo, abbiamo la nostra finestra… ora mettiamoci dentro qualcosa!
Per inserire bottoni e controlli vari all'interno di una finestra Maya utilizza i layout. Questi sono "contenitori" per gli oggetti da mettere nella finestra. In pratica Maya divide la finestra in tante caselle, e noi possiamo mettere un oggetto in ognuna di queste caselle. Per coloro i quali abbiano mai avuto modo di programmare in QT… è esattamente la stessa (orribile) idea dei layout di QT.

Ad ogni modo, esistono vari tipi di layout:

columnLayout  -> divide la finestra in righe. Usando questo layout si ottiene una colonna contenente i vari componenti

rowLayout -> divide la finestra in colonne. Usando questo layout si ha una sola riga di componenti

gridLayout -> divide la finestra con una griglia. Usando questo layout possiamo avere qualsiasi combinazione di righe e colonne.

In alcune situazioni può tornare utile combinare più tipi di layout: in particolare è possibile mettere un layout dentro un altro layout.
Ad es possiamo fare un rowLayout con 2 righe.
La prima riga può contenere un testo e la seconda riga può contenere un gridLayout 2x2, in modo da metterci 4 bottoni.
In questo modo possiamo avere una riga con un solo oggetto e 2 righe con 2 oggetti. Ovviamente le combinazioni possibili sono molteplici, anche se spesso simpler is better.

Oltre a questi layout di base ce ne sono alcuni con funzionalità più avanzate, come:

frameLayout -> ha la possibilità di avere un titolo, e di essere collapsable (cioè di poterlo aprire e chiudere)

tabLayout
-> un layout a schede. Ad ogni scheda è associato un layout figlio che viene visualizzato quando si seleziona la scheda.

formLayout
-> un layout che permette di posizionare i figli sia in modo assoluto che relativo alla finestra. Utile se si vogliono creare interfacce piuttosto complesse.

Benissimo, ora che sappiamo cos'è un layout non ci resta che crearne uno.
In questo esempio userò un columnLayout e metterò 2 bottoni e uno slider.

$win = `window -title "Crea primitiva" -w 300 -h 200`;
columnLayout -rowSpacing 10 -columnWidth 280 -columnAttach "both" 10;
button -l "Sfera";
button -l "Cubo";
floatSliderGrp -min 0.1 -value 1 -l "Dim" -cw3 40 50 50	-field true Dimensione;
showWindow $win;
setParent..
Il codice è abbastanza facile da capire:

- riga 1: creaiamo la finestra

- riga 2: columnLayout crea il nostro layout largo 280 pixel (parametro columnWidth). Gli altri parametri dicono al layout di spaziare le righe di 10 pixel (rowSpacing) e di espandere i controlli in modo che stiano a 10 pixel sia da destra che da sinistra (columnAttach). Se invece di both in columnAttach specificassimo left o right i nostri bottoni sarebbero a 5 pixel dal bordo sinistro (o destro) e la loro larghezza sarebbe determinata solo dalla lunghezza del loro testo o dalla loro proprietà width se specificata.
La proprietà columnWidth funziona solo se abbiamo l'attach è da entrambi i lati, altrimenti il layout viene ridimensionato come il più largo dei figli.
Quando creiamo un layout Maya AUTOMATICAMENTE  lo assegna come parent dei successivi oggetti che creeremo. In altre parole, tutti i bottoni etc. che creeremo da questo momento in poi saranno in automatico figli del layout e andranno quindi a finire nelle sue caselle.

- righe 3,4: creano i 2 bottoni, che per ora non fanno nulla quando usati. Il parametro –l (label) serve per indicare il testo del bottone.

- riga 5: crea uno slider group (cioè testo + edit box + slider). Se ci servissero numeri interi invece di floatSliderGrp dovremmo usare intSliderGroup. I parametri –min e –max settano i limiti dello slider e –value il valore iniziale. Con –field true abilitiamo l'edit box dove vediamo il valore.
Il parametro –cw3 serve per indicare la larghezza delle 3 colonne (testo, edit box e slider). Questo parametro è un po' particolare, infatti potete usare –cw per settare la larghezza solo di una colonna, ad es:
-cw 2 30
setta la dimensione della colonna 2 a 30.
Se invece volete settare tutte le colonne userete –cw2 o –cw3 nel caso abbiate 2 o 3 colonne (ma non si può usare cw2 se avete 3 colonne).
Notare infine che la larghezza del layout ha priorità su quella dei singoli controlli.
Infine ho dato anche un nome allo slider, in modo da poterne in seguito prendere il valore (vedi sotto)

- riga 6: questa non è indispensabile qui, ma è sempre buona norma usarla. setParent ristabilisce quale sia il parent degli oggetti. Come detto sopra il layout era diventato il parent dei bottoni automaticamente. Con setParent possiamo far tornare la finestra principale come parent, in modo che se creassimo un altro bottone diventerebbe figlio della finestra principale.
Potremmo scrivere setParent $win, per tornare ad avere $win come parent, oppure per tornare in su di un livello usiamo setParent.. (in questo esempio i 2 comandi danno lo stesso risultato).

Ovviamente il prossimo step è quello di assegnare un'azione ai bottoni.
Cambiamo le righe di creazione dei bottoni in questo modo:

button -l "Sfera" -command "sphere";
button -l "Cubo" -command "polyCube";

Il flag –command permette di assegnare un qualsiasi comando MEL al nostro bottone. Possiamo ad esempio, aggiungere un bottone "Esci" alla nostra finestra usando:

button -l "Esci" -command "deleteUI –window $win";

deleteUI è un comando che ci permette di cancellare parte di un'interfaccia e viene usato principalmente nel modo che ho appena mostrato.

Ok, l'ultima cosa da cambiare è quella di prendere il valore dello slider e usarlo come parametro per il lato/raggio del cubo/sfera.

Per fare questo creeremo un paio di funzioni e le assegneremo ai bottoni:

proc creaCubo()
	{
	$val = `floatSliderGrp -q -value Dimensioni`;
	polyCube -w $val -h $val -d $val;
	}

proc creaSfera()
	{
	$val = `floatSliderGrp -q -value Dimensioni`;
	sphere -r $val;
	}
Modifichiamo inoltre i bottoni con:

button -l "Sfera" -command "creaSfera";
button -l "Cubo" -command "creaCubo";
Le due proc (=funzioni in MEL)  altro non fanno che mettere lo slider in modalità query e richiederne il valore, che poi sarà usato per creare il cubo/sfera. Facile no?

Benissimo, ora divertitevi un po' a fare qualche interfaccina del genere, dopodichè potete passare a guardarvi il prossimo esempio, che è un po' più interessante.

In questo esempio vi faccio vedere come creare un'interfaccia per una semplice animazione utilizzando MEL.
Le spiegazioni sono nei commenti del codice, comunque sono 3 procedure:
creaScena, animaScena e creaInterfaccia (indovinate a che servono!)

Notare che le procedure NON vengono chiamate automaticamente. Se scrivete solo le 3 procedure non succede nulla. Il tutto funziona perché l'ultima riga richiama creaInterfaccia!

proc creaScena()
	{
	// Disabilitiamo il bottone Crea, e cambiamo il testo
	button -e -enable false -l "Attendere prego..." Crea;
	
	// Crea una "griglia" di 11x11 cubi bevelati
	$n=0;
	for ($x=-5; $x<=5; $x++)
		{
		for ($z=-5; $z<=5; $z++)
			{
			$nome = "cubo"+$n;
			// Creiamo un cubo
			polyCube -w 0.95 -h 0.95 -d 0.95 -n $nome;
			// Lo spostiamo
			move -a $x 0 $z $nome;
			// Lo beveliamo (0.2% di bevel, oaf vuol dire che usa la %
			// roundness 1, 3 suddivisioni)
			$bevel = `polyBevel -offset 0.2 -oaf true -r 1 -sg 3 $nome`;
			// Settiamo fillNgons del bevel a true (x estetica)
			setAttr ($bevel[0] + ".fillNgons") 1;
			// Average normal per smussare il tutto
			polyAverageNormal $nome;
			
			$n++;
			}
		}

	// Abilitiamo il bottone Anima!
	button -e -enable true Anima;
	button -e -l "Scena creata" Crea;

	// Cancelliamo tutta la history
	delete -all -constructionHistory;
	}

proc animaScena()
	{
	// Troviamo il numero dell'ultimo frame
	$frameMax = `intField -q -value nFrames`;
	// Cicliamo fra i cubi
	for ($n=0; $n<121; $n++)
		{
		$nome = "cubo" + $n;
		
		// Spostiamo il cubo su y di un valore tra -1 e 1
		$cy = `rand -1.0 1.0`;
		move -r 0.0 $cy 0.0 $nome;
		//Settiamo un keyframe a 0
		setKeyframe -time 0 -attribute translateY $nome;
		// Spostiamo il cubo su y di un valore tra -1 e 1
		$cy = `rand -1.0 1.0`;
		move -r 0.0 $cy 0.0 $nome;
		// Settiamo un keyframe all'ultimo frame
		setKeyframe -time $frameMax -attribute translateY $nome;
		}
	}

proc creaInterfaccia()
	{
	// Se la finestra è gia aperta la chiudiamo prima di aprirla di nuovo
	if (`window -exists AniCtrl`)
		{
		deleteUI -window AniCtrl;
		}

	// Creaiamo l'interfaccia
	window -w 300 -h 400 -t "Controllo animazione" AniCtrl;
	columnLayout -rs 10 -cw 280 -cat "both" 10 MainLayout;
	text -l "Step 1" -al "center";
	button -l "Crea scena" -command "creaScena" Crea;
	text -l "Step 2";

	// Per mettere dei controlli in fila creiamo un rowLayout con 3 colonne (-nc 3)
	// e lo inseriamo come figlio del columnlayout
	rowLayout -nc 3 -parent MainLayout;
	text -l "Numero di frames";
	intField -min 1 -value 90 nFrames;
	button -l "Anima!" -enable false -command "animaScena" Anima;
	// Usiamo setParent per tornare al columnLayout
	setParent ..;

	text -l "Step 3";
	button -l "Esci" -command "deleteUI -window AniCtrl";

	setParent ..;

	// Infine mostriamo la finestra
	showWindow AniCtrl;
	}

creaInterfaccia;

Benissimo, questo è tutto (anche se ci sarebbe molto altro da dire... ma se vi dico tutto io che gusto c'è? :P )! Ovviamente commenti e critiche e richieste sono apprezzatissimi!  :hello:

---
Questo articolo è stato importato automaticamente dal forum il 31/lug/2014
Per vedere il post originale e/o i commenti sul forum prima di quella data clicca qui