20 July, 2010

Rigenerator: Update 1

The major change in the new version is the rule based DG traversal. Earlier DG traversal was unrestricted and it will fetch all the nodes involved in the scene. In the new version I have added rules that are stored in a simple dictionary structure which can be updated dynamically. This allows me to select a DAG structure and Rigenerator will only get the rig involved in that selected DAG tree.

Rules are used by algorithm to decide if it needs to ignore a node, or ignore a branch or end at a particular node in DG. These conditions are triggered when we encounter specified node type or name. I will add regular expression to both, node name and type, so that we can target more generalized types of nodes. Later on, my plan is to be able to specify node patterns and levels in the rules. This rule based DG traversal is very powerful as I can fine tune the algorithm dynamically to extract any kind of rig.

I have also fixed problems with DG connection sequence in the code. So now there will be no connection dependency problems like this:
connectAttr nurbsCurveShape.worldSpace[0] curveInfo1.inputCurve;
connectAttr makeNurbsCircle1.outputCurve nurbsCurveShape.create;
// This will be an error since nurbsCurveShape is not created 
//  when doing first connection
// Shape is created when we make the second connection

Next addition is the option to include top hierarchy nodes of the selected rig. There are three options for this:
1. Recreate the top hierarchy
2. Use existing top hierarchy
3. Just group the rig under a separate node

For example, you Rignerate the Arm setup and also want all the top hierarchy nodes, e.g. shoulder, upper_body, root etc, then you can include those transform nodes, so it maintains the hierarchy. Using existing hierarchy helps, if you are mirroring the rig. And you can group the rig under a single node, in case you want to move it somewhere else.

Right now the code generation is still in .MA format and even if its simplicity is very useful it adds limitations because certain type of code cannot be executed with MEL! I can understand the reasons behind it, but it has added complexity to the code generation.
For example,
createNode animCurveUA -n L_Index2_rotateZ;
setAttr "L_Index2_rotateZ.wgt" no;
setAttr "L_Index2_rotateZ.tan" 10;
setAttr -s 3 "L_Index2_rotateZ.ktv[0:2]"  -10 26.247651337441738 0 0 10 -77.759996825174923;
Last line will silently fail and also the code following that line. This thread explains this: LINK

Hence the next step is to add special processing for special nodes, in this case animCurveUA. So instead of using MPlug.getSetAttrCmds() I will query attribute using normal mel commands. But, I need to generalize this into a proper system, instead of going and adding so many specific if conditions. This will also allow me to generate special commands for deformers as I have posted in one of my earlier posts. So that's the next goal.

19 July, 2010

FreeMind: Mind mapping tool

It is very important to organize not only your code but the thought process and all the ideas that come up during planning of a project. I started with my rigging framework and then branched to make Rigenerator, which by itself is now a big project. Each feature of Rigenerator requires good amount of planning to consider all possible cases. At the current stage code of Rigenerator is turning very complex for me even with lines and lines of comments. I have started loosing myself in these different possible scenarios and ideas to solve them. The problem is that going back to a particular problem after few days is not easy.

So I have decided to document as much thought process as I can so that resuming to the last problem is easier and I can trace old problems and their solutions. I found that I can do this by a technique called mind mapping. Basically you write everything in nodes which are interconnected and organized as a tree. I am using FreeMind (open source) to document my ideas and its helping me so much. And I always feel good when I am organized :)

You may find this tool very helpful. Check out the video demo at the bottom of the screenshot page.

14 July, 2010

Rigenerator : Converting deformer network into its command

While developing my Rigenerator tool, I am studying more and more about Maya DG graph and how to reproduce it. Right now I can create all the nodes individually and put them together to recreate the rig. However, I want to be able to replace those individual commands with a specific command e.g. use cluster instead of individual create, addAttr, setAttr, connectAttr commands for each node involved in that cluster deformation.

I believe this feature is going to be very helpful since, it can literally give you a major part of code for your rig already laid out. So you don't have to go back in Maya to check all connections and then come back to editor to code. But, implementing this feature is very tricky so I am studying how deformer network is created, how a deformer gets all the inputs and what each node in that network is used for. I have taken some notes from this study and I want to post them once I have some example images ready.

13 July, 2010

Cluster Deformer Weights

Each component affected by a cluster has its own weight stored in the deformer attribtue .wl (weightList). This attribute is inherited from weightGeometryFilter node. ".wl" is a two dimensional array with first dimension specifying an array related to each geometry object a cluster affects.e.g.
cluster1.wl[0] => array of weight values for nurbsCurve1
cluster1.wl[1] => array of weight values for nurbsCurve2
cluster1.wl[0][3] =>  cluster weight of nurbsCurve1.cv[3]

Now, let's say nurbsCurve1 has 8 CVs, out of which first four (0:3)  are affected by cluster1. Hence the cluster1.wl[0] will have 8 actual weight values (keep in mind that you can do "getAttr cluster1.wl[0][1000]" even if 1000th CV does not exist, more on that later). Now,we change all weights to 0.5 using cmds.percent("cluster1", "nurbsCircle1", v=0.5). That will also change weights of CVs which are not affected by cluster1. Now if I go to "Edit Membership Tool" and add a CV to cluster1, by default its weight would be 0.5 instead of 1.

This may not be very useful, but this is one of those good to know aspects of Maya.