Ce didacticiel est une introduction à la création d'interfaces utilisateur graphiques dans MEL pour Maya 2010 et les versions antérieures. Maya 2011 introduit une nouvelle méthodologie pour créer des interfaces graphiques qui ne sera pas traitée ici. Nous allons examiner le code approprié pour les interfaces utilisateur, la gestion des erreurs, et nous allons mettre sur pied un script très utile qui vous donne un contrôle considérable sur le point pivot d'un objet..
Si vous envisagez de donner vos scripts à un autre artiste, il peut s'avérer extrêmement utile de créer une interface graphique conviviale rendant votre code accessible aux non-programmeurs. De nos jours, j'utilise rarement des raccourcis clavier personnalisés, mais plutôt une poignée d'interfaces utilisateur que j'ai construites dans MEL pour automatiser les processus Maya. Je peux les transporter avec moi et je ne dois modifier aucune préférence pour pouvoir travailler confortablement sur plusieurs postes de travail. La possibilité de créer et de gérer des interfaces utilisateur est un outil puissant mais parfois frustrant de la boîte à outils MEL..
Jetons un coup d'oeil à ce que nous allons créer aujourd'hui. Commencez par enregistrer le fichier "EdW_PivotControl.mel" inclus dans ce didacticiel dans votre répertoire de scripts. Ensuite, ouvrez Maya. J'utiliserai Maya 2010 pour la durée de ce didacticiel, mais le même code devrait fonctionner pour la plupart des versions de Maya. Tapez ce qui suit dans la ligne de commande et appuyez sur Entrée:
source EdW_PivotControl; EdW_PivotControl;
Nous devrions avoir une fenêtre ouverte avec quelques boutons. Essayez de créer une géométrie et expérimentez le script. L'objectif est de créer un script qui vous permet de contrôler à la volée les points de pivotement des objets..
Présentez les procédures nécessaires pour créer ce script:
J'utilise epc_ comme préfixe. Comme dans les tutoriels précédents, vous voulez vous assurer que vos procédures ont des noms uniques, afin de ne pas interférer avec d'autres scripts..
Nous allons commencer notre script en ouvrant ce vieux bloc-notes, Microsoft Notepad. La première procédure est facile:
Enregistrez votre fichier. Lorsque vous enregistrez un document MEL, veillez à choisir "Tous les fichiers" sous "enregistrer en tant que type". Enregistrez votre document sous forme de fichier .mel dans votre répertoire de scripts Maya. J'utiliserai EdW_PivotControl.mel comme nom de fichier, mais n'hésitez pas à choisir ce que vous voulez.
Nous arrivons maintenant à la partie difficile. Créer des interfaces utilisateur dans MEL n'a jamais été un processus particulièrement élégant, aussi je ferai de mon mieux pour rendre le processus aussi simple que possible. Parfois, il est préférable de dessiner quelque chose sur du papier avant de commencer à écrire du code. Préparez donc une présentation de base pour ce que vous voulez que l'interface utilisateur finale ressemble. Ce script est assez simple, mais lorsque vous commencez à gérer les onglets, les menus, les barres de défilement, etc., vous voulez vous assurer que vous avez un plan de jeu en tête..
Nous allons examiner trois types de commandes d'interface utilisateur:
Voici un aperçu de notre esquisse en fonction des commandes MEL utilisées pour les créer:
La première étape de la création de l'interface utilisateur consiste à établir la fenêtre. Parce que notre objet Window aura un nom unique, Maya ne peut pas avoir deux fenêtres identiques ouvertes en même temps. La première partie de notre procédure vérifie si la fenêtre est déjà ouverte et la ferme si elle est.
// Créer une interface utilisateur globale proc pivotControl ()
if ('window -exists PivotControlMain')
deleteUI PivotControlMain;
; //…;
Maintenant, essayons de créer une fenêtre dans le code et voyons ce qui se passe:
window -rtf 1 -t "Contrôle Pivot EdW" -mnb 1 -mxb 1 -w 450 -h 300 PivotControlMain;
Pour le moment, la fenêtre a été créée dans le script, mais une autre commande est nécessaire pour l'afficher. Cette commande viendra toujours après toutes les commandes de l'interface utilisateur pour la fenêtre..
showWindow PivotControlMain;
Notre code complet devrait ressembler à ceci:
// Fonction principale global proc EdW_PivotControl () pivotControl; ; // Créer l'interface utilisateur globale proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "Contrôle Pivot EdW" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; showWindow PivotControlMain; ;
Source dans le nouveau code et exécutez-le à partir de la ligne de commande Maya. Voici ce que vous devriez obtenir:
source EdW_PivotControl; EdW_PivotControl;
La fenêtre est l'objet le plus haut dans notre hiérarchie d'interface utilisateur. Toutes les dispositions et les contrôles sont des enfants de cet objet. La première mise en page que nous allons utiliser est une mise en page en colonne, pour maintenir les boutons:
columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout;
J'ai constaté qu'inclure des instructions ou des clarifications dans l'interface utilisateur peut rendre le script plus utilisable. Ajoutez un contrôle de texte au script:
text -l "Déplacer le pivot vers:";
Ensuite, nous voulons ajouter une disposition pour maintenir les boutons en haut de la fenêtre, pour déplacer les pivots. GridLayout est une mise en page que nous pouvons utiliser. Elle crée un ensemble de cellules équidistantes contenant un objet chacune..
gridLayout -cwh 60 24 -nrc 2 5;
Chaque cellule de la grille peut contenir un seul contrôle. Ceux-ci sont automatiquement remplis lorsque vous créez les objets sous la présentation. Dans notre cas, nous voulons créer neuf boutons. Nous utiliserons plus tard l'indicateur -command pour indiquer aux boutons quelle procédure appeler:
bouton -l "Centre"; bouton -l "Y Min"; bouton -l "Y Max"; bouton -l "origine"; bouton -l "Sélectionné"; bouton -l "X Min"; bouton -l "X Max"; bouton -l "Z Min"; bouton -l "Z Max";
Nous avons maintenant besoin d'un moyen de dire à Maya que nous en avons terminé avec gridLayout et que nous voulons ajouter d'autres éléments à columnLayout. Pour ce faire, nous allons utiliser une commande MEL pour définir le parent de gridLayout.
setParent…;
Le… ; indique que vous souhaitez associer un parent à la mise en page une étape dans la chaîne hiérarchique. Nous pourrions aussi utiliser le nom de la mise en page, mais cela n'est utile que si toutes les mises en page ont des noms explicites:
setParent EPC_MainColumnLayout;
Notre script pivotControl devrait maintenant ressembler à ceci:
global proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "Contrôle Pivot EdW" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout; text -l "Déplacer le pivot vers:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; bouton -l "Centre"; bouton -l "Y Min"; bouton -l "Y Max"; bouton -l "origine"; bouton -l "Sélectionné"; bouton -l "X Min"; bouton -l "X Max"; bouton -l "Z Min"; bouton -l "Z Max"; setParent…; showWindow PivotControlMain; ;
Comme pour gridLayout, le columnLayout doit être fermé en définissant son parent.
setParent…;
Source dans le script et voyez ce que vous obtenez:
La procédure d'interface utilisateur est terminée!
// Fonction principale global proc EdW_PivotControl () pivotControl; ; // Créer l'interface utilisateur globale proc pivotControl () if ('window -exists PivotControlMain') deleteUI PivotControlMain; ; window -rtf 1 -t "Contrôle Pivot EdW" -mnb 1 -mxb 1 -w 200 -h 350 PivotControlMain; columnLayout -adjustableColumn 1 -rowSpacing 0 EPC_MainColumnLayout; text -l "Déplacer le pivot vers:"; gridLayout -cwh 60 24 -nrc 2 5 -ag 1; bouton -l "Centre"; bouton -l "Y Min"; bouton -l "Y Max"; bouton -l "origine"; bouton -l "Sélectionné"; bouton -l "X Min"; bouton -l "X Max"; bouton -l "Z Min"; bouton -l "Z Max"; setParent…; setParent…; showWindow PivotControlMain; ;
Nous devons maintenant créer le code permettant de déplacer réellement le point pivot d'un objet. Pour ce faire, nous allons créer deux procédures qui fonctionneront ensemble:
Disposez le pseudo-code pour epc_getBounds:
crée le squelette de la procédure, avec un type de retour et un argument passé.
procédure globale float [] epc_getBounds (string $ objSel) ;
sélectionner l'objet passé en argument et obtenir les informations du cadre de sélection.
procédure globale float [] epc_getBounds (chaîne $ objSel) select -r $ objSel; float $ getBoundArray [] = 'xform -q -ws -bb'; ;
L'indicateur -boundingBox renvoie six valeurs dans un tableau: x minimum, x maximum, y minimum, y maximum, z minimum et z maximum.
calculer les moyennes entre les minimums et les maximums. Rappelez-vous que les tableaux commencent toujours par un index de zéro.
float $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax plus xmin divisé par deux float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax plus ymin divisé par deux float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax plus zmin divisé par deux
calculer les moyennes entre les minimums et les maximums. Rappelez-vous que les tableaux commencent toujours par un index de zéro.
float $ bbXAv = (($ getBoundArray [3] + $ getBoundArray [0]) / 2); // xmax plus xmin divisé par deux float $ bbYAv = (($ getBoundArray [4] + $ getBoundArray [1]) / 2); // ymax plus ymin divisé par deux float $ bbZAv = (($ getBoundArray [5] + $ getBoundArray [2]) / 2); // zmax plus zmin divisé par deux
Ajouter les moyennes nouvellement calculées et retourner le tableau final.
$ getBoundArray [6] = $ bbXAv; $ getBoundArray [7] = $ bbYAv; $ getBoundArray [8] = $ bbZAv; return $ getBoundArray;
La procédure finale devrait ressembler à ceci:
procédure globale float [] epc_getBounds (chaîne $ 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; ;
Nous pouvons maintenant appliquer ce code à notre procédure epc_movePivotLocal. Écrivez le pseudo-code:
créer le squelette pour la procédure. Configurez une boucle for-in afin que le code soit exécuté une fois pour chaque objet sélectionné dans la scène..
proc global epc_movePivotLocal (chaîne $ mode) chaîne $ sel [] = 'ls -sl'; for ($ thisObj dans $ sel) // le code va ici; ;
Utilisez la procédure return-value de epc_getBounds pour écrire un tableau flottant:
float $ pos [] = 'epc_getBounds $ thisObj';
Nous allons maintenant utiliser une instruction switch-case pour déplacer le pivot. La structure de base d'un commutateur est la suivante:
switch ($ variable) // la variable peut être de n'importe quel type, y compris les chaînes et les majuscules case variableValue: // si la variable correspond à variableValue // exécuter ce code break; case otherValue: // code here break; ;
L'instruction switch-case est un système en cascade, ce qui signifie que si vous n'incluez pas la commande "break" après chaque cas, les autres cas seront également exécutés. Pour notre procédure, nous souhaitons ajouter un boîtier de commutation nous permettant d'utiliser la même procédure pour déplacer un pivot vers plusieurs positions différentes. Notre boîtier se présentera comme ceci:
switch ($ mode) case "center": CenterPivot $ thisObj; Pause; case "ymin": déplacer -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; ;
Continuez à ajouter des cas au script afin que chacun de nos boutons d'interface utilisateur ait un cas correspondant. La procédure complète devrait ressembler à ceci:
proc global epc_movePivotLocal (chaîne $ mode) chaîne $ sel [] = 'ls -sl'; for ($ thisObj dans $ sel) float $ pos [] = 'epc_getBounds $ thisObj'; switch ($ mode) case "center": CenterPivot $ thisObj; Pause; case "ymin": déplacer -a -rpr $ pos [6] $ pos [1] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "ymax": déplacer -a -rpr $ pos [6] $ pos [4] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "origin": move -a -rpr 0 0 0 ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "xmin": déplacer -a -rpr $ pos [0] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "xmax": move -a -rpr $ pos [3] $ pos [7] $ pos [8] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "zmin": déplacer -a -rpr $ pos [6] $ pos [7] $ pos [2] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; case "zmax": move -a -rpr $ pos [6] $ pos [7] $ pos [5] ($ thisObj + ".rotatePivot") ($ thisObj + ".scalePivot"); Pause; ; ; ;
Notre dernière procédure suit à peu près la même idée.
proc global epc_movePivotToObject () string $ selLast [] = 'ls -sl -tail 1'; chaîne $ copyToObj = $ selLast [0]; sélectionnez -deselect $ copyToObj; string $ selSet [] = 'ls -sl'; float $ pivotSel [] = 'xform -q -piv -ws $ copyToObj'; print $ pivotSel; for ($ each in $ selSet) move -a $ pivotSel [0] $ pivotSel [1] $ pivotSel [2] ($ each + ".rotatePivot") ($ each + ".échellePivot"); ; ;
Il n'y a que deux nouveaux drapeaux dans cette procédure:
Maintenant, il ne reste plus qu'à faire en sorte que nos boutons dans l'interface utilisateur appellent les procédures que nous avons écrites..
bouton -l "Centre" -c "Centre epc_movePivotLocal"; bouton -l "Y Min" -c "epc_movePivotLocal ymin"; bouton -l "Y Max" -c "epc_movePivotLocal ymax"; bouton -l "origine" -c "origine epc_movePivotLocal"; bouton -l "Sélectionné" -c "epc_movePivotToObject"; bouton -l "X Min" -c "epc_movePivotLocal xmin"; bouton -l "X Max" -c "epc_movePivotLocal xmax"; bouton -l "Z Min" -c "epc_movePivotLocal zmin"; bouton -l "Z Max" -c "epc_movePivotLocal zmax";
Et nous avons fini!