Manual de Blender XV extendiendo Blender

extendiendo Blender. Al contrario de muchos programas con los que puedes estar familiarizado, Blender no es monolítico y estático. Puedes extender sus funcionalidades incluso sin tener que modificar las fuentes y recompilarlas. Hay dos maneras de realizar dicha extensión: scripts en Python y plugins, siendo el primero de los dos el preferido y mayormente usado. Esta parte describira ambas técnicas.
capítulos .

  • scripts en Python.
  • sistema de plugins de Blender

scripts en Python .

Blender tiene una característica muy poderosa que a menudo es pasada por alto. Esta característica es un intérprete de Python totalmente funcional. Esto le permite a cualquier usuario añadir funcionalidades a Blender escribiendo un simple script de Python. Python es un lenguaje de programación interpretado, interactivo, y orientado a objetos. Incorpora módulos, excepciones, tipeado dinámico, tipo de datos dinámicos de muy alto nivel y clases. Python combina un gran poder con una sintaxis muy sencilla. Esta expresamente diseñado para ser usado como una extensión para las aplicaciones que necesiten una interfaz programable, y esto es por lo que Blender lo utiliza. De las dos maneras que tiene de extender Blender, siendo la otra los plugins binarios, la tratada aquí los script de Python es la más poderosa, versátil, más sencilla de comprender y robusta. Realmente es preferible usar Python que escribir un plugin. Realmente los script de Python tenían unas funcionalidades limitadas en Blender 2.25, la última de las versiones que liberó nan. Cuando Blender se hizo código abierto muchos de los desarrolladores que se movían alrededor de la fundación lo eligieron para trabajar y, junto con el cambio de UI, el Api de Python es probablemente la parte de Blender que ha tenido un desarrollo más grande. Una total reorganización de lo que existía fue llevada a cabo y muchos nuevos módulos fueron añadidos. Dicha evolución está aún en proceso y una mejor integración esta por venir en las próximas versiones de Blender. Blender tiene una ventana texto junto con los otros tipo de ventana la cual es accesible vía el botón del menú tipos de ventana o a través de shift-f11. Una ventana de texto recién abierta es gris y esta vacía, y tiene una barra de herramientas muy sencilla (barra de herramientas de texto.). De izquierda a derecha están el botón estándar de selección de ventana y el menú ventana. Luego está el botón de pantalla completa, seguido por un botón que muestra/oculta el número de líneas del texto y el botón menú.

Barra de herramientas de texto.

El botón menú () permite seleccionar que buffer de texto tiene que ser mostrado, y también le permite crear un nuevo buffer o cargar un fichero de texto. Si elige cargar un fichero en la ventana texto temporalmente se crea una ventana de selección de ficheros, con las funciones usuales. Una vez que el buffer de texto está en la ventana texto, esta se humilde en un editor de texto muy simple. Escribir en el teclado provoca que aparezca texto en el buffer de texto. Como siempre con presionar LMB arrastrar y liberar LMB se selecciona el texto. Los siguientes comandos del teclado son aplicables:

  • alt-c o Control-c – Copia el texto marcado al portapapeles;
  • alt-x o Control-x – Corta el texto marcado al portapapeles;
  • alt-v or Control-v – Pega el texto marcado desde portapapeles en la posición del cursor en la ventana texto;
  • alt-s – Guarda el texto como un fichero de texto, una ventana de selección de ficheros aparecerá;
  • alt-o – Carga un texto, una ventana de selección de ficheros aparecerá;
  • alt-f – Emergerá la herramienta buscar;
  • shift-alt-f o RMB – Emergerá el menú fichero para la ventana de texto;
  • alt-j – Emergerá un panel donde puede especificar un número de línea para situar el cursor;
  • alt-p – Ejecuta el texto como un script de Python;
  • alt-u – Deshacer;
  • alt-r – Rehacer;
  • Control-r – Reabrir (recargar) el buffer actual;
  • alt-m – Humilde el contenido de la ventana de texto en texto 3d (max. 100 caracteres),

el portapapeles de Blender que corta/copia/pega esta separado del portapapeles de Windows así que no podrá copiar desde o hacia Blender. Para acceder a su portapapeles de Windows utilice shift-Control-c shift-Control-v. Para eliminar un buffer de texto tan sólo presione el botón x, próximo al nombre del buffer, tal y como hace para los materiales, etcétera. La más importante combinación de teclas es alt-p la cual hace que el contenido del buffer sea pasado al intérprete de Python de Blender. La siguiente sección le mostrara un ejemplo de script de Python. Antes de que continúe tenga en cuenta que Blender viene con un intérprete de Python muy sencillo con unos pocos módulos totalmente específicos de Blender, que están descritos en la **referencia**.
otros usos para la ventana de texto: la ventana de texto se utiliza también cuando quieres compartir tus ficheros (*.blend) con la comunidad o con tus amigos. Puedes usarla para escribir un texto aclaratorio de los contenidos de tu fichero. Esto es mucho más interesante que tener dicho fichero en un archivo separado. Asegúrate de mantenerlo visible mientras salves tu fichero. Si compartes el archivo con la comunidad y quieres hacerlo bajo alguna licencia puedes escribir dicha licencia en una ventana texto. Para tener acceso a los módulos estándar de Python necesitarás tener instalado Python. Puedes descargarlo de Python programming language – Oficial website.
configurando la variable del sistema pythonpath .

Asegúrate de comprobar en blender.org – Home cual versión exacta de Python es con la que fue construida Blender para evitar posibles problemas de compatibilidad. Blender también debe conocer donde se ha realizado dicha instalación. Esto se hace definiendo una variable entorno pythonpath.
configurando pythonpath en Windows 95,98,me .

Una vez que haya instalado Python en, digamos, c:\python22 debe editar el fichero c:\autoexec. Bat con su editor de textos favorito y añadir una linea:

Código:

Set pythonpath=c:\python22;c:\python22\dlls;c:\python22\lib;c:\python22\lib\lib-tk


Y reiniciar el sistema.
configurando pythonpath en winnt,2000,XP .

Una vez que haya instalado Python en, digamos, c:\python22. Vaya al icono mi PC en el escritorio, RMB y seleccione properties. Seleccione la pestaña advanced y presione el botón environment variables. Debajo de la caja de variables del sistema, (la segunda caja), pinche en new. Si no eres administrador posiblemente no seas capaz de hacer esto. En este caso pinche en new en la caja superior. Ahora, en la caja variable name (nombre de variable), escriba pythonpath y en la caja variable value (valor de la variable), escriba:

Código:

C:\python22;c:\python22\dlls;c:\python22\lib;c:\python22\lib\lib-tk


Pulse ok repetidamente para salir de todos los diálogos. Dependiendo del sistema operativo quizás tengas que reiniciar.
configurando pythonpath en Linux y otros unixes .

Normalmente tendrás Python ya instalado. Si no fuese así, hazlo. Ahora solo tendrás que descubrir dónde está instalado. Esto es sencillo, solo arranque una Shell interactiva de Python simplemente abriendo una Shell y escribiendo Python en ella. Escriba los siguientes comandos:

Código:

>>> import Sys.
>>> print Sys, Path


Y anote lo que se muestre por pantalla que debería ser algo como.

Código:

[, /usr/local/lib/python2.2, /usr/local/lib/python2.2 /plat-linux2, /usr/local/lib/python2.0/lib-tk, /usr/local/lib/python2.0/lib-dynload, /usr/local/lib/python2.0/site-packages]


Añada esto a su fichero favorito rc (fichero de configuración) como una variable de entorno. Por ejemplo, añada en su.bashrc la siguiente línea.

Código:

Export pythonpath=/usr/local/lib/python2.2:/usr/local/lib/python2.2/plat-linux2:/usr/local/lib/python2.2/lib-tk:/usr/local/lib/python2.2/lib-dynload:/usr/local/lib/python2.0/site-packages


Todo en una única línea. Abra una nueva Shell, o salga e introduzca de nuevo el login.
un ejemplo funcional de Python .

Ahora que ha visto que Blender es extensible vía script de Python y que tiene los elementos básicos para el manejo de scripts y sabe cómo lanzarlos, antes de estrujar su cerebro con la Api de Python echemos un vistazo a un pequeño ejemplo. Realizaremos un pequeño script para producir polígonos. Este script duplica lo que hace spaceadd>>Mesh>>circle, pero creara polígonos rellenos, no sólo con el perímetro exterior. Para hacer el script aún más completo este exhibirá una interfaz gráfica de usuario (Gui) escrita completamente a través de la Api de Blender.
cabeceras, importación de los módulos y variables globales .

Las primeras 32 líneas de código son mostradas abajo.
cabecera del script.

Código:

001 ######################################################
002 #
003 # script demostración para la guía de Blender 2.3
004 #
005 ###################################################s68
006 # este script genera polígonos. Es bastante inútil.
007 # ya que puedes hacer lo mismo con ad->Mesh->circle.
008 # pero es un buen ejemplo y, además los.
009 # polígonos están rellenos.
010 ######################################################
011
012 ######################################################
013 # importación de los módulos.
014 ######################################################
015
016 import Blender.
017 from Blender import nmesh.
018 from Blender. Bgl import *
019 from Blender. Draw import *
020
021 import math.
022 from math import *
023
024 # parámetros del polígono.
025 t_numberofsides = create (3)
026 t_radius = create (1.0)
027
028 # events.
029 event_noevent = 1
030 event_draw = 2
031 event_exit = 3
032


.

Después de necesarios comentarios que indican lo que hace el script se encuentra la importación de los módulos de Python (líneas 016-022). Blender es el módulo principal de la Api de Python de Blender. Nmesh es el módulo que proporciona acceso a las mallas de Blender, mientras que BGL y draw dan acceso a las funciones y constantes de OpenGL y a la interfaz de ventanas de Blender, respectivamente. El módulo math es el módulo matemático de Python, pero dado que ambos módulos math y os están incluidos dentro de Blender no necesita una completa instalación de Python para usarlos. Los polígonos se definen a través del número de lados y de su radio. Estos parámetros tienen valores que deben ser definidos por el usuario a través del GUI, líneas (025-026), con lo que se deben crear dos botones genéricos, con sus valores por defecto. Finalmente, los objetos GUI trabajaran con eventos y también los generaran. Los identificadores de los eventos son enteros que serán definidos por el programador. Es una buena práctica utilizar nombres fáciles de recordar para los eventos, ¿cómo se hace en la líneas (029-031).
dibujando el GUI .

El código fuente que se encarga del dibujado del GUI está en la función draw (dibujo) (dibujando el GUI).
dibujando el GUI

Código:

033 ######################################################
034 # dibujando el GUI.
035 ######################################################
036 Def draw():
037 global t_numberofsides.
038 global t_radius.
039 global event_noevent,event_draw,event_exit.
040
041 ########## titles.
042 glclear(gl_color_bufer_bit)
043 glrasterpos2d(8, 103)
044 text(demo polygon script)
045
046 ######### parameters GUI buttons.
047 glrasterpos2d(8, 83)
048 text(parameters:)
049 t_numberofsides = number(no, of sides:, event_noevent, 10, 55, 210, 18, 050 t_numberofsides, val, 3, 20, number of sides of out polygon),
051 t_radius = slider(Radius:, event_noevent, 10, 35, 210, 18, 052 t_radius, val, 0.001, 20.0, 1, Radius of the polygon),
053
054 ######### draw and exit buttons.
055 button(draw,event_draw, 10, 10, 80, 1
056 button(exit,event_exit, 140, 10, 80, 1
057


.

Las líneas (037-039) proporcionan acceso a los datos globales. El verdadero meollo del asunto comienza a partir de las líneas (042-044). La ventana de OpenGL es inicializada, y su actual posición configurada a x=8, y=103. El origen de esta referencia es la esquina inferior izquierda de la ventana de scripts. Entonces el título demo polygon script es mostrado. Una cadena de caracteres es escrita en las líneas (047-04, entonces se crean los botones para introducir los parámetros. El primero (líneas 049-050) es un botón numérico, exactamente como esos que hay en la ventana de botones de Blender. Para comprender todos los parámetros por favor diríjase a la referencia de la Api. Básicamente está la etiqueta del botón, el evento generado por el botón, su localización (x, y) y sus dimensiones (anchura, altura), su valor, que es un dato perteneciente al objeto mismo, los valores máximos y mínimos permitibles y un texto que aparecerá como ayuda mientras sitúa el cursor sobre el botón, como una etiqueta de ayuda. Las líneas (051-052) definen un botón numérico con un deslizador, con una sintaxis muy similar. Las líneas (055-056) finalmente crean el botón draw (dibujar)el cual creara los polígonos y un botón exit (salir).
manejando eventos .

El GUI no se ha dibujado, y no trabajara, hasta que se escriba un manejador de eventos apropiado y se registre (manejando eventos).
manejando eventos

Código:

058 Def event(evt, val):
059 if (evt == qkey and not val):
060 exit()
061
062 Def Bevent(evt):
063 global t_numberofsides.
064 global t_radius.
065 global event_noevent,event_draw,event_exit.
066
067 ######### manages GUI events.
068 if (evt == event_exit):
069 exit()
070 elif (evt== event_draw):
071 polygon(t_numberofsides, val, t_radius, val)
072 Blender. Redraw()
073
074 register(draw, event, bevent)
075


.

Las líneas (058-060) definen el manejador de eventos del teclado, en este caso respondiendo a la que con una sencilla llamada a exit(). Hay más interesantes líneas en (062-072) donde se manejan los eventos del GUI. Cada vez que un botón del GUI es usado esta función es llamada, con el número de evento definido en el los parámetros del botón. El núcleo de esta función es una estructura de selección que ejecuta diferentes códigos dependiendo del número de evento. Como última llamada, se invoca a la función register. Esto efectivamente dibuja el GUI y comienza el bucle que captura los eventos.
manejando mallas .

Finalmente, cabecera del script muestra la función principal, la que crea el polígono. Es una simple edición de la malla, pero muestra muchos puntos importantes de la estructura interna de datos de Blender.
cabecera del script.

Código:

076 ######################################################
077 # cuerpo principal.
078 ######################################################
079 Def polygon(numberofsides,Radius):
080
081 ######### creates a new Mesh.
082 poly = nmesh. Getraw()
083
084 ######### populates it of vértices.
085 for i in range (0,numberofsides):
086 phi = 3.141592653589 * 2 * i / numberofsides.
087 x = Radius * cos(phi)
088 y = Radius * sin(phi)
089 z = 0
090
091 v = nmesh. Vert(x y, z)
092 poly, vértices, append(v)
093
094 ######### adds a new vertex todo the center.
095 v = nmesh. Vert(0,0,0.)
096 poly, vértices, append(v)
097
098 ######### connects the vértices todo form Faces.
099 for i in range (0,numberofsides):
100 f = nmesh. Face ()
101 f, v, append(poly, vértices[i])
102 f, v, append(poly, vértices[(i+1)%numberofsides])
103 f, v, append(poly, vértices[numberofsides])
104 poly, Faces, append(f)
105
106 ######### creates a new object with the new Mesh.
107 polyobj = nmesh. Putraw(poly)
108
109 Blender. Redraw()


.

La primera línea importante aquí es la número (082). Aquí hay un nuevo objeto malla, donde se crea el poly polígono. El objeto malla esta constituido de una lista de vértices y de una lista de caras, además de otras interesantes cosas. Para nuestros propósitos los vértices y la lista de caras será lo que necesitaremos. Por supuesto la malla recientemente creada ésta vacía. El primer bucle (lines 085-092) calculara la localización x y, z de los vértices numberofsides necesarios para definir el polígono. Para un plano su coordenada z será cero para todos los vértices. La línea (091) llama al método vert de nmesh para crear un nuevo objeto vértice de coordenadas (x y, z). Tal objeto es entonces añadido (linea 096) en la lista de vértices vértices de la malla poly polígono. Finalmente en las líneas (095-096) un último vértice es añadido al centro. Las líneas (099-104) conectan los vértices para crear las caras. No será necesario crear todos los vértices primero y luego las caras. Podrás crear una nueva cara tan pronto como todos los vértices estén disponibles. La línea (100) crea una nueva cara. Un objeto cara tiene su propia lista de vértices v (hasta 4) definidos. Las líneas (101-103) añaden 3 vértices a la lista f, v originalmente vacía. Los vértices son dos vértices adyacentes del polígono y el vértice central. Estos vértices deben de ser tomados de la lista de vértices vértices de la malla. Finalmente la línea (104) añade la cara recién creada a la lista de Faces caras de nuestra malla poly polígono.
conclusiones .

Si crea su fichero polygon, py conteniendo el código anteriormente descrito y lo carga dentro de una ventana de texto de Blender, como a aprendido en la sección anterior y presiona alt-p en dicha ventana para lanzarlo vera como la ventana desaparece y se vuelve gris. En la esquina inferior izquierda el GUI se dibujara (el GUI de nuestro ejemplo.).

El GUI de nuestro ejemplo.

Seleccionando, por ejemplo, 5 vértices y un radio de 0.5, y presionando el botón draw aparecerá un pentágono en el plano xy de la ventana 3d (el resultado de nuestro script de ejemplo.).

El resultado de nuestro script de ejemplo.
referencia de Python .

La documentación de referencia del lenguaje de programación Python para Blender es un libro en sí mismo. Por razones de espacio no se incluye en este documento. aquí está
scripts de Python .

Hay más de 100 scripts para Blender disponibles en internet. Como los plugins, los scripts son muy dinámicos, cambiando su interfaz, sus funcionalidades y su localización en internet muy rápidamente, así que, para una lista actualizada de ellos por favor dirijase a uno de estos dos sitios, blender.org – Home o blender artists forums – Powered by vbulletin.
sistema de plugins de Blender .

Esta sección muestra una referencia detallada de cómo escribir plugins de secuencia y de textura para Blender.
escribiendo un plugin de textura .

En esta sección escribiremos un plugin de textura básico y después enseñaremos a usarlo. Los elementos básicos detrás de un plugin de textura consisten en que tú estas dando algunos valores de entrada, tales como posición, etc y alguna información más. Entonces dependiendo del tipo de plugin de textura se te devolverá información sobre la intensidad, el color y/o las normales. Tanto los archivos necesarios para desarrollar los plugins como unos pocos plugins se pueden encontrar en el directorio Blender/plugins. Alternativamente puede obtener más plugins de http://www.cs.umn.edu/~mein/blender/plugins los plugins son utilizados (cargados/llamados) en Blender a través de Dlopen(). Para aquellos que no están familiarizados con el sistema Dlopen diremos que este permite a un programa (blender) usar un objeto compilado como si éste fuese parte del programa mismo, similar a cuando se enlazan librerías dinámicamente, exceptuando que el objeto a cargar se determina cuando se está ejecutando el programa. La ventaja de usar el sistema Dlopen para los plugins consiste en que es muy rápido acceder a una función y, además no hay sobrecarga en la interfaz del plugin, lo cual es crítico cuando (como en el caso de los plugins de textura) el plugin se puede llamar varios millones de veces en un único render. La desventaja de este sistema es que el plugin funciona como si realmente fuese parte de Blender, con lo que si el plugin se muere, Blender muere. Los ficheros de cabecera que se encuentran en el subdirectorio plugin/include/ de la instalación de Blender están documentados mostrando las funcionalidades que se proporcionan a los plugins. Dichas funcionalidades incluyen las funciones de las librería imbuf para cargar y trabajar con imágenes y buffers de imagen, y funciones de ruido y turbulencia para un texturizado consistente.
especificación.

  • #include <plugin, h>

todos los plugins de Blender deben incluir este fichero cabecera, que contiene todas las estructuras y definiciones necesarias para trabajar correctamente con Blender.

  • char name[]=tiles;

un string (cadena de caracteres) conteniendo el nombre del plugin, este valor se usara para indicar el título de la textura en la ventana de botones de textura

  • define nr_types 2 char stnames[nr_types][16]= {square, deformed};

a los plugins se les permite tener subtipos separados para variaciones mínimas en algoritmos – Por ejemplo, la textura clouds (nubes) que está por defecto en Blender tiene los subtipos default y color. Nr_stypes debería ser definido con el número de subtipos que el plugin requiera y, además a cada subtipo se le tiene que dar un nombre. Cada plugin debe tener al menos 1 subtipo y el nombre de ese subtipo.

  • varstruct varstr[]= {.};

Varstr contiene toda la información que Blender necesita para mostrar los botones del plugin. Los botones para los plugin pueden ser de tipo numérico para introducir datos, o de tipo texto para introducir comentarios u otra información. Se pueden utilizar como máximo 32 variables en los plugins. Cada estructura varstruct consta de un tipo, un nombre, un rango de información y una nota emergente sobre la herramienta. el tipo define el tipo de dato para cada botón, y la manera en la que se muestra dicho botón. Para botones numéricos este valor debería ser una combinación (ored) de int o flo para el formato del número y num, Numsli o Tog para el tipo de botón. Los botones de texto son de tipo label. el nombre es lo que se mostrara en el botón y está limitado a 15 caracteres. el rango de información consiste en 3 números reales que definen los valores máximo, mínimo y por defecto para el botón. Para los botones Tog el mínimo es configurado cuando el botón se haya presionado y el máximo cuando esta sin presionar. la nota emergente (tol tip) es una cadena de caracteres que se mostrara cuando el puntero esté encima del botón (si el usuario tiene los tool tips activos). Tiene un límite de 80 caracteres y se tiene que poner a null () si no se utiliza.

  • typedef structure cast {.};

la estructura cast se usa en la llamada a la función doit, y simplifica el acceso de cada plugin a los valores de los datos. La estructura cast debería contener, en este orden, un entero o número real por cada botón definido en VAR(*.str), incluidos los botones de texto. Típicamente deberían tener el mismo nombre que el botón para permitir una búsqueda o una referencia sencilla.

  • float result[8];

el Vector result se usa para enviar y recibir información al plugin. Los valores de result están definidos de esta manera: result índice significado rango result[0] valor de la intensidad 0.0 todo 1.0 result[1] valor del color rojo 0.0 todo 1.0 result[2] valor del color verde 0.0 todo 1.0 result[3] valor del color azul 0.0 todo 1.0 result[4] valor del color transparente (alpha) 0.0 todo 1.0 result[5] valor del desplazamiento normal en x result[6] valor del desplazamiento normal en y result[7] valor del desplazamiento normal en z el plugin siempre devuelve el valor de la intensidad. Devolver el color (RGB) o la normal es opcional, y se debería indicar con el return de la función doit(), siendo 1 para (RGB) y 2 para (normal). Antes de que se llame al plugin, Blender asigna el resultado de renderizar normalmente en result[5], result[6] y result[7].

  • float cfra

el valor cfra actualizado por Blender a su valor actual antes de que todos los renders se hagan. Este valor es el número de frame +/-.5 dependiendo de las configuraciones del campo.

  • plugin_tex_doit Prototype

la función plugin_tex_doit debería ser prototipada para que pueda ser usada por la función getinfo. No necesita cambiar esta línea.

  • plugin_tex_getversión

esta función debería estar en cada plugin para que pueda ser cargado correctamente. No debería cambiar esta función.

  • plugin_but_changed

esta función se usa para pasar información sobre que botones cambia el usuario en la interfaz. La mayoría de los plugins no necesitan esta función, solo cuando el interfaz permita al usuario modificar algunas variables que furze al plugin a recalcularse (una tabla hash aleatoria, por ejemplo).

  • plugin_init

si fuese necesario los plugins pueden utilizar esta función para inicializar datos internos. Nota: esta función de iniciación se puede llamar varias veces si el mismo plugin de textura se copia. En esta función, no inicialice datos globales específicos a una única instancia de un plugin.

  • plugin_getinfo

esta función se usa para comunicar información a Blender. Nunca deberías cambiarla.

  • plugin_tex_doit

la función doit es la responsable de devolver información a Blender sobre píxeles requeridos. los argumentos

  • int stype

este es el número de subtipos seleccionados, mira las entradas nr_types y char stypes anteriores.

  • cast *cast

la estructura cast que contiene los datos del plugin, mira la entrada cast anterior.

  • float *texvec

esto es un puntero a 3 float, los cuáles son las coordenadas para las cuales un valor de la textura debe retornarse.

  • float *dxt float *dyt

si los punteros son no-null apuntaran a 2 vectores (2 arrays de 3 float) que definen el tamaño del valor textura requerida en el espacio píxel apuntan solo a no-null cuando el osa esté activado, y se usan para calcular adecuadamente el antialiasing. La función doit debería rellenar el array result y devolver 0, 1, 2 o 3 dependiendo de que valores hayan rellenado el array. La función doit debería siempre rellenarse con el valor intensidad. Si la función asigna el valor color debería devolver 1, si asigna el valor normal debería devolver 2 y si asigna todo debería devolver 3.
interacción texturas/materiales .

Blender es algo diferente de la mayoría de paquetes 3d en lo que se refiere a la separación lógica entre materiales y textura en Blender las texturas son objetos que devuelven ciertos valores, son generadores de señales de hecho. Los materiales controlan el mapeado de texturas en los objetos, lo que está afectado, en que cantidad, en que manera, etc. Plugins adecuadamente diseñados deberían incluir únicamente variables que, afecten a la señal devuelta no al mapeado de ella. Es mejor incluir botones para controlar el escalado, el rango, los ejes, etc únicamente cuando hagan a la textura más fácil de usar (en caso del botón tamaño en el plugin tiles) o aceleran el cálculo (los subtipos intensity/color/Bump en el plugin clouds2). De otra manera los botones del material hacen a esos botones redundantes, y la interfaz incrementa innecesariamente su complejidad.
un plugin de textura genérico:

Código:

#include plugin, h.
/* nombre de la textura */
Char name[24]=.
#define nr_types 3
Char stnames[nr_types][16]= {intens,color, Bump};
/* estructura para los botones, * butcode name default min max 0
*/.

Varstruct varstr[]= {
{num|flo, const 1, 1.7, -1.0, 1.0, }, };
Typedef structure cast {
Float a;
} cast.

Float result[8];
Float cfra;
Int plugin_tex_doit(int, cast*, float*, float*, float*).
/* funciones fijas */
Int plugin_tex_getversión(Void) {
Return b_plugin_version;
}.

Void plugin_but_changed(int but) { }.

Void plugin_init(Void) { }.

Void plugin_getinfo (plugininfo *info) {
Info->name= name;
Info->stypes= nr_types;
Info->nvars= sizeof(varstr)/sizeof(varstruct).

Info->snames= stnames[0];
Info->result= result;
Info->cfra= &cfra;
Info->varstr= varstr.

Info->init= plugin_init;
Info->tex_doit= (Texdoit) plugin_tex_doit;
Info->call-back= plugin_but_changed;
}.

Int plugin_tex_doit(int stype, cast *cast, float *texvec, float *dxt, float *dyt) {.

If (stype == 1) {
Return 1;
} if (stype == 2) {
Return 2;
}
Return 0;
}


nuestras modificaciones: .

El primer paso es tener un plan. Para que sirve este plugin y como los usuarios interactúan con él. Para este ejemplo crearemos una textura sencilla que crea un simple patrón de ladrillos. Ahora copiaremos nuestro plugin genérico al archivo Cube, c y rellenaremos los espacios vacíos. Es siempre una buena idea añadir algunos comentarios. Lo primero de todo es decir a los usuarios que hace el plugin, de dónde pueden obtener una copia, con quién deberían contactar para mejorarlo o para informar de fallos y cual es la licencia del código. Cuando uses comentarios asegúrate de usar /* */. Los plugins están en c y algunos compiladores de c no aceptan los comentarios con el estilo de C++ (//).

Código:

/*
Descripción: este plugin es un ejemplo de plugin de textura que crea.

Un simple patrón de ladrillos.

Toma dos valores, el tamaño brik y el tamaño montar, el tamaño brik es el tamaño de cada ladrillo, el tamaño montar es el tamaño que hay entre los ladrillos (cemento).

Autor: kent mein (mein@cs, umn, edu)
Sitio web: <nowiki>http://www.cs.umn.edu/~mein/Bender/plugins.

Licencia: dominio público.
Última modificación: tue oct 21 0:57:13 cdt 2003
*/
/nowiki>


Lo siguiente que necesitamos será rellenar el nombre, realmente debería ser el mismo que tú fichero.c, preferiblemente descriptivo, con menos de 23 caracteres, sin espacios y todas las letras en minúsculas.

Código:

char name[24]= Cube, c;


.

Vamos a mantener este plugin simple, solo tiene un tipo que está relacionado con la intensidad. Así que necesitamos lo siguiente:

Código:

#define nr_types 1
Char stnames[nr_types][16]= {default};


.

Para nuestro interfaz vamos a permitir a la gente cambiar el tamaño del ladrillo, el espaciado entre ellos y los valores de intensidad devueltos por el ladrillo y el espaciado entre ladrillos. Para ello necesitamos modificar varstr y cast. Cast debería tener una variable por cada entrada que haya en varstr.

Código:

/* estructura para los botones, * butcode name default min max tool tip.
*/
Varstruct varstr[]= {
{num|flo, brick. 8, 0.1, 1.0, size of cell}, {num|flo, montar. 1, 0.0, 0.4, size of boarder in cell}, {num|flo, brik int, 1, 0.0, 1.0, color of brick}, {num|flo, montar int, 0, 0.0, 1.0, color of montar}, }.

Typedef structure cast {
Float brick, montar, bricki, mortari;
} cast;


.

Ahora rellenaremos la función plugin_tex_doit. Básicamente queremos romper nuestra textura en bloques que estarán formados de un ladrillo y del espaciado a lo largo de las aristas del ladrillo (cemento) y entonces determinar si estamos en el ladrillo o estamos en el cemento. El código siguiente hace esto.

Código:

int plugin_tex_doit(int stype, cast *cast, float *texvec, float *dxt, float *dyt) {
Int c[3];
Float pos[3], Cube.
/* configura el tamaño de nuestro bloque */
Cube = cast->brik + cast->montar.
/* necesitamos determinar donde estamos dentro del ladrillo actual. */
C[0] = (int)(texvec[0] / Cube),
C[1] = (int)(texvec[1] / Cube),
C[2] = (int)(texvec[2] / Cube).

Pos[0] = abs(texvec[0] - (c[0] * Cube)),
Pos[1] = abs(texvec[1] - (c[1] * Cube)),
Pos[2] = abs(texvec[2] - (c[2] * Cube)).
/* descubrir si estamos en una posición de cemento o no. */
If ((pos[0] <= cast->montar) || (pos[1] <= cast->montar) ||
(pos[2] <= cast->montar)) {
Result[0] = cast->mortari;
} else {
Result[0] = cast->bricki;
}
Return 0;
}


.

Una cosa que destacar, la función abs esta definida en una cabecera que está en plugins/include. En ese lugar hay otras funciones de uso común por lo que sería aconsejable que echará un vistazo allí.
compilando: .

Bmake es una utilidad simple (shell script) para ayudar a la compilación y desarrollo de plugins, y puede encontrarse en el subdirectorio plugins del directorio de instalación de Blender. Se invoca mediante: Bmake (nombre_plugin, c) e intentara enlazar las librerías adecuadas y compilar adecuadamente para su sistema el archivo c especificado. Si usted esta intentando desarrollar plugins en una máquina Windows, Bmake puede no funcionar en este caso, debería usar lcc. Puede usar lo siguiente para compilar un plugin con lcc, asumiendo que usted tiene sus plugins en c:\blender\plugins: aquí tiene un ejemplo de cómo se compilaría el plugin de textura sinus, c. Abra una ventana dos y haga lo siguiente: (nota: asegúrese de que el directorio lcc\bin está en su Path).

Código:

CD c:\blender\plugins\texture\sinus.

Lcc -ic:\blender\plugins\include sinus, c.

Lcclnque -dll sinus, obj c:\blender\plugins\include\TeX.Def.

Implib sinus, dll


escribiendo un plugin de secuencia .

En esta sección escribiremos un plugin de secuencia básico y luego seguiremos los pasos para usar un plugin de secuencia. Las bases de un plugin de secuencia son: se reciben unas entradas (1-3 buffers de imagen de entrada, así como alguna otra información), y se produce como resultado un buffer de imagen de salida. Todos los archivos necesarios para el desarrollo de plugins, así como unos pocos plugins de ejemplo pueden encontrarse en el directorio Blender/plugins. Puede conseguir adicionalmente un puñado de plugins en http://www.cs.umn.edu/~mein/blender/plugins.
especificación: .

  • #include <plugin, h>

todos los plugins de Blender deben incluir este fichero cabecera, que contiene todas las estructuras y definiciones necesarias para trabajar correctamente con Blender.

  • char name[]=blur;

un string (cadena de caracteres) conteniendo el nombre del plugin, este valor se usara para indicar el título de la textura en la ventana de botones de textura.

  • varstruct varstr[]= {.};

varstr contiene toda la información que Blender necesita para mostrar los botones del plugin. Los botones para los plugin pueden ser de tipo numérico para introducir datos, o de tipo texto para introducir comentarios u otra información. Se pueden utilizar como máximo 32 variables en los plugins. Cada estructura varstruct consta de un tipo, un nombre, un rango de información y una nota emergente sobre la herramienta. el tipo define el tipo de dato para cada botón, y la manera en la que se muestra dicho botón. Para botones numéricos este valor debería ser una combinación (ored) de int o flo para el formato del número y num, Numsli o Tog para el tipo de botón. Los botones de texto son de tipo label. el nombre es lo que se mostrara en el botón y está limitado a 15 caracteres. el rango de información consiste en 3 números reales que definen los valores máximo, mínimo y por defecto para el botón. Para los botones Tog el mínimo es configurado cuando el botón se haya presionado y el máximo cuando esta sin presionar. la nota emergente (tol tip) es una cadena de caracteres que se mostrara cuando el puntero esté encima del botón (si el usuario tiene los tool tips activos). Tiene un límite de 80 caracteres y se tiene que poner a null () si no se utiliza.

  • typedef structure cast {.};

la estructura cast se usa en la llamada a la función doit, y simplifica el acceso de cada plugin a los valores de los datos. La estructura cast debería contener, en este orden, un entero o número real por cada botón definido en VAR(*.str), incluidos los botones de texto. Tipicamente deberían tener el mismo nombre que el botón para permitir una búsqueda o una referencia sencilla.

  • float cfra

el valor cfra actualizado por Blender a su valor actual antes de que todos los renders se hagan. Este valor es el número de frame +/-.5 dependiendo de las configuraciones del campo.

  • plugin_seq_doit Prototype

la función plugin_seq_doit debería ser prototipada para que pueda ser usada por la función getinfo. No necesita cambiar esta línea.

  • plugin_seq_getversión

esta función debería estar en cada plugin para que pueda ser cargado correctamente. No debería cambiar esta función.

  • plugin_but_changed

esta función se usa para pasar información sobre que botones cambia el usuario en la interfaz. La mayoría de los plugins no necesitan esta función, solo cuando el interfaz permita al usuario modificar algunas variables que furze al plugin a recalcularse (una tabla hash aleatoria, por ejemplo).

  • plugin_init

si fuese necesario los plugins pueden utilizar esta función para inicializar datos internos. Nota: esta función de iniciación se puede llamar varias veces si el mismo plugin de textura se copia. En esta función, no inicialice datos globales específicos a una única instancia de un plugin.

  • plugin_getinfo

esta función se usa para comunicar información a Blender. Nunca deberías cambiarla.

  • plugin_seq_doit

la función de secuencia doit es responsable de aplicar el efecto del plugin y de copiar los datos finales en el buffer de salida. los argumentos

  • cast *cast

la estructura cast, que contiene los datos del plugin, véase la entrada cast más arriba.

  • float facf0

el valor de la curva ipo del plugin para el offset del primer campo. Si el usuario no ha hecho una curva IPO, su rango va entre 0 y 1 para la duración del plugin.

  • float facf1

el valor de la curva ipo del plugin para el offset del segundo campo. Si el usuario no ha hecho una curva IPO, su rango va entre 0 y 1 para la duración del plugin.

  • int x int y

la anchura y altura de los buffers de imagen, respectivamente.

  • int x int y

un apuntador al primer buffer de imagen al que el plugin esta vinculado. Sera siempre un buffer de imagen valido.

  • imbuf *ibuf2

un apuntador al segundo buffer de imagen al que el plugin esta vinculado. Los plugins que usan este buffer deberían comprobar si es un buffer null, pues el usuario puede no haber vinculado el plugin a dos buffers.

  • imbuf *out

el buffer de imagen de la salida del plugin.

  • imbuf *use

un apuntador al tercer buffer de imagen al que el plugin esta vinculado. Los plugins que usan este buffer deberían comprobar si es un buffer null, pues el usuario puede no haber vinculado el plugin a tres buffers. estructura de imagen imbuf la estructura imvaya contiene siempre 32 bits de datos de píxel abgr. Las estructuras imvaya son siempre iguales en tamaño, indicado por los valores de x e y.
interacción con el usuario Blender no tiene ninguna manera de saber cuántas entradas espera el plugin, por lo que le es posible a un usuario adjuntar sólo una entrada a un plugin que espera dos. Por esta razón es importante comprobar siempre los buffers que usa el plugin para asegurarnos de que son todos válidos. Los plugins de secuencia deberían incluir también una etiqueta de texto describiendo el número de entradas requeridas en la interfaz de botones.
plugin de secuencia genérico:

Código:

#include plugin, h.

Char name[24]=.
/* estructura para los botones, * butcode name default min max 0
*/.

Varstruct varstr[]= {
{ label, in: x strips, 0.0, 0.0, 0.0, }, };
/* la estructura cast es para entrada en la función doit principal.

Varstr y cast deben tener las mismas variables en el mismo orden */.

Typedef structure cast {
Int dummie; /* debido al botón etiqueta */
} cast.
/* cfra: el fotograma actual */.

Float cfra.

Void plugin_seq_doit(cast *, float, float, int, int, imvaya *, imvaya *, imvaya *, imvaya *).

Int plugin_seq_getversión(Void) {
Return b_plugin_version;
}.

Void plugin_but_changed(int but) {
}.

Void plugin_init() {
}.

Void plugin_getinfo (plugininfo *info) {
Info->name= name;
Info->nvars= sizeof(varstr)/sizeof(varstruct),
Info->cfra= &cfra.

Info->varstr= varstr.

Info->init= plugin_init;
Info->seq_doit= (seqdoit) plugin_seq_doit;
Info->call-back= plugin_but_changed;
}.

Void plugin_seq_doit(cast *cast, float facf0, float facf1, int xo, int yo, imvaya *ibuf1, imvaya *ibuf2, imvaya *outbuf, imvaya *use) {
Char *in1= (char *)ibuf1->rect;
Char *out=(char *)outbuf->rect.
}


.
nuestras modificaciones: .

El primer paso es diseñar un plan de juego. Qué hará este plugin, ¿cómo interactúan con el los usuarios. Para este ejemplo crearemos un filtro simple que tendrá un botón de deslizamiento para una intensidad de 0-255. Si alguno de los componentes r, g o b de un píxel en la imagen fuente es menos de la intensidad seleccionada, devolverá negro y alfa, de lo contrario devolverá lo que haya en la imagen. Ahora copiaremos nuestro plugin genérico a simpfilt, c y rellenaremos los vacíos. Siempre es una buena idea añadir algunos comentarios. Primero, explicar a los usuarios lo que hace el plugin, dónde pueden obtener una copia, a quién deberían contactar para fallos/mejoras, y cualquier restricción de licencia sobre el código. Al usar comentarios, debemos asegurarnos de usar comentarios del estilo /* */. Los plugins están en c, y algunos compiladores de c no aceptan comentarios del estilo //.

Código:

/*
Descripción: este plugin es un ejemplo de plugin de secuencia que filtra píxeles.

De baja intensidad. Funciona con un strip como entrada, autor: kent mein (mein@cs, umn, edu)
Sitio web: http://www.cs.umn.edu/~mein/blender/plugins.

Licencia: dominio público.
Última modificación: Sun sí 7 23:41:35 cdt 2003
*/


Después necesitamos rellenar el nombre, debería ser el mismo que el archivo.c. Preferiblemente descriptivo, menos de 23 caracteres, sin espacios, y todo minúsculas.

Código:

char name[24]= simpfilt, c;


.

Cast y varstr necesitan estar sincronizados. Queremos una barra de desplazamiento por lo que haremos lo siguiente:

Código:

varstruct varstr[]= {
{ label, in: 1 strips, 0.0, 0.0, 0.0, }, { num|int, intensity, 10.0, 0.0, 255.0, our threshold value}, }.

Typedef structure cast {
Int dummie; /* debido al botón etiqueta */
Int intensity;
} cast;


.

Ahora necesitamos rellenar plugin_seq_doit. Básicamente queremos pasar por cada píxel y si RGB es menor que la intensidad seleccionada, coloca el píxel de salida a: 0,0,0,255, si no, devuelve el mismo valor que el píxel de entrada para esa posición.

Código:

int x, y.

For(y=0;y cast->intensity) &
(in1[1] > cast->intensity) &
(in1[2] > cast->intensity)) {
Out[0] = out[1] = out[2] = 0;
Out[3] = 255;
} else {
Out[0] = in1[0];
Out[1] = in1[1];
Out[2] = in1[2];
Out[3] = in1[3];
}
}
}


.

Terminamos pues con simpfilt, c.
compilando: .

Bmake es una utilidad simple (shell script) para ayudar a la compilación y desarrollo de plugins, y puede encontrarse en el subdirectorio plugins/ del directorio de instalación de Blender. Se invoca mediante: Bmake (nombre_plugin, c) e intentara enlazar las librerías adecuadas y compilar el archivo c especificado adecuadamente para su sistema. Si usted esta intentando desarrollar plugins en una máquina Windows, Bmake puede no funcionar en este caso, debería usar lcc. Puede usar lo siguiente para compilar un plugin con lcc, asumiendo que usted tiene sus plugins en c:\blender\plugins: aquí tiene un ejemplo de cómo se compilaría el plugin de secuencia swep, c. Abra una ventana dos y haga lo siguiente: (nota: asegúrese de que el directorio lcc\bin está en su Path)

Código:

cd c:\blender\plugins\sequence\swep.

Lcc -ic:\blender\plugins\include swep, c.

Lcclnque -dll swep, obj c:\blender\plugins\include\seq, Def.

Implib swep, dll


Nota: se ha corregido alguna traducción para adaptarla al castellano, gracias a por ofrecernos está traducción.

Este tutorial esta extraído de en su sitio web podrás encontrar este mismo tutorial traducido a más idiomas, Blender es un programa gratuito.

Ver más sobre el tema y los comentarios en el foro