Entradas populares

domingo, 7 de noviembre de 2010

avanzando un poco mas nuestro publicador

ya hemos hecho un script para publicar los modelos en una carpeta determinada, ahora imaginemos que estamos en otra fase de produccion y el modelo aparte de geometria tiene las texturas y las queremos copiar a una carpeta determinada, esto nos complica un poco la exportacion ya que tendremos que ver que shaders tiene el objeto, de esos shaders ver cuantos tienen texturas y esas copiarlas a otra carpeta

para ello, aunque realmente no he empezado el script he ido añadiendo varios metodos a la clase mayaObject, que ya veis que empieza a ser mas compleja, esos metodos nos daran los inputs y outputs de nuestros objetos, los shaders asignados, y el valor de un atributo o su(s) conexion(es) si esta conectado



ya veis que son todo metodos muy simples, casi todos de menos de 10 lineas de codigo, pero que vamos consiguiendo ya una funcionalidad bastante fuerte, el siguiente paso sera crear unas nuevas clases que nos ayudaran bastante, la clase shadingEngine, la clase shader de la cual derivaremos las phong, lambert y demas y la clase file con la que trabajaremos sobre las texturas

y esto es todo por hoy, parece que mas que un blog estoy haciendo una bitacora, pero sobre todo estoy intentando explicar un modo de hacer los scripts que en mi opinion es mas sencillo y que sobre todo, al permitir una reutilizacion muy grande, nos hara la vida cada vez mas facil segun vayamos haciendo scripts

descubrimiento importante y muy potente

ayer profundizando un poco mas en la programacion orientada a objetos del python, me encontre que en las ultimas versiones las clases, si estan definidas como descendientes de object, tienen el metodo __new__, este metodo, que se ejecuta antes del metodo __init__ nos permite modificar la creacion de la instancia de la clase, es decir, aunque nosotros hayamos dicho que nos cree una instancia de la clase A, podemos decirle en el metodo __new__ que lo que queremos realmente es que sea una instancia de la clase B, en otras palabras y poniendolo dentro de nuestras clases, podemos decirle siempre que nos cree un objeto de clase mayaObject y el ya se encargara de devolvernos uno de clase mesh, transform o lo que considere oportuno,

asi que me he puesto manos a la obra y he modificado la creacion de los objetos de clase mayaObject, ahora, cuando le digamos que cree una instancia de la clase, lo que hara sera mirar si hemos definido el tipo, si no lo hemos definido y un objeto con ese nombre existe en la escena mirara su tipo, si lo hemos definido pues se fiara de nosotros, una vez que sepa de que tipo tiene que ser, mira a ver si esta entre las clases que hemos definido, y si esta, pues nos devuelve un objeto de su clase

este es el metodo __init__ que he definido



tambien he tenido que crear una pequeña funcion en el __init__.py del modulo para definir __all__ que me devuelve los ficheros con las clases que he definido

para probar que tal funciona esto he creado un pequeño metodo en la clase scene que aparte de venir muy bien en el futuro, ahora nos permite testear su funcionamiento, lista_seleccionados



ya veis que es muy simple pero muy potente, nos devuelve una lista de objetos cada uno en de su propia clase de los objetos que tengamos seleccionados

esto me facilita mucho la creacion de una idea que tenia en la cabeza, las subclases apartir de la clase scene, ahora podriamos definir facilmente una clase model_scene, animation_scene o render_scene y que dependiendo del path que tenga alguno de sus metodos trabaje distinto como puede ser un check, un publica, o un renderiza

sábado, 6 de noviembre de 2010

subidos los archivos a un repositorio

acabo de crear un proyecto en google code y ya si quereis podeis bajaros los archivos.

para bajaros los archivos teneis que tener algun cliente de subversion instalado, mejor si lo teneis en el eclipse y la url del repositorio es

svn checkout http://maya-classes.googlecode.com/svn/trunk/ maya-classes-read-only

si alguno quereis colaborar podriamos hablarlo y os iria dando permisos para ir subiendo vuestras modificaciones al repositorio

el proyecto esta aqui

resumen de los metodos y clases

aqui os dejo una imagen en la que se ven las clases que he definido por ahora y los metodos de cada una, podeis ver que con muy poco trabajo ya podemos hacer combinaciones de esos metodos y tener bastantes scripts que nos pueden ayudar, aparte de que todos serian del mismo estilo y podrian funcionar tanto dentro de maya como en modo batch

crear un script para publicar modelos

he intentado hacer un script de demostracion de como se haria un script para produccion siguiendo este metodo, pero creo que me ha quedado un poco largo, asi que lo ire explicando en varios pasos

supongamos que una vez que los modeladores han acabado de modelar, sus modelos tienen que ser publicados en un sitio concreto y con estas caracteristicas

  • de una solo pieza
  • sin historico
  • con un locator por encima con el nombre MDL_<nombre del modelo>

y que el script este hecho de tal modo que pueda ejecutarse facilemente desde maya o en modo batch sobre multiples escenas

en primer script lo haremos muy facil, muy parecido al ejemplo que he puesto para el MayaPython



en el lo unico interesante es la llamada a la funcion LVpublicaModelo, a la que le pasamos el nombre que queremos que tenga el modelo, en este caso "cortacesped"

en la clase 'scene' le hemos añadido este metodo, y aunque ya es algo mas complicado seguimos trabajando de un modo mas abstracto



en el llamamos a LVmayaObject que ya lo hemos visto, pero tambien a dos que no hemos visto, el LVmesh y el lvPath

el LVmesh es un descendiende del LVmayaObject donde ejecutamos las tareas propias de los poligonos, y el LVpath es una clase que nos define los path del proyecto como queramos

vemos facil que lo primero que hacemos es crear el nombre del archivo final

luego creamos un objeto de la clase mesh, con el nombre que le hemos dado y llamamos a la funcion combina, esta funcion lo que hace es que le pasamos una lista de objetos de clase 'mesh', nos hace un combine de ellos y nos devuelve un objeto de clase transform, tambien descendiente de LVmayaObject



la lista la hemos generado con un nuevo metodo para la escena, el listade



este metodo nos devuelve una lista de todos los objetos del tipo que busquemos en la escena de maya y nos los devuelve como una lista de mayaObjects o de la clase que necesitemos dependiendo de que tipo de objeto de maya que busquemos

veis que la funcion no es muy complicada, aparte de que nos puede ser muy util en muchos otros casos

ahora creamos el locator que va a ser el padre de este objeto, como aun no hemos definido la clase locator va a tener que ser de clase LVmayaObject, pero de todos modos probamos a tipificarla por si algun dia definimos esa clase

ejecutamos la funcion de creacion
y luego dos funciones que hemos metido nuevas al LVMayaObject, el emparenta, que emparenta un objeto LVmayaObject o un descendiente suyo al objeto actual



y el selecciona, que nos selecciona o añade a la seleccion el objeto actual



al final creamos un nuevo objeto scene llamando al metodo graba_seleccionado en el objeto scena actual



como veis cada una de los metodos nuevos que hemos ido añadiendo a las clases son bastante sencillos, y el metodo publicaModelo no llega a llamar a maya.cmds, estamos abstrayendo las funcionalidades a base

vamos a complicarlo todo (o no), el mayaObject

Bueno, igual que para gestionar las escenas y trabajar sobre ellas hemos creado la clase scene, ahora voy a enseñaros lo que tengo de lo que va a ser la piedra angular de todo los scripts que trabajen con elementos de la scena, el mayaObject, en esta clase intentaremos definir los metodos basicos con los que trabajaremos en distintos tipos de nodos de maya como puede ser crear, borrar, duplicar, instanciar, seran todas funciones basicas menos un par de ellas que son simplemente para que en vez de los nombres de los objetos nos devuelvan los elementos como otros mayaObjects o sus descendientes, tambien podemos incluir metodos de informacion, como un metodo que nos escriba en un archivo o imprima en pantalla la informacion que queramos de ese nodo.

De esta clase sera de la que luego derivaremos muchas otras, como por ejemplo una clase mesh, en la que tendremos los metodos que necesitemos para trabajar con poligonos, la clase transform, que nos valdra para gestionar las jerarquias

En principio estos metodos son sencillos y parecen demasiado simple, pero hay que mirar un paso adelante para ver su utilidad, por ejemplo en la clase "mesh" podriamos crear un metodo que nos exporte esa geometria , que la cambie por otra, que haga un check de si esta correctamente modelada o que nos haga un informe de cuantos poligonos tiene el objeto, ahora mismo solo estamos creando una base que a la vez es la estructura de nuestra organizacion de los scripts, lo que antes hariamos como un script muy largo para modificar poligonos, ahora es un metodo de muchas menos lineas que esta guardado con otros scripts de poligonos dentro de la clase y que estan hechos de tal modo que unos scripts se apoyan en otros, no solo un archivo que tenemos guardado en el maya/scripts

Habria otros ejemplos de descendientes de la clase maya object como podria ser la clase shader, de la cual todavia podria descender la clase fileTexture, y se encargaria de las conexiones, path de texturas, ....., o una clase camera con controles adicionales como el viejo script de DoF que escribi hace tiempo

Aqui os dejo la clase tal y como la tengo por ahora, esta con los metodos basicos, pero segun vayamos viendo cosas se ira rellenando con metodos mas y mas complejos, pero a la vez apoyados en los metodos y clases ya existentes



No tiene por que ser asi o tener estos metodos, puede tener otros que considereis mas oportunos para vuestras necesidades, como por ejemplo que en vez de scribir en un archivo de texto normal escriba en formato xml, o que se meta en una base de datos.

Otra posibilidad es crearnos classes de objetos virtuales, podriamos crearnos por ejemplo una clase bindMesh que teniendo todos los metodos de una clase mesh tuviese ademas algunas caracteristicas especificas de cuando queremos usarla en un rig

viernes, 5 de noviembre de 2010

interfaces en maya 2011

con el cambio de la interface de maya a qt, la creacion de interfaces que era bastante complicada en versiones anteriores se ha simplificado bastante, ahora, usando el qt designer podemos diseñar interfaces facilmente, cargar directamente el archivo .ui que guarda en maya y tratar muchos de sus widgets como los controles standar de maya

el unico problema que tiene este metodo es que tenemos que saber donde esta guardado el archivo .ui, y esto complica un poco las cosas, o que tenemos que pasar un archivo que aun se puede editar o modificar, y esto en algun caso puede no interesarnos, sobre todo si queremos distribuirlo o no tenemos acceso a donde va a instalarse el script

para evitar esto tenemos dos opciones

la primera es que en vez de llamar al comando loadUI() con el parametro file, llamarlo con el parametro string, habiendo copiado todo el contenido del archivo .ui a una variable texto

por ejemplo:



esta opcion es eficaz, pero queda un poco feo el tener ese tocho de la interface en el codigo

la segunda, viene a ser lo mismo, pero en vez de que sea una variable dentro del codigo, que sea el resultado de una funcion que importaremos de otro archivo, mas o menos seria:



esta para mi es la opcion mas elegante, aparte de que nos abre la opcion de generar automaticamente interfaces, lo unico que es un poco cansino el tener que copiar el archivo de texto, grabarlo y demas, por eso en un rato hace unos dias me hice un script que me genera directamente ese archivo desde el archivo .ui



el script os lee a donde apunta la variable PYTHONPATH y os deja grabar el archivo en una de ellas para que se pueda leer facil

jueves, 4 de noviembre de 2010

automatizando sobre distintos archivos

muchas veces nos encontramos que tendremos que hacer scripts para automatizar tareas sobre varias scenas, el modo tipico seria hacer un script dentro de maya que nos fuese abriendo las escenas y ejecutando el script, aqui voy a dar otra aproximacion a ese problema y como podemos solucionarlo

imaginar que tenemos por ejemplo que exportar una serie de escenas a fbx, lo que crearemos sera una clase "scene", que en principio tendra solo los metodos de __init__(), abrir_archivo() y exportar_fbx(), para ello trabajaremos sin abrir maya en ningun momento


AVISO, el codigo es mas bien pseudocodigo, esta tecleado en la misma ventana de crear entradas del blog y esta sin testear, es codigo explicativo de una idea, no funcional 

creamos la clase en eclipse y seria mas o menos asi.



con esto ya tendriamos lo necesario para actuar sobre una scena que es al final lo que queremos hacer

ahora en otro archivo creamos el verdadero script





si lo hemos hecho en eclipse, ahora solo tendriamos que decir que nos lo ejecute y ya empezaria a exportar los archivos

en principio puede parecer que nos hemos complicado un poco para hacer un script tan simple, con el primero que necesitemos puede parecer que si, pero supongamos que ahora lo que necesitamos es un archivo de texto de cada escena, o un check a ver si esta bien organizada, con crear en el objeto scena, que es realmente con el que queremos trabajar, un metodo para cada una de estas funciones ya lo tendriamos, de este modo, en vez de que nuestros scripts cumplan funciones por separado empezamos a crear una estructura facilmente reutilizable, tanto desde una interface, un script en maya o un script externo

con este modo conseguimos varias cosas a la vez, reutilizacion, abstraccion en el script final, organizacion, una mayor limpieza en los scripts y un mejor mantenimiento

algun otro dia hablare sobre como llevar mas adelante esta idea con el MayaObject()

miércoles, 3 de noviembre de 2010

configurandolo todo

lo primero comentaros como tengo yo todo preparado para trabajar

suelo trabajar con eclipse como ide para los scripts, con el subversive como conexion a subversion y el pydev.
tambien tengo el qtdesigner para diseñar las interfaces, todo lo podeis descargar y configurar tal y como cuenta en esta pagina 

mi modo de trabajar es bastante basico, en eclipse escribo las classes o los metodos y desde maya las llamo, intento no desarrollar nada en maya, sobre todo por lo facil que es perder un script cuando cometes un fallo y el script no acaba

hay tambien una conexion eclipse->maya que esta bastante bien para los scripts en mel

de toda la configuracion lo mas complejo es el autocompletar, me ha dado algunos fallos pero siguendo las instrucciones de la web que he puesto funciona bastante bien

tengo configurado dos interpretes de python en el eclipse, uno el python 2.6 y otro el mayapy del maya 2011 que es con el que suelo correr los scripts, asi desde eclipse puedo lanzar tareas a maya.

luego tengo el script mas importante en este momento de mi arsenal, el que me permite facilmente ejecutar cualquier script dentro de maya, lo copie de esta pagina

import sys, os
SZ_MAYA_LOCATION = 'C:/Program Files/Autodesk/Maya2011'

def MayaPython(func):
    def MayaEnvironWrapper(*args):
        os.environ["MAYA_LOCATION"] = SZ_MAYA_LOCATION
        sys.path.append(os.environ["MAYA_LOCATION"] + "/Python/lib/site-packages")
        import maya.standalone
        import maya.mel as mel
        maya.standalone.initialize(name = 'python') 
        version = mel.eval('getApplicationVersionAsFloat')
        print 'ejecutando maya version %s' % version
        # extra initialization scripts
        #maya.mel.eval('source "initialStartup.mel"') 

        return func(*args)
    # end of MayaEnvironWrapper

    return MayaEnvironWrapper
# end of MayaPython


este script nos permite definir metodos y funciones que se ejecuten dentro de maya simplemente importando esta funcion y poniendo "@MayaPython" en la linea anterior a la definicion de nuestra clase, por ejemplo

from MItools.maya_tools import MayaPython
import MImayaObjects.scene as MIscene

@MayaPython
def MIrender_vray(path):
    scene=MIscene.scene(scenePath = path)
    scene.abre_file()
    scene.lanza_render()
  

ERrender_vray('c:/directorio/projecto/archivo.mb')


este script nos abrira el archivo y lo lanzara a render, realmente lo que estamos haciendo al poner @MayaPython es pasar la funcion que estamos definiendo como argumento para la funcion MayaPython(), que esta ejecuta al final, asi tenemos un modo muy facil de ejecutar scripts sobre maya sin abrir la interface

lo primero, me presento

hola a todos, mi nombre es larry Vizoso, llevo unos 11 años dedicandome a esto del 3d casi siempre como TD, desarrollando herramientas y scripts primero en mel, y ahora en python, aqui os enseño algunas de ellas

demo 2010

intentare ir poniendo ideas, trucos y scripts para maya y para 3d en general

un saludo

empezando a crear el blog

vamos a empezar a crear este blog para compartir algunas de las ideas y desarrollos que voy haciendo.

espero que resulten de ayuda