Este tutorial explica los pasos necesarios para escribir y compilar un VEX Operator en Houdini.
Usaremos la simple operación de crear un generador de ondas aplicado a una superficie para mostrar un método simple de crear tus propias herramientas VEX. Omitiremos que Houdini ya dispone de un operador VEX Ripple propio y lo reinventaremos con nuestro propio código.
Acerca del VEX OperatorLos operadores de tipo VEX están disponibles en todos los contextos de Houdini y nos permiten ampliar la funcionalidad de la aplicación. Usualmente crearemos y editaremos los operadores en el VEX Builder Environmente de Houdini.
El VEX Builder crea el código fuente necesario para la llevar a cabo la compilación y se ocupa de instalar el nuevo operador en nuestra aplicación. La edición se puede hacer en el editor visual, que nos permite codificar y compilar herramientas complejas conectando simples nodos.
En elgun momento eso puede ser contraproducente, por ejemplo, si tenemos que crear muchas herramientas similares, o ya conocemos el algoritmo que queremos usar. Entonces una linea de código resulta máss fácil de escribir en un editor de texto que construir redes de nodos para funciones como esta, convirtiendose en aburrido y tedioso:
fn easeInSine t b c d = (
-c * cos (t/d * (180 / 2)) + c + b
)
PreparaciónPodemos crear y compilar operadores VEX con un simple editor de text y una consola de comandos para compilar un archivo .vfl con vcc. Esto es apropiado para usuarios avanzados puesto que ofrece mayor libertad, como en el caso de hacer un procesado por lotes de varios directorios llenos de archivos con código fuente.
Como esto suena bastante complicado, nosotros vamos a crear nuestro nuevo operador "Ripple" directamente en Houdini.
Comenzamos una nueva sesión y vamos a File > New Operator Type para abrir este cuadro de dialogo:
El Operator Name define el nombre interno de la herramienta. Es recomendable deifinir nuestro propio "nombre-enclave" para prevenir posibles conflictos de nombres con otros desarrolladores.
El Operator Label especifica el nombre que será mostrado en el menú contextual.
El Operator Style "VEX Type" crea un nuevo operador de tipo VEX para la
Network Type especificada. Como nuestro Ripple deformará geometría, elegiremos la opción
Geometry Operator.
En
Save to Library se define la ruta y el nombre del archivo donde el OTL (Operator Type Library) compilado se guardará. Podemos guardar diferentes operadores en el mismo archivo OTL construyendo una librería. Para propositos de prácticas instalaremos la librería solo en el actual HIPfile.
Le damos a
Accept: el operador se creará y el cuadro del Operator Type Properties se abrirá:

El operador ahora está listo para ser usado, aunque todavía no contiene nada.
Para completar la preparación crearemos un grid de prueba añadiendo un GridSOP y el RDG Ripple al objeto.
Pulsamos [TAB], escribimos
ge y añadimos un nodo Geometry. Entramos en él [ENTER] o [ i ] y borramos el fileOP. Añadimos entonces un gridOP [TAB]
gr [ENTER]. Pulsamos Shift+RMB sobre el output del gridOP y escribimos
rdg y pulsamos [ENTER].
Debemos tener algo como esto:

Ahora podemos añadir el código para nuestro operador VEX.
El código del VEXEn el Operator Type Properties vamos a la pestaña VEX Code. Este es un simple editor de texto que nos permite escribir y editar el código:

VEX está basado en sintaxis de C, y un operador es basicamente una simple función.
sop define el contexto donde la función trabajará - como nuestro operador se aplicará a un "surface operator", entonces es
sop.
rgd_ripple es el nombre de la función. Por defecto no hay argumentos definidos y entre los parentesis está vacío. Lo mismo para las llaves, cuyo interior es el cuerpo de la función. Ahora también está vacío, por lo tanto no sucedera nada.
La onda (Ripple)La ondulanción es una función simple basada en el seno (
sinus) de la onda. Empezaremos creando el código de la onda y entonces añadiremos funciones adicionales.
El seno de una onda usualmente conlleva tres parámetros: frecuencia, velocidad y amplitud.

La amplitud define la altura. La frecuencia, la distancia entre las dos "montañas". La velocidad define la rápidez del movimiento de las ondas. Esta función sería algo como esto:
f(x) = sin(x * frequency + speed) * amplitudeCalcularemos la distancia de cada punto de la malla (grid) y el centro de la misma, y usaremos este valor como
x en nuestra función. El resultado será el mismo para todos los puntos con la misma distancia, generando una ondulación radial.
Primero añadimos los argumentos para nuestra función:
sop
rdg_ripple( float frequency = 50;
float speed = 0;
float amplitude = 1;)
{
}
La palabra
float le dice al compilador el tipo de argumento que será usado y además le asignamos un valor por defecto
El cuerpo de la función será este:
sop
rdg_ripple( float frequency = 50;
float speed = 0;
float amplitude = 1;)
{
vector offset = {0, 0, 0};
float offset_y = 0;
float dist = length(P);
offset_y = sin(dist * frequency + speed) * amplitude;
setcomp(offset, offset_y, 1);
P += offset;
}
Primero, definimos offset como vector con el valor (0,0,0) y offset_y como float.
P es una variable global en el contexto
sop y bloquea la posición del punto procesado. Calcularemos la longitud de P, que es la misma que
length(vector(0,0,0)-P), y usamos esto en la función del seno de la onda. El offset resultante es sumando a la posición original del punto.
Para ver una lista de todas las variables globales consultar la ayuda de Houdini.
Una vez apliquemos los cambios, la malla será deformada. Se verá una malla rara si no hay suficiente subdivisión y el valor del amplitude es demasiado alto para el tamaño por defecto de la malla.
Añadimos detalle a la malla, aumentando el valor de
rows y
columns, y ajustamos la amplitud de la onda para ver algo como esto:
El interfazVEX ofrece los denominados
pragmas para definir el aspecto del interfaz. Serán añadidos siempre antes que la declaración de la función. Añadiremos los pragmas etiquetando los argumentos, definiendo sus rangos y combinandolos en una pestaña:
#pragma group Basic frequency speed amplitude
#pragma label frequency "Frequency"
#pragma range frecuency 0 1
#pragma label speed "Speed"
#pragma label amplitude "Amplitude"
#pragma range amplitude -1 1
sop
rdg_ripple( float frequency = 50;
#pragma group groupname parameter1 parameter2... parameterN combina la lista de argumentos en una pestaña.
#pragma label parameter "my label" define el nombre de la etiqueta para el parámetro.
#pragma range min max define el rango para el parámetro.
El interfaz tiene un aspecto mas amigable ahora:

Los
Pragmas son una buena razón para querer escribir nuestro código VEX en un editor de texto y compilarlo usando la linea de comandos con el compilador VEX: esto ofrece la posibilidad de crear un proceso por lotes de versiones diferentes de nuestra herramienta, reemplazar etiquetas y rangos desde un archivo de texto o desde una base de datos, procesando el codigo fuente usando un proprocesador personalizado.
Podemos ver una lista de todos las directivas de preproceso consultando la ayuda de Houdini
ConclusiónEl RDG Ripple puede ser facilmente ampliado para ofrecer controles adicionales, como un centro variable,
clamping o
decay de la onda. Puedes implementar esto como un ejercicio o simplemente usando los archivos adjuntos:
La escena de ejemplo:
rdg_ripple_sample.hipncEl código fuente:
rdg_ripple.vflLa herramienta completa:
OP_rdg_ripple.otlUna ondulación no es nada extraordinario evidentemente, y puede ser facilmente implementado en un pointSOP, CHOPS y de mil formas diferentes. Pero es un sistema conciso usando un conocido comportamiento para unos primeros pasos con VEX.