miércoles, 31 de diciembre de 2014

Morning of pencil and paper!!

Some friend of mine critized me because my blog is called "Art & Tech" and so far there has been a lot of "Tech" and practically no "Art". And I think she's right, (God save me from disagreeing with a woman!!)

I tend to load the Tech truck more because it's interesting for me but also because I believe it's harder to master, or at least the logical part of your brain is not as involved in Art as it is in this. Those of you who know me get the idea that I don't pretend to belittle Arts. In fact I find it indispensable for my life, it's just that there are moments and moments for each and since i come from a technical background I tend to lie more often there. But I'm aware that I need to boost my art skills so here I
am!!

This morning of 31st December is a wonderful morning for drawing a little bit. I already have around 10 hours of english study with Bai & By, going in 1-2 hours of study per day rhythm I think it's ok if I'm able to sustain it through the rest of the course.

The other "homework" i had was to search for references for my models in order to do my demo reel. As of now, I'm pretty well with the results and ideas i have, though it's true I could do some more just to cover my back.

Ladies and gentlemen with great honour I present you: Anna Nicole Smith!! God bless her, life wasn't easy for her.



domingo, 28 de diciembre de 2014

Learning Maya: first polygon modeling exercise

Enough of computer science for a while here, i will be posting a modeling exercise we did in class before christmas.

I've been practising to gain speed but each time I repeated the exercise I bumped into new problems, I guess that's part of the higher learning. My teacher is quite convinced this is good, moreover he deals with the exercises in class in such a way that we will find "unexpected" problems.

From my point of view I think it's cool because it enriches the class. The easy way to go for him would be to do things straightforward but then little we would learn!

3D requires a constant practising effort because one always runs into problems we need to solve to get the job done and often there are several ways to do the same thing but not all of them are quick and when you find yourself in a rush it's fairly good to know the best way.

The exercise consists of a hard surface using Maya polygon modeling tools. It's the first and the last we have done of its genre because we needed to begin with animation and so the modeling classes were interrupted.

It's a hamster wheel done in approximately 1 h 30 min. This includes importing the image plane references and adjusting sizes to make sure the images match from the three cameras. I had a little trouble with some unexpected behaviour when converting NURBS surface to polygon when doing the "feet" that sustain the wheel. Hopefully I will get faster with practice.

Here is the image reference:


And here is the turntable i did with playblast.



By the way, I'm gathering ideas aimed at my demo reel. I have some things in mind but i need to check up on them with my teacher, as I suspect there might be any not suitable at all.

domingo, 7 de diciembre de 2014

Learning Python: Objects, Bindings And Names

As you all know, i'm currently following a course on Maya in order to become CG Generalist one day (hopefully on April/May 2015 i will land a job in the games/film industry).

Having a programming background i can't help myself learning Python to complement my skills in Maya and so, i started a couple of weeks ago to mess around with the Maya Python Command Engine and PyQt for GUIs.

Well, this last friday i received Maya Python for Games and Film which has revealed to be quite instructive. The first chapters telling the basics, one can still learn something new specially if you come from another more traditional language such as C/C++ like me.

Each time we learn a new programming language we try to find the same mechanics we found on the ones we already know as well as the new features, those that sustain the raison d'être of this new language.

Well, taking the first steps in Python that's what happened to me: as i am used to in C++ i try to figure out whether a variable in Python is a reference (&), a copy( new object) or a pointer (*).

The truth is this way of thinking does not fit well into Python. In Python one cannot think any more about "variables" but rather "names" and references and pointers become "bindings". It will make you do less errors and get less unwanted surprises when coding. I've found the following example in the web:

1
2
3
4
5
6
7
8
9
>>> dict = {'a':1,'b':2}
>>> list = dict.values()
>>> list
[1, 2]
>>> dict['a']=3
>>> list
[1, 2]
>>> dict
{'a': 3, 'b': 2}

If you store the result of dict.values(), and change the dictionary afterwards, the previously stored result remains untouched. However, if a dictionary has lists as value entries, the behavior is not the same: If you change the dict, the list you previously created via dict.values() gets automagically updated.

1
2
3
4
5
6
7
8
9
>>> dict = {'a':[1],'b':[2]}
>>> list = dict.values()
>>> list
[[1], [2]]
>>> dict['a'].append(3)
>>> dict
{'a': [1, 3], 'b': [2]}
>>> list
[[1, 3], [2]]

One would think that the same method dict.values() has different behaviour depending on the values of the dictionary. In the first case it would return a copy of the values in a list and in the second case it would return a reference/pointer. Well dismiss references, pointers and variables and think of names, bindings and objects.

EXPLANATION

I find the graphical answer explaining this on the web by Michael Hudson very illustrative and self-explanatory so i will "echo" it here in my blog just as a reminder.

Case 1. "Copy"
1
>>> dict = {'a':1,'b':2}

The above line could be illustrated as follows:

    ,------.       +-------+
    | dict |------>|+-----+|     +---+
    `------'       || "a" |+---->| 1 |
                   |+-----+|     +---+
                   |+-----+|     +---+
                   || "b" |+---->| 2 |
                   |+-----+|     +---+
                   +-------+

where "dict" is a name, all the others surrounded by +---+ are objects and ------> are bindings.

>>> list = dict.values()

    ,------.       +-------+
    | dict |------>|+-----+|             +---+
    `------'       || "a" |+------------>| 1 |
                   |+-----+|             +---+
                   |+-----+|              /\
                   || "b" |+-----.    ,---'
                   |+-----+|     |    |
                   +-------+     `----+----.
                                      |    |
    ,------.       +-----+            |    \/
    | list |------>| [0]-+------------'   +---+
    `------'       | [1]-+--------------->| 2 |
                   +-----+                +---+
Now,  this:

>>> dict['a']=3

    ,------.       +-------+
    | dict |------>|+-----+|             +---+
    `------'       || "a" |+-.           | 1 |
                   |+-----+| |           +---+
                   |+-----+| |            /\
                   || "b" |+-+---.    ,---'
                   |+-----+| |   |    |
                   +-------+ |   `----+----.
                             |        |    |
    ,------.       +-----+   |        |    \/
    | list |------>| [0]-+---+--------'   +---+
    `------'       | [1]-+---+----------->| 2 |
                   +-----+   |            +---+
                             |            +---+
                             `----------->| 3 |
                                          +---+

So list and dict yield the no surprise result:

>>> list
> [1, 2]
> >>> dict
> {'a': 3, 'b': 2}

which is fine.

Case 2. "Reference"


>>> dict = {'a':[1],'b':[2]}
    ,------.       +-------+
    | dict |------>|+-----+|     +-----+   +---+
    `------'       || "a" |+---->| [0]-+-->| 1 |
                   |+-----+|     +-----+   +---+
                   |+-----+|     +-----+   +---+
                   || "b" |+---->| [0]-+-->| 2 |
                   |+-----+|     +-----+   +---+
                   +-------+

>>> list = dict.values()
    ,------.       +-------+
    | dict |------>|+-----+|             +-----+   +---+
    `------'       || "a" |+------------>| [0]-+-->| 1 |
                   |+-----+|             +-----+   +---+
                   |+-----+|               /\
                   || "b" |+-----.    ,----'
                   |+-----+|     |    |
                   +-------+     `----+-----.
                                      |     |
    ,------.       +-----+            |     \/
    | list |------>| [0]-+------------'   +-----+   +---+
    `------'       | [1]-+--------------->| [0]-+-->| 2 |
                   +-----+                +-----+   +---+


>>> dict['a'].append(3)

                                                    +---+
    ,------.       +-------+                     ,->| 1 |
    | dict |------>|+-----+|             +-----+ |  +---+
    `------'       || "a" |+------------>| [0]-+-'
                   |+-----+|             | [1]-+-.
                   |+-----+|             +-----+ |  +---+
                   || "b" |+-----.         /\    `->| 3 |
                   |+-----+|     |    ,----'        +---+
                   +-------+     |    |
                                 `----+-----.
    ,------.       +-----+            |     \/
    | list |------>| [0]-+------------'   +-----+   +---+
    `------'       | [1]-+--------------->| [0]-+-->| 2 |
                   +-----+                +-----+   +---+

Since the list binded by the object "a" is the same binded by the first position object of "list" the above statement is changing the same "referenced" object. So we have the following correct either:


> >>> dict
> {'a': [1, 3], 'b': [2]}
> >>> list
> [[1, 3], [2]]

CONCLUSION

In a nutshell i think that python tries to avoid copying objects whenever possible and it has a reason because copying is always expensive, not to mention deep copying!! So whenever we need a copy of an object we have to explicitly request it via copy.copy().

jueves, 4 de diciembre de 2014

Different Frames In Animation And Their Mission

It's been a couple of days since we left the polygon modeling classes aside to start off the module of animation. I'm talking about the classes i'm following at CICE here in Madrid.

The teacher immediately recommended us to have a look at the known by many as the bible of animation, the book by Richard Williams "The Animator's Survival Kit". It didn't surprise me at all because it's been a long time since i've heard people talking marvellous things about that book.  In fact a couple of years ago i decided to buy it from Amazon in english. I knew there were some videos accompanying the book but couldnt find them so i decided to download them from a torrent.... Turned out to be priceless.

So here i am now, taking a look again at the book, reading the first chapters in what most closely concerns me and the classes i'm following and as i was reading how the animation process was set in the 1940s i was thinking that it might be a good idea to write a post to establish the basics and what is for me a good approach to deal with my first animation exercises and not get lost in the process. I don't know what my teacher would think of this, but since i brought it out of Williams' book i dont think this will bother him.

What ill be talking is about the different keys that exists and their importance when organizing an animation.

KEYS, EXTREMES, BREAKDOWNS & INBETWEENS

1. What is a key?

The 'key frames' are the storytelling drawings or poses (3D). The drawing or drawings that show what's happening in the shot. They are the indispensable drawings that can make the story understandable. Cut one out and the storytelling is incomplete. The keys are the first drawings to be made, they guide the action. In traditional hand-drawn animation, animators tend to put a circle around the key number to emphasize their importance.

2. Extremes

The extremes are the main drawings. The ones where there is a change in direction - the ends of the action where the direction changes. For example an arm swinging when walking or a pendulum. They usually indicate both ends of an arc.

3. Breakdowns or  passing position

It's the drawing right in the middle of two extremes. Some animators underline the breakdown or passing position because it's so important to the action. It marks the zenith of the arc and gives volume.

4. Inbetweens

Finally these are the less important drawings. They are the interpolation between extreme poses. In computer animation these frames are calculated by the computer. In traditional hand-drawn animation these are the drawings left for the assistants and junior animators because once all the keys and extremes are set it's very difficult to screw it up.

Here is a self explanatory video based on Williams' book examples:


domingo, 30 de noviembre de 2014

My first Maya Python/PyQt plugin

THE PLUGIN

What i'm gonna show in the next video is the first plugin for Maya i've coded. I wanted to do something with GUI so i forced myself to use PyQt and the QTDesigner to get familiar with it. The idea of this plugin came up during one of the sessions of the Máster in audiovisual production with Autodesk Maya that i'm following at CICE here in Madrid.
I recalled that 3ds max has a very complete tool for pivot alignment and orientation. One can do the practically the same with Maya but the local axis alignment. This comes handy when we cannot do a snap to the grid or geometric vertex to position the object's pivot.

Modifying the object's pivot position is a very usual operation when we find ourselves modeling stuff. It allows for example to rotate an object's duplicate around a geometric center that can be found through the bounding box of the proper object itself.

ABOUT MY INTEREST IN MAYA TOOLS DEVELOPMENT

The course is mainly focused on 3d concepts such as NURBS & polygon modeling, lighting, texturing, rendering, dynamics etc, all from a Maya artist point of view so no coding at all taught. I felt very disappointed when the other Master i was about to do was cancelled, this one oriented exclusively to Maya tools development and API understanding. The reason was that there wasnt people enough interested in the course. Truth is we were at first 10 people (enough for it) but 5 of them were being sent by the same company as an education at work thing and this company backed off at the last moment. So there we were only 5 people, which the school though was not a proper amount to dedicate a room during five and a half months, in other words, it wasn't profitable.
'Okay, then i'll try in April 2015 while im working' (the schedule allowed me to balance it with work) but then new surprise "the teacher is leaving to work for MPC in Canada, the course will not be released anymore".

Well then find another teacher!!! Apparently this is such a "high profile" that there is little demand for this kind of education (usually 3d artist dont wanna know anything about coding) and at the same time it's difficult to find a teacher. Is this caused by the fact that there are few Technical Directors or Tech Artists out there? is it a "niche" job?

All this said, that's why im trying to make it up and start learning tools development on my own since there is no place else where to study this here in Spain. It will require more effort and the steps will be smaller but with help from other technical directors in a facebook group and mainly my will power  (yes! i can !) i hope to get enough understanding and experience to land a job as CG Generalist/TD.

Ohhhh excuse me, this post is about the plugin. I 'll let the video do the talking!!




lunes, 24 de noviembre de 2014

Adding a Custom Script Folder To Be Loaded On Maya Startup

Now that we have our IDE setup there is one more thing to do: 
we need to tell Maya where to look for our custom scripts.
The method i ve used is basically to create a "userSetup.py" file in my "My Documents\maya\2015-x64\scripts" which was previously empty.

Anything written python wise in that file will run on Maya startup, so i decided to add a path to the python system path as explained hereafter.

The following has been taken from 


Initializing the Maya Environment in and for Python

Maya runs any Python commands in the userSetup.py file whenever it starts up. You can use this file to set up your working environment or execute commonly used Python commands such as importing the maya.cmds module.
The userSetup.py script is executed during the initialization and setup phase of Maya; therefore, only commands which set up your working environment and have no dependencies on Maya functionality can be successfully run in this script.
Note:
You can use maya.utils.executeDeferred() to delay code execution until after the Maya scene is initialized. For more information, see maya.utils.
  1. Create a file named userSetup.py in the following folder:
    • Windows: <drive>:\Documents and Settings\<username>\My Documents\maya\<Version>\scripts
    • Mac OS X: ~/Library/Preferences/Autodesk/maya/<version>/scripts
    • Linux: ~/maya/<version>/scripts
  2. In the userSetup.py file, type the commands you want Maya to run on start up; for example, import maya.cmds as mc.
    Note:
    Make sure you save the file with the right extension (.py).

Adding items to your Python path

To add items to your path in Python, do one of the following:
  1. Set PYTHONPATH in your Maya.env file, or in your environment before you run Maya
  2. Append to sys.path in your userSetup.py or other script once Maya is running.
Here is an example of appending sys.path
import sys sys.path.append( '/Users/jdoe/maya/Scripts' )
Note: userSetup.py must be located in the initial python path ( sys.path) in order to be run automatically at startup. The default Python path can be added to by setting the environment variable PYTHONPATH.

MEL and Python importing

If you have a MEL script in your path, you do not need to source it before accessing any single global procedure it contains with the same name. However, Python requires you to import a script explicitly before accessing any classes or functions it contains; for example:
# This will access the function "bar" in the file "foo.py"
import foo
foo.bar()

Visual Studio Setup for Maya Python and Qt4 programming

I'm following a course on 3d using Maya and having worked as a programmer for a couple of years i want to learn to code some python tools for Maya as well as some C++ plug-ins. So the first thing to do is to choose the development environment.

I ve heard in some places that people tend to use SublimeText and that it's really easy to configure for Maya python programming. Well the truth is i'm rather used to VS since i ve programmed in C++ and C# doing some things on my own. Plus, lately i ve been programming some stuff in python and pygame and i used VS with the python tools so this is my selected IDE.

Now i will explain how to setup Visual Studio 2013 for Maya Python programming.

VISUAL STUDIO 2013 SETUP FOR MAYA TOOLS PROGRAMMING IN PYTHON

1. Download and install Python Tools for Visual Studio (PTVS).You can get them here.

2. Download and install PyQt4 for python 2.7 (since Maya 2015 is using python version 2.7.3). You can get it here. You need to install PyQt4 in the following path:

C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages

3. Open VS 2013 and create a Python Application project.
Under project properties->debug you need to add the following folders to the search path:

C:\Program Files\Autodesk\Maya2015\devkit\other\pymel\extras\completion\py
C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages\maya
C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages\pymel
C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages\PySide
C:\Program Files\Autodesk\Maya2015\Python\Lib\site-packages\PyQt4

Now we have autocompletion for maya.cmds, pyqt4 etc!!

Under "interpreter path" add the line:

C:\Program Files\Autodesk\Maya2015\bin\mayapy.exe

You can have the mayapy.exe interpreter if you want or the one in python27 folder if you prefer. We ve made sure both python version are the same 2.7

4. Now we will add the possibility to execute code from VS directly into Maya.
Download the fast script execution (toMaya) by Josbalcaen here.

- once installed, restart VS 2013
- go to Tools->Options->Keyboard
- search for "ToMaya" and create a new shortcut for example ALT+SPACE

5. write the following code in the Maya script editor

1
2
3
4

import maya.cmds as cmds
try: cmds.commandPort(name="127.0.0.1:6000", close=True, echoOutput=True)
except:    pass
cmds.commandPort(name="127.0.0.1:6000", echoOutput=True)

and put it in a custom shelf or configure your userSetup.mel file to execute the script on Maya startup.

Click on the script, now Maya is listening to this port which is the one ToMaya uses for sending the scripts via VS.

That's all, we should have maya.cmds, PyQt and Python auto completion along with direct execution in Maya!!.

If you prefer, i ve gathered all the necessary stuff needed and put it here. (except for the PTVS, sorry!!)


sábado, 25 de octubre de 2014

Algorithms, part I Sumup

Now that the course is over, this a summary of the algorithms' performance seen in the lectures.

1.a.Quick-Union Algorithm

M union-find operations on N objects
QF M*N
QU M*N
Weighted QU N + M*lg(N)
QU + path compression N + M*lg(N)
Weighted QU + path compression N + M*lg*(N)

Where lg* is the iterative 2-base logarithm:

N lg*(N)
1 0
2 1
4 2
16 3
65536 4
pow(2, 65536) 5

1.b. Algorithm theory and Memory

We can assume the performance in time of an algorithm follows a linear rule on logarithms:

T(N) = a * pow(N, b) and lg(T(N)) = b * lg(N) + c

where b is the slope.

b represents system independent effects such as algorithm design and data input.
a represents system dependent effects like hardware, software, systems.

The 32-bits java data model specifies the following amount of memory distributed on:



data type bytes
boolean 1
byte 1
char 2
int 4
float 4
long 8
double 8
char[] 2N + 24
int[] 4N + 24
double[] 8N + 24
object overhead 16
if inner class 8
reference 8
padding multiple of 8


2. Sorting algorithms


sorting inplace? stable? worst average best remarks
selection yes no pow(N,2)/2 pow(N,2)/2 pow(N,2)/2 N exchanges
insertion yes yes pow(N,2)/2 pow(N,2)/4 N small N or partially ordered arrays
shell (3x+1) yes no ? ? N subquadratic, tight code
merge no yes NlgN NlgN NlgN NlgN guarantee, stable
quick yes no pow(N,2)/2 2NlgN NlgN faster in practice
3-way quick yes no NlgN 2NlgN N improves quicksort in presence of duplicate keys
heapsort yes no 2NlgN 2NlgN 2NlgN poor use of cache memory, inner loop longer than quicksort,not stable
????? yes yes NlgN NlgN NlgN holy sorting grail

3. Priority Queue and binary heap

Find largest M items in a steam of N items

implementation time space
sort NlgN N
elementary PQ MN M
binary heap NlgM M
best in theory N M

Any representation of a heap-ordered complete binary tree where keys in nodes and parent key no smaller than children's keys.


implementation insert del max max
unordered array 1 N N
ordered array N 1 1
binary heap lgN lgN 1


4. Symbol Tables

worst case average
implementation search insert delete search insert delete key interface
sequential search (unordered list) N N N N/2 N N/2 equals
binary search (ordered array) lgN N N lgN N/2 N/2 compareTo
BST N N N 1.39lgN 1.39lgN ? compareTo
2-3 tree clgN clgN clgN lgN clgN clgN compareTo
red-black BST 2lgN 2lgN 2lgN lgN lgN lgN compareTo


5. Hash Tables

worst case average
implementation search insert delete search insert delete key interface
separate chaining lgN* lgN* lgN* 3-5* 3-5* 3-5* equals
linear probing lgN* lgN* lgN* 3-5* 3-5* 3-5* equals
(*) under uniform hashing assumption