Modelado de procedimientos con scripts de MEL en maya - Día 2

Este tutorial es una introducción al uso de procedimientos y archivos MEL externos, funciones, bucles e interacción con scripts dentro del área de trabajo de Maya. Repasaremos las prácticas básicas de codificación y armaremos un ingenioso objeto geométrico que sería muy difícil de crear sin secuencias de comandos..


Archivos / Complementos Adicionales:
  • Descarga el guión final

Creación de procedimientos

En este tutorial, crearemos un archivo de script externo con cuatro "procedimientos": scripts autocontenidos destinados a alcanzar objetivos específicos. El primer procedimiento tomará cualquier número de objetos seleccionados en la ventana gráfica Maya y creará una jerarquía encadenada para facilitar las dobles transformaciones. El segundo script anulará la selección de los objetos seleccionados, y el tercero moverá los puntos de pivote de los objetos seleccionados al origen del espacio mundial. Estos tres scripts te permitirán crear fácilmente algunos efectos interesantes con múltiples objetos. El cuarto procedimiento combinará los tres primeros para crear una 'Espiral de Fermat', similar al complejo espiral que se encuentra en las cabezas de girasol..


Paso 1

Abierto Maya. Para el curso de este tutorial, usaré Maya 2010, pero los mismos comandos deberían funcionar para la mayoría de las versiones de Maya. Comience por crear un cubo en el centro de la ventana gráfica..


Paso 2

Vaya a 'Editar> Duplicar especial' y haga clic en el cuadro de opción para abrir este cuadro de diálogo. Crear nueve copias.


Paso 3

Vaya a 'Ventana> Jerarquía de hipergrafía'. Ahora necesitamos criar los cubos juntos para crear una "cadena". Para hacer esto, primero haga clic en 'pCube2' y luego haga clic en 'pCube1', y presione 'p' en su teclado. Esto es el principal objeto seleccionado (pCube2) al segundo seleccionado (pCube1).

Continúe este proceso (seleccionando el niño, luego el padre y luego presionando 'p' para encadenarlos) para cada uno de nuestros cubos. Una vez completado, cada objeto en el centro de la jerarquía debe tener un cubo primario y un cubo secundario, y la jerarquía general debe tener este aspecto:


Etapa 4

Cierre la ventana 'Jerarquía de Hypergraph' Seleccione todos los objetos haciendo clic sobre los cubos en el centro de la ventana gráfica. Luego, manteniendo todos los cubos seleccionados, intente moverlos y rotarlos.

Debido a que las transformaciones de cada cubo son ahora relativas al cubo un paso arriba en la cadena, la doble transformación resultante le permite mover los cubos de una manera muy única: las traducciones pequeñas se convierten rápidamente en grandes cambios.


Paso 5

Con todos los cubos aún seleccionados, presione 'Shift-P' en su teclado para quitar los padres de los padres. Ahora hemos recorrido todos los pasos principales que queremos automatizar con nuestro script. Así que comienza un nuevo archivo Maya y abre un editor de texto. Mi favorito personal es Notepad ++, que incluso tiene un complemento de idioma MEL disponible. Siéntase libre de usar el editor de texto que prefiera, pero por ahora usaré el viejo Bloc de notas de Microsoft. El bloc de notas es simple, pero hace el trabajo.


Paso 6

Sigue adelante y guarda tu archivo. Al guardar un documento MEL, asegúrese de elegir "Todos los archivos" en "guardar como tipo". Guarde su documento como un archivo .mel en su directorio de scripts de Maya. Usaré EdW_DoubleTransform.mel como mi nombre de archivo.


Paso 7

Para crear un procedimiento, debes saber un par de cosas de antemano. Primero, debe definir un "alcance" para el procedimiento. El alcance establece desde dónde se puede acceder a un procedimiento. Un alcance "local" significa que el código solo es accesible para otros procedimientos dentro del mismo archivo .mel. "Global" significa que el procedimiento está disponible para otros archivos de comandos y para el usuario, y también se carga en la memoria. En general, utilizo muchos procedimientos globales. Esta no es la mejor práctica de codificación absoluta, pero me gusta que mis procedimientos estén disponibles en varios scripts. En segundo lugar, debe elegir un nombre para su procedimiento. En general, intente elegir algo único y descriptivo: si el procedimiento es global, no desea que el nombre entre en conflicto con cualquier otro procedimiento en cualquier otro script. Por lo general, escribo un tipo de iniciales en el nombre, y como el script que estamos escribiendo se llama "DoubleTransform", en este caso usaré "dt". En su forma más básica, este es el procedimiento que estamos construyendo:

 proc global dt_makeParentChain () // acciones del script;

Paso 8

Lo primero que haremos con nuestro procedimiento es definir una variable que eventualmente alojará una lista de nombres de objetos. En MEL, las variables se indican con un signo de dólar ($) antes del nombre de la variable. Hay diferentes tipos de datos que una variable puede contener: cadenas de texto, números enteros llamados números enteros, números decimales de coma flotante, valores vectoriales, etc. La sintaxis para declarar una variable es la siguiente:

 dataType $ variableName;

Por ahora, haremos una variable de cadena vacía:

 cadena $ selectedObjects;

Si queremos, también podemos asignar datos a la variable en la misma línea de código. Las comillas dobles se utilizan para definir cadenas de texto.

 string $ selectedObjects = "esta es una cadena de texto";

un solo signo de igual significa "establecer la variable en". Un doble signo igual significa "es igual a", y se usa cuando se comparan variables.


Paso 9

Para probar nuestra nueva variable, necesitamos agregar un comando de impresión. Esto generará una cadena al Editor de secuencias de comandos cuando se ejecute la secuencia de comandos. En este caso, simplemente estamos imprimiendo el contenido de la variable '$ selectedObjects'.

 imprimir $ selectedObjects;

Paso 10

Añade un comentario a tu nuevo procedimiento. Tiendo a agregar un comentario antes de cada procedimiento, para poder encontrarlos rápidamente más tarde. Algunos de mis scripts tienen docenas de procedimientos, y los comentarios hacen que el proceso de depuración y cambio de código sea mucho más fácil. El código completo ahora debería verse así:

 // Hacer cadena global principal proc dt_makeParentChain () string $ selectedObjects = "esta es una cadena de texto"; imprimir $ selectedObjects; ;

Paso 11

Guarda el archivo y vuelve a Maya. Cada vez que Maya se inicia, escanea el directorio de scripts y carga una lista de todos los archivos allí. Si ha agregado un script al directorio mientras Maya ya está abierto, entonces el sistema no sabe que el archivo existe. En este caso, tiene dos opciones: reiniciar Maya o puede usar el comando "rehash" para forzar a Maya a actualizar esa lista de archivos. Usaremos el segundo método, así que vaya a 'Ventana> Editores generales> Editor de secuencias de comandos', escriba lo siguiente:

 refrito;

Ahora pulsa 'Ctrl-Enter' para ejecutar el comando.


Paso 12

Para probar su guión, deberá "inicializarlo" en maya. El comando "rehash" le dice a maya que el archivo existe, y el comando "source" le dice a Maya que cargue el script en la memoria. Escriba lo siguiente en el editor de secuencias de comandos:

 fuente EdW_DoubleTransform.mel;

Luego, escriba el comando para el procedimiento que creamos dentro del script:

 dt_makeParentChain;

Esto es lo que debe obtener en el editor de secuencias de comandos después de ejecutar el procedimiento:


Paso 13

Ahora que hemos creado un procedimiento de funcionamiento, vamos a averiguar el pseudocódigo para lo que queremos que el procedimiento haga en nuestro script final:

  • escribir una lista de objetos seleccionados a una variable
  • obtener el número de objetos seleccionados
  • padre cada objeto al anterior en la lista

Paso 14

Para obtener una lista de los objetos seleccionados en la vista Maya, use el comando list, "ls". La lista se usa generalmente con un indicador que le dice al comando que tome lo que esté seleccionado actualmente en la ventana gráfica de maya, -sl. Intente seleccionar algunos objetos en el viewport maya y escriba el comando completo (que se muestra a continuación) en el editor de scripts, recuerde presionar 'Ctrl-Enter' para ejecutar el comando.

 ls -sl;

Paso 15

El comando list genera una serie de cadenas que representan la lista completa de objetos seleccionados. Para que esta información sea útil para nosotros, necesitamos escribir el resultado del comando "listar" en una variable. Para hacer esto, ajuste el comando de lista en marcas de verificación (Nota, la marca de verificación, también llamada comillas inversas, generalmente se encuentra arriba de la tecla de tabulación del teclado ... asegúrese de no usar la marca de comillas simples al lado de introducir clave). Al ajustar un comando en marcas de verificación se traduce como "la salida de". Nuestro comando ahora debería verse así:

 string $ selectedObjects = 'ls -sl';

Paso 16

La variable $ selectedObjects es una sola cadena de texto. Lo que realmente necesitamos es algo que se llama una matriz de cadenas: una lista ordenada de cadenas que están contenidas en una sola variable. Para convertir nuestra cadena en una matriz de cadenas, use corchetes al declarar la variable:

 string $ selectedObjects [] = 'ls -sl';

Ahora, cuando nos referimos a la variable, podemos usar cualquiera de los arreglos:

 $ selectedObjects // todas las cadenas en la matriz

... O una cadena individual dentro de la matriz, al proporcionar un índice: la posición de la cadena que queremos dentro de la propia matriz. Los valores de índice en MEL siempre comienzan en cero como se muestra a continuación:

 imprimir $ selectedObjects [0]; // devuelve la primera cadena en la matriz print $ selectedObjects [2]; // devuelve la tercera cadena en la matriz

Paso 17

También necesitaremos una forma de averiguar cuántos objetos hay en la matriz. Puedes usar el comando "tamaño" para hacer eso. Vamos a crear una nueva variable para almacenar esta información. Un número entero está representado por un número entero, al que siempre se hace referencia en MEL como "int":

 int $ numSelectedObjects = 'tamaño ($ selectedObjects)';

Paso 18

Ahora necesitamos una manera de parentalizar cada objeto de acuerdo con su lugar en la matriz. Hay varias formas de hacer esto, pero por ahora usaremos un ciclo básico "para". Los bucles for son comunes en la programación como una forma de realizar una acción varias veces. La sintaxis de un bucle for que se ejecuta diez veces es la siguiente:

 para (int $ i = 0; $ i < 9; $i++) //action to be done ;

La estructura del bucle tiene tres partes. $ i = 0 define una variable entera, $ i

 para ($ i = 0; $ i < $numSelectedObjects; $i++)  //action to be performed ;

Paso 19

Ahora necesitamos usar un comando 'padre' para crear la cadena de jerarquía. La sintaxis de este comando es la siguiente:

 padre childObject parentObject;

Así que en nuestro caso, el comando padre sería:

 para ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[(i-1)] $selectedObjects[i]; ;

Paso 20

Con nuestro ciclo completado, ahora debemos deseleccionar el último objeto de la selección, usando el comando "seleccionar" con la marca "deseleccionar". Para calcular el índice del último objeto seleccionado, tomamos el número total de objetos y luego, como el índice de cualquier matriz en Maya comienza en 0, reste 1.

 seleccione -deseleccione $ selectedObjects [($ numSelectedObjects - 1)];

Paso 21

Y con eso, nuestro primer procedimiento ya está completo:

 // Hacer cadena global principal proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'tamaño ($ selectedObjects)'; para ($ i = 1; $ i < $numSelectedObjects; $i++)  parent $selectedObjects[($i - 1)] $selectedObjects[$i]; ; select -deselect $selectedObjects[($numSelectedObjects - 1)]; ;

Paso 22

Debajo de 'dt_makeParentChain', cree un nuevo procedimiento para separar los objetos seleccionados. El código debajo de los padres selecciona los objetos seleccionados para el mundo, que es lo mismo que eliminarlos..

 global proc dt_unParentSelected () parent -w; ;

Paso 23

Nuestro tercer procedimiento automatizará el proceso de mover el punto de pivote de un objeto al origen. Al igual que antes, comenzamos creando el esquema del procedimiento:

 proc global dt_pivotToOrigin () // acciones de procedimiento;

Paso 24

Luego usamos la misma técnica que en el primer procedimiento para escribir una lista de los objetos seleccionados en una variable:

 string $ selectedObjects [] = 'ls -sl';

Paso 25

Ahora tenemos que añadir en un bucle. Si bien podríamos usar el mismo tipo de bucle for que en el primer script, usemos un bucle para cada bucle. Un bucle "para cada" es una versión especializada del bucle for que se ejecuta una vez para cada valor en una matriz. También le permite escribir una variable que representa el valor del índice actual. La sintaxis se ve así:

 para ($ cada uno en $ arrayVariable) // haga esta acción con $ cada uno;

La variable $ cada contiene el valor del índice actual de la matriz. Para nuestro script, este es el aspecto que debe tener el código:

 para ($ thisObj en $ selectedObjects) // mueve el pivote de $ thisObj;

Esta misma técnica se puede utilizar para automatizar cualquier comando maya para cualquier número de objetos seleccionados.


Paso 26

Usando la variable $ thisObj ahora podemos seleccionar el objeto que actualmente está siendo observado por el bucle:

 seleccione -r $ thisObj;

Paso 27

Para mover el pivote al origen, podemos usar el comando "xform" y restablecer los indicadores -rp (rotatePivot) y -sp (scalePivot) a 0 en los ejes X, Y y Z:

 xform -ws -rp 0 0 0 -sp 0 0 0;

Paso 28

Los componentes principales de la secuencia de comandos ahora están terminados, y su código, que contiene los tres procedimientos, debe tener este aspecto:

 // Hacer cadena global principal proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'tamaño ($ selectedObjects)'; para ($ 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; ; ;

Paso 29

Ahora vamos a crear un cuarto procedimiento que usará los tres anteriores para crear una interesante progresión geométrica llamada "Espiral de Fermat", que se basa en la relación angular de la relación dorada, phi. Es una forma que se encuentra comúnmente en la naturaleza y sigue todo tipo de reglas geométricas interesantes. Comencemos escribiendo el pseudocódigo:

  • crear una esfera
  • crea 1,000 copias
  • cadena de padres todas las esferas
  • mover los objetos en el eje x
  • Mueve todos los puntos de pivote de la esfera al origen.
  • gire las esferas en Y 137.5 grados (el ángulo dorado)

Paso 30

Entonces, para empezar, vamos a crear un nuevo esquema de procedimiento:

 proc global dt_fermatSpiral () 

Paso 31

Ahora vamos a crear una esfera con 8 divisiones radiales y 8 de altura, y escribiremos los nodos de transformación y forma resultantes en una matriz de cadenas para que podamos hacer un seguimiento de ellos. La mayoría de los comandos que crean geometría generan dos cadenas: el nombre del nodo de transformación y el nombre del nodo de forma. En su mayor parte, desea trabajar con la cadena del nodo de transformación, que se almacenará en el índice [0] en la variable de matriz $ seedSphere creada a continuación:

 string $ seedSphere [] = 'polySphere -sx 8 -sy 8';

Paso 32

Ahora vamos a crear una variable de matriz de cadena vacía:

 string $ allSpheres [];

Paso 33

Luego abre un for-loop que se ejecuta 1,000 veces:

 para ($ i = 1; $ i<1000; $i++)

Paso 34

Ahora necesitamos duplicar nuestra esfera recién creada y escribir los nodos de transformación y forma resultantes en una variable:

 string $ duplicatedSphere [] = 'duplicate';

Paso 35

Aquí, agregamos el nombre de nuestro nodo de transformación duplicado al final de la matriz $ allSpheres. Puede usar el comando "tamaño" para determinar cuántos objetos ya están en la matriz, y usar el resultado como el índice para nuestro nuevo valor.

 $ allSpheres [tamaño ($ allSpheres)] = $ duplicatedSphere [0];

Paso 36

Aquí seleccionamos todas las esferas creadas y ejecutamos el comando de cadena principal que creamos anteriormente:

 seleccione -r $ allSpheres; dt_makeParentChain;

Paso 37

Después de criar las esferas juntas, las seleccionamos de nuevo y las movemos todas .05 en X usando el comando "mover":

 seleccione -r $ allSpheres; mueve 0.05 0 0;

Paso 38

Después de restablecer la posición de origen utilizando nuestro procedimiento "pivotToOrigin" creado previamente, seleccionamos las esferas una última vez y las giramos 137.5 grados en Y. Con eso hecho, ejecutamos nuestro script sin padre:

 dt_pivotToOrigin; seleccione -r $ allSpheres; gire 0 137.5 0; dt_unParentSelected;

Paso 39

Y eso completa nuestro procedimiento final. Entonces, nuestro script completo debería verse así:

 // Hacer cadena global principal proc dt_makeParentChain () string $ selectedObjects [] = 'ls -sl'; int $ numSelectedObjects = 'tamaño ($ selectedObjects)'; para ($ 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; ;

Paso 40

Y con eso hemos terminado! Guarde el script y vuelva a ejecutar el proceso 'rehash' / 'source' como se detalla arriba. Luego ingrese el siguiente comando en el editor de secuencias de comandos de Maya, presione 'Ctrl-Enter' y espere unos segundos:

 dt_fermatSpiral ();

Y ahí tienes la Espiral de Fermat, construida completamente con MEL. Intente jugar con diferentes ángulos, formas y transformaciones en el procedimiento final: puede obtener todo tipo de patrones interesantes!


Este tutorial es el día 2 de una serie - Ir al día 1.