Ce tutoriel est une introduction à l'utilisation de fichiers MEL externes, ainsi que de procédures, fonctions, boucles et interactions scriptées au sein de l'espace de travail Maya. Nous allons passer en revue les pratiques de base en matière de codage et de création d'un objet géométrique astucieux qu'il serait très difficile de créer sans script.
Dans ce didacticiel, nous allons créer un fichier de script externe avec quatre "procédures" - des scripts autonomes destinés à atteindre des objectifs spécifiques. La première procédure utilisera n'importe quel nombre d'objets sélectionnés dans la fenêtre Maya et créera une hiérarchie chaînée pour faciliter les doubles transformations. Le second script supprime les objets sélectionnés et le troisième déplace les points de pivotement des objets sélectionnés vers l'origine de l'espace mondial. Ces trois scripts vous permettront de créer facilement des effets intéressants avec plusieurs objets. La quatrième procédure combinera les trois premières pour créer une «spirale de Fermat», similaire au tourbillon complexe trouvé sur les têtes de tournesol..
Ouvrez Maya. Pour ce didacticiel, j'utiliserai Maya 2010, mais les mêmes commandes devraient fonctionner pour la plupart des versions de Maya. Commencez par créer un cube au centre de la fenêtre.
Allez dans 'Edition> Dupliquer spécial' et cliquez sur la case d'option pour faire apparaître cette boîte de dialogue. Créer neuf copies.
Allez dans 'Fenêtre> Hiérarchie Hypergraph'. Nous devons maintenant parenter les cubes ensemble pour créer une "chaîne". Pour ce faire, cliquez d'abord sur «pCube2», puis sur «pCube1» et appuyez sur «p» sur votre clavier. Ceci parent le premier objet sélectionné (pCube2) au deuxième objet sélectionné (pCube1).
Continuez ce processus (en sélectionnant l'enfant, puis le parent, puis en appuyant sur 'p' pour les chaîner ensemble) pour chacun de nos cubes. Une fois terminé, chaque objet au milieu de la hiérarchie devrait avoir un cube parent et un cube enfant, et la hiérarchie globale devrait ressembler à ceci:
Fermez la fenêtre 'Hypergraph Hierarchy'. Sélectionnez tous les objets en faisant glisser la sélection sur les cubes au milieu de la fenêtre. Puis, en gardant tous les cubes sélectionnés, essayez de les déplacer et de les faire pivoter.
Étant donné que les transformations de chaque cube sont maintenant relatives au cube situé au-dessus de la chaîne, la double transformation obtenue vous permet de déplacer les cubes d'une manière tout à fait unique: les petites traductions deviennent rapidement des modifications importantes..
Avec tous les cubes toujours sélectionnés, appuyez sur "Shift-P" sur votre clavier pour supprimer les parents. Nous avons maintenant parcouru toutes les étapes principales que nous souhaitons automatiser avec notre script. Commencez donc par créer un nouveau fichier Maya et ouvrez un éditeur de texte. Mon favori personnel est Notepad ++, qui a même un plugin de langage MEL disponible. N'hésitez pas à utiliser l'éditeur de texte que vous préférez, mais pour l'instant je vais utiliser le bon vieux Bloc-notes Microsoft. Le bloc-notes est simple, mais il fait le travail.
Allez-y et sauvegardez 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. Je vais utiliser EdW_DoubleTransform.mel comme nom de fichier..
Pour créer une procédure, vous devez connaître quelques éléments à l’avance. Tout d'abord, vous devez définir une "portée" pour la procédure. Scope détermine l’endroit où une procédure peut être consultée. Une étendue "locale" signifie que le code n'est accessible qu'aux autres procédures contenues dans le même fichier .mel. "Global" signifie que la procédure est disponible pour les autres fichiers de script et pour l'utilisateur, et qu'elle est également chargée en mémoire. En général, j'utilise beaucoup de procédures globales. Ce n'est pas la meilleure pratique de codage absolue, mais j'aime bien avoir mes procédures disponibles dans plusieurs scripts. Deuxièmement, vous devez choisir un nom pour votre procédure. En général, essayez de choisir quelque chose d'unique et de descriptif - si la procédure est globale, vous ne voulez pas que le nom entre en conflit avec une autre procédure dans un autre script. En général, je mets des initiales dans le nom, et comme le script que nous écrivons s'appelle "DoubleTransform", je vais utiliser "dt" dans ce cas. En gros, voici la procédure que nous construisons:
proc global dt_makeParentChain () // actions du script;
La première chose que nous ferons avec notre procédure est de définir une variable qui hébergera éventuellement une liste de noms d’objets. Dans MEL, les variables sont désignées par un signe dollar ($) avant le nom de la variable. Une variable peut contenir différents types de données: des chaînes de texte, des nombres entiers appelés entiers, des nombres décimaux en virgule flottante, des valeurs vectorielles, etc. La syntaxe à utiliser pour déclarer une variable est la suivante:
dataType $ nomVariable;
Pour l'instant, nous allons créer une variable chaîne vide:
string $ selectedObjects;
Si nous le souhaitons, nous pouvons également affecter des données à la variable dans la même ligne de code. Les guillemets doubles servent à définir des chaînes de texte.
string $ selectedObjects = "ceci est une chaîne de texte";
un seul signe égal signifie "définir la variable sur". Un double signe égal signifie "est égal à" et est utilisé lors de la comparaison de variables.
Afin de tester notre nouvelle variable, nous devons ajouter une commande d'impression. Cela générera une chaîne dans l'éditeur de script lors de l'exécution du script. Dans ce cas, nous imprimons simplement le contenu de la variable '$ selectedObjects'.
print $ selectedObjects;
Ajoutez un commentaire à votre nouvelle procédure. J'ai tendance à ajouter un commentaire avant chaque procédure afin de pouvoir les retrouver rapidement plus tard. Certains de mes scripts comportent des dizaines de procédures et les commentaires facilitent grandement le processus de débogage et de modification du code. Le code complet devrait maintenant ressembler à ceci:
// Définit la procédure globale de la chaîne parent dt_makeParentChain () string $ selectedObjects = "ceci est une chaîne de texte"; print $ selectedObjects; ;
Enregistrez le fichier et retournez à Maya. À chaque démarrage, Maya analyse le répertoire des scripts et charge la liste de tous les fichiers. Si vous avez ajouté un script au répertoire alors que Maya est déjà ouverte, le système ne sait pas que le fichier existe. Dans ce cas, vous avez deux options: redémarrer Maya ou vous pouvez utiliser la commande "rehash" pour forcer Maya à mettre à jour cette liste de fichiers. Nous allons utiliser la deuxième méthode, donc allez dans 'Fenêtre> Editeurs généraux> Editeur de script', tapez ce qui suit:
rehash;
Maintenant, appuyez sur 'Ctrl-Entrée' pour exécuter la commande.
Pour tester votre script, vous devez l’initialiser dans Maya. La commande "rehash" indique à maya que le fichier existe et la commande "source" indique à Maya de charger le script en mémoire. Tapez ce qui suit dans l'éditeur de script:
source EdW_DoubleTransform.mel;
Ensuite, tapez la commande pour la procédure que nous avons créée dans le script:
dt_makeParentChain;
Voici ce que vous devriez obtenir dans l'éditeur de script après avoir exécuté la procédure:
Maintenant que nous avons mis en place une procédure qui fonctionne, trouvons le pseudocode de ce que nous souhaitons que cette procédure fasse dans notre script final:
Afin d’obtenir une liste des objets sélectionnés dans la fenêtre Maya, utilisez la commande list "ls". La liste est généralement utilisée avec un drapeau qui indique à la commande de saisir tout ce qui est actuellement sélectionné dans la fenêtre maya, -sl. Essayez de sélectionner des objets dans la fenêtre maya et tapez la commande complète (illustrée ci-dessous) dans l'éditeur de script. N'oubliez pas d'appuyer sur 'Ctrl-Entrée' pour exécuter la commande..
ls -sl;
La commande list génère un ensemble de chaînes représentant la liste complète des objets sélectionnés. Afin de nous rendre ces informations utiles, nous devons écrire le résultat de la commande "list" dans une variable. Pour ce faire, placez la commande de liste entre guillemets (Remarque, le coche, également appelé coche arrière, est généralement situé au-dessus de la touche de tabulation du clavier… veillez à ne pas utiliser le guillemet simple en regard la touche Entrée). Le fait de mettre une commande entre guillemets se traduit par "la sortie de". Notre commande devrait maintenant ressembler à ceci:
string $ selectedObjects = 'ls -sl';
La variable $ selectedObjects est une chaîne de texte unique. Ce dont nous avons vraiment besoin est ce qu’on appelle un tableau de chaînes - une liste ordonnée de chaînes contenues dans une seule variable. Pour transformer notre chaîne en tableau de chaînes, utilisez des crochets pour déclarer la variable:
chaîne $ selectedObjects [] = 'ls -sl';
Maintenant, chaque fois que nous faisons référence à la variable, nous pouvons utiliser le tableau entier:
$ selectedObjects // toutes les chaînes du tableau
… Ou une chaîne individuelle à l'intérieur du tableau, en fournissant un index - la position de la chaîne souhaitée dans le tableau lui-même. Les valeurs d'index dans MEL commencent toujours à zéro, comme indiqué ci-dessous:
print $ selectedObjects [0]; // retourne la première chaîne du tableau print $ selectedObjects [2]; // retourne la troisième chaîne du tableau
Nous aurons également besoin d’un moyen de déterminer le nombre d’objets contenus dans le tableau. Vous pouvez utiliser la commande "size" pour faire exactement cela. Créons une nouvelle variable pour stocker ces informations. Un nombre entier est représenté par un entier, qui est toujours référencé dans la MEL comme un "int":
int $ numSelectedObjects = 'taille ($ selectedObjects)';
Nous avons maintenant besoin d'un moyen de parenter chaque objet en fonction de sa place dans le tableau. Il existe une poignée de façons de faire cela, mais pour le moment, nous allons utiliser une boucle "pour" de base. Les boucles for sont courantes dans la programmation pour effectuer une action plusieurs fois. La syntaxe d'une boucle for qui s'exécute dix fois est la suivante:
pour (int $ i = 0; $ i < 9; $i++) //action to be done ;
La structure de la boucle comporte trois parties. $ i = 0 définit une variable entière, $ i
pour ($ i = 0; $ i < $numSelectedObjects; $i++) //action to be performed ;
Nous devons maintenant utiliser une commande 'parent' pour créer la chaîne hiérarchique. La syntaxe de cette commande est la suivante:
parent childObject parentObject;
Donc, dans notre cas, la commande parente serait:
pour ($ i = 1; $ i < $numSelectedObjects; $i++) parent $selectedObjects[(i-1)] $selectedObjects[i]; ;
Avec notre boucle terminée, nous devons maintenant désélectionner le dernier objet de la sélection, en utilisant la commande "select" avec le drapeau "désélectionner". Pour calculer l'index du dernier objet sélectionné, nous prenons le nombre total d'objets, puis, parce que l'index de tout tableau de Maya commence à 0, soustrayez 1.
select -deselect $ selectedObjects [($ numSelectedObjects - 1)];
Et avec cela, notre première procédure est maintenant terminée:
// Make proc général de la chaîne de parent dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'taille ($ selectedObjects)'; pour ($ i = 1; $ i < $numSelectedObjects; $i++) parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ;
Sous 'dt_makeParentChain', créez une nouvelle procédure pour rendre non liés les objets sélectionnés. Le code sous les parents sélectionne les objets sélectionnés dans le monde, ce qui revient au même que leur suppression..
proc global dt_unParentSelected () parent -w; ;
Notre troisième procédure automatisera le processus de déplacement du point de pivotement d'un objet vers l'origine. Comme auparavant, nous commençons par créer le plan de procédure:
proc global dt_pivotToOrigin () // actions de procédure;
Nous utilisons ensuite la même technique que dans la première procédure pour écrire une liste des objets sélectionnés dans une variable:
chaîne $ selectedObjects [] = 'ls -sl';
Nous devons maintenant ajouter une boucle. Bien que nous puissions utiliser le même type de boucle for que le premier script, utilisons plutôt une boucle for-each. Une boucle "for-each" est une version spécialisée de la boucle for qui s'exécute une fois pour chaque valeur d'un tableau. Il vous permet également d'écrire une variable qui représente la valeur de l'index actuel. La syntaxe ressemble à ceci:
for ($ each dans $ arrayVariable) // effectue cette action avec $ each;
La variable $ each contient la valeur de l'index actuel du tableau. Pour notre script, voici à quoi devrait ressembler le code:
for ($ thisObj dans $ selectedObjects) // déplace le pivot de $ thisObj;
Cette même technique peut être utilisée pour automatiser toute commande maya pour un nombre quelconque d'objets sélectionnés..
En utilisant la variable $ thisObj, nous pouvons maintenant sélectionner l’objet actuellement examiné par la boucle:
sélectionnez -r $ thisObj;
Afin de déplacer le pivot vers l'origine, nous pouvons utiliser la commande "xform" et réinitialiser les indicateurs -rp (rotationPivot) et -sp (échellePivot) à 0 sur les axes X, Y et Z:
xform -ws -rp 0 0 0 0 -sp 0 0 0;
Les composants principaux du script sont maintenant terminés et votre code, contenant les trois procédures, doit ressembler à ceci:
// Make proc général de la chaîne de parent dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'taille ($ selectedObjects)'; pour ($ i = 1; $ i < $numSelectedObjects; $i++) parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ; // Un-Parent Objects global proc dt_unParentSelected() parent -w; ; // Move Pivot to Origin global proc dt_pivotToOrigin() string $selectedObjects[] = 'ls -sl'; for($thisObj in $selectedObjects) select -r $thisObj; xform -ws -rp 0 0 0 -sp 0 0 0; ; ;
Nous allons maintenant créer une quatrième procédure qui utilisera les trois précédentes pour créer une progression géométrique intéressante appelée "Spirale de Fermat", basée sur la relation angulaire du nombre d'or, phi. C'est une forme que l'on retrouve couramment dans la nature et qui suit toutes sortes de règles géométriques intéressantes. Commençons par écrire le pseudocode:
Donc, pour commencer, créons un nouveau plan de procédure:
procédure globale dt_fermatSpiral ()
Nous allons maintenant créer une sphère avec 8 divisions radiales et 8 divisions de hauteur, et écrire les nœuds de transformation et de forme résultants dans un tableau de chaînes afin que nous puissions les suivre. La plupart des commandes qui créent une géométrie génèrent deux chaînes: le nom du noeud de transformation et le nom du noeud de forme. Pour la plupart, vous souhaitez utiliser la chaîne de noeud de transformation, qui sera stockée dans l'index [0] de la variable de tableau $ seedSphere créée ci-dessous:
string $ seedSphere [] = 'polySphere -sx 8 -sy 8';
Nous allons maintenant créer une variable de tableau de chaîne vide:
chaîne $ allSpheres [];
Puis ouvrez une boucle for qui s'exécute 1 000 fois:
pour ($ i = 1; $ i<1000; $i++)
Nous devons maintenant dupliquer notre nouvelle sphère créée et écrire les nœuds de transformation et de forme résultants dans une variable:
string $ duplicatedSphere [] = 'duplicate';
Ici, nous ajoutons le nom de notre noeud de transformation dupliqué à la fin du tableau $ allSpheres. Vous pouvez utiliser la commande "size" pour déterminer le nombre d'objets déjà présents dans le tableau et utiliser le résultat comme index pour notre nouvelle valeur..
$ allSpheres [taille ($ allSpheres)] = $ duplicatedSphere [0];
Ici, nous sélectionnons toutes les sphères créées et exécutons la commande de chaîne parent créée précédemment:
select -r $ allSpheres; dt_makeParentChain;
Après avoir parent les sphères ensemble, nous les sélectionnons à nouveau et les déplaçons toutes .05 dans X à l’aide de la commande "déplacer":
select -r $ allSpheres; se déplacer de 0,05 0 0;
Après avoir réinitialisé la position d'origine à l'aide de notre procédure "pivotToOrigin" créée précédemment, nous sélectionnons les sphères une dernière fois et les faisons pivoter de 137,5 degrés en Y. Ensuite, exécutez notre script non apparenté:
dt_pivotToOrigin; select -r $ allSpheres; tourner à 0 137,5 0; dt_unParentSelected;
Et cela achève notre procédure finale. Donc, notre script complet devrait ressembler à ceci:
// Make proc général de la chaîne de parent dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'taille ($ selectedObjects)'; pour ($ i = 1; $ i < $numSelectedObjects; $i++) parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ; // Un-Parent Objects global proc dt_unParentSelected() parent -w; ; // Move Pivot to Origin global proc dt_pivotToOrigin() string $selectedObjects[] = 'ls -sl'; for($thisObj in $selectedObjects) select -r $thisObj; xform -ws -rotatePivot 0 0 0 -scalePivot 0 0 0; ; ; //Create Fermat's Spiral of Spheres global proc dt_fermatSpiral() string $seedSphere[] = 'polySphere -sx 8 -sy 8'; string $allSpheres[]; for ($i=1; $i<1000; $i++) string $duplicatedSphere[] = 'duplicate'; $allSpheres[size($allSpheres)] = $duplicatedSphere[0]; ; select -r $allSpheres; dt_makeParentChain; select -r $allSpheres; move 0.05 0 0; dt_pivotToOrigin; select -r $allSpheres; rotate 0 137.5 0; dt_unParentSelected; ;
Et avec ça on a fini! Enregistrez le script et relancez le processus 'rehash' / 'source' comme indiqué ci-dessus. Ensuite, entrez la commande suivante dans l'éditeur de script de Maya, appuyez sur 'Ctrl-Entrée' et attendez quelques secondes:
dt_fermatSpiral ();
Et là, vous avez la spirale de Fermat, entièrement construite en MEL. Essayez de jouer avec différents angles, formes et transformations dans la procédure finale - vous pouvez obtenir toutes sortes de motifs intéressants!