Maya MEL Modélisation procédurale pour artistes - UIs

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..

Les interfaces des utilisateurs

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..


Étape 1

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;

Étape 2

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..


Étape 3

Présentez les procédures nécessaires pour créer ce script:

  • EdW_PivotControl - lance la procédure principale du script
  • epc_pivotControl - crée l'interface utilisateur
  • epc_getBounds - utilise la commande xform pour obtenir le cadre de sélection de l'objet sélectionné
  • epc_movePivotLocal - déplace le pivot de l'objet vers une position locale (y min, x min, etc.)
  • epc_movePivotToObject - déplace le pivot vers l'emplacement d'un autre objet

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..


Étape 4

Nous allons commencer notre script en ouvrant ce vieux bloc-notes, Microsoft Notepad. La première procédure est facile:


Étape 5

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.


Étape 6

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..


Étape 7

Nous allons examiner trois types de commandes d'interface utilisateur:

  • Windows - Objets de niveau supérieur dotés des boutons standard de toutes les fenêtres du système d'exploitation, tels que Réduire, Agrandir et Fermer..
  • Layouts - différentes façons d'organiser les objets dans une fenêtre.
  • Contrôles - boutons, curseurs, champs de texte, etc. Ce sont les éléments interactifs de l'interface utilisateur..

Voici un aperçu de notre esquisse en fonction des commandes MEL utilisées pour les créer:


Étape 8

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;
; //…;

Étape 9

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;
  • -resizeToFitChildren (-rtf), si la valeur est true, la fenêtre sera automatiquement redimensionnée pour s'adapter à toutes les dispositions et tous les contrôles que vous créez.
  • -title (-t) le texte affiché dans la barre de titre en haut de la fenêtre
  • -minimButton (-mnb) active ou désactive le bouton Réduire
  • -maximButton (-mxb) active ou désactive le bouton Agrandir
  • -largeur (-w) largeur de la fenêtre en pixels
  • -hauteur (-h) hauteur de la fenêtre en pixels

Étape 10

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;

Étape 11

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; ;

Étape 12

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; 

Étape 13

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;
  • -réglableColonne (-ac) la colonne sera redimensionnée automatiquement en fonction de la largeur de la fenêtre
  • -rowSpacing (-rs) la distance en pixels entre chaque ligne de la colonne

Étape 14

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:";
  • -label (-l) le texte actuel du contrôle


Étape 15

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;
  • -cellWidthHeight (-cwh) définit la largeur et la hauteur de chaque cellule.
  • -numberOfRowsColumns (-nrc) définit le nombre de lignes horizontales et de colonnes verticales dans la grille


Étape 16

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";
  • -étiquette (-l) le texte affiché sur le bouton


Étape 17

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;

Étape 18

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; ;

Étape 19

Comme pour gridLayout, le columnLayout doit être fermé en définissant son parent.

setParent…;

Étape 20

Source dans le script et voyez ce que vous obtenez:


Étape 22

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; ;

Étape 23

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:

  • epc_getBounds utilisera une commande xform et un peu d'arithmétique pour renvoyer les valeurs minimales, maximales et moyennes du cadre de sélection.
  • epc_movePivotLocal va récupérer les informations du cadre de sélection en utilisant epc_getBounds pour déplacer les emplacements de pivot.

Étape 24

Disposez le pseudo-code pour epc_getBounds:

  • sélectionnez l'objet passé de epc_movePivotLocal
  • écrire le résultat d'une commande xform interrogée dans un tableau
  • obtenir les moyennes des minimums et des maximums x, y et z renvoyés par la forme x
  • ajouter les moyennes sur le tableau de retour
  • renvoyer le tableau de la boîte englobante avec les moyennes

Étape 25

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) ;

Étape 26

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'; ;
  • -query (-q) interroge la commande, au lieu de transformer quoi que ce soit
  • -worldSpace (-ws) s’assure que le
  • -boundingBox (-bb) renvoie les positions min et max du cadre de sélection

L'indicateur -boundingBox renvoie six valeurs dans un tableau: x minimum, x maximum, y minimum, y maximum, z minimum et z maximum.


Étape 27

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

Étape 28

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

Étape 28

Ajouter les moyennes nouvellement calculées et retourner le tableau final.

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

Étape 29

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; ;

Étape 30

Nous pouvons maintenant appliquer ce code à notre procédure epc_movePivotLocal. Écrivez le pseudo-code:

  • écrire une liste d'objets sélectionnés dans un tableau
  • obtenir les informations du cadre de sélection pour chaque objet sélectionné, à l'aide de la procédure epc_getBounds
  • créer une instruction switch-case pour contrôler où le pivot doit se déplacer

Étape 31

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; ;

Étape 32

Utilisez la procédure return-value de epc_getBounds pour écrire un tableau flottant:

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

Étape 32

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; ;

Étape 33

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; ; ; ;

Étape 33

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:

  • -tail (-tl) n'écrit que le dernier objet sélectionné dans le tableau (commande ls)
  • -pivot (-piv) demande l'emplacement actuel du pivot sur un objet (commande xform)

Étape 35

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";
  • -commande (-c) appelle une commande ou une liste de commandes chaque fois que le bouton est enfoncé

Étape 35

Et nous avons fini!