Monday, June 10, 2013

Some Face Rig workflow Tips

Happy Monday

Here are some Face Rig workflow Tips that may be helpful.  I'm not a senior level facial rigger yet, but these steps were very useful to me.  Hope they are helpful.

--try to pose cartoon face to fit a real face expression reference
(a technique that is helpful to remember poses is to write a function that prints something like
"setAttr eye_anim.tx 1;setAttr nose_anim.tx 1; ..." ).  Then save the string onto some transform .. ex. group named "poses", attribute "smile".  Then can run something like  eval(`getAttr`) and it sets the pose.

--take notes on technical steps so they don't have to be remembered.
(things like what do i need to select to run it, any pictures to help with running this ...)

--write scripts that make your work easier not harder… the less dependencies they have or the easier it is to install them / use them the better.

Something I learned from watching Daniel Williams' online tutorials (pointpuster dot com) was to try out a solution, it doesn't have to be the best solution. Then try to look at it and evaluate it/critique it to make it better.


Great facial expression reference:
Mark Simon's Facial Expressions (A Visual Reference for Artists)

Here's an example script I wrote to help with quickly remembered face rig pose.
 /**@file na_getPose.mel
*Prints command to set Pose should work on faces or bodies.(Tested Maya 2008)
*@author Nathaniel O. Anozie (ogbonnawork at gmail dot com)
*@note date created: June 10, 2013
*@note How to Install
*@note source na_getPose.mel
*@defgroup anim Animation Posing
*save pose syntax, gives a string we can call with eval to set face to current pose
*would need to copy pose to text editor before reusing
*@note Modify at your own risk

//-------assumes all animator controls selected on scene
global proc string na_getPose(){
    print("[na_getPose] Start Computing Pose….\n");
    string $cmd = "";
    string $sel[] = `ls -sl`;
    if(size($sel)==0){error("Requires Animator Controls Selected First !!!\n");}
    string $attr[] = {};
    for($obj in $sel){
        $attr = {};
        $attr = `listAttr -k -u $obj`;
        //visibility translateX translateZ
        //visibility translateX translateZ
        //visibility translateX translateY translateZ rotateX rotateY rotateZ scaleX scaleY scaleZ
        //rotateX rotateY rotateZ mouthUp
        //print( stringArrayToString($attr," ") );
        $cmd += ""+na_getSinglePose($obj, stringArrayToString($attr," ") );
    print("[na_getPose] Completed Computing Pose !!!\n");
    print $cmd;
    return $cmd;

//result ex: "setAttr jaw_anim.rotateX 0; setAttr jaw_anim.rotateY 0; setAttr jaw_anim.rotateZ -11.81234478"
//obj   --  the object ex: "jaw_anim"
//attr  --  the attributes space separated ex: "rotateX rotateY rotateZ"

global proc string na_getSinglePose(string $obj, string $attr){
    //print("[na_getSinglePose] Computing current pose ….\n");
    //string $obj = "jaw_anim";
    //string $attr = "rotateX rotateY rotateZ";
    string $result = "";
    string $attrAr[] = stringToStringArray($attr," ");
    string $cmdAr[] = {};
    for($attr in $attrAr)
        $cmd = "";
        float $arg;
        $arg = getAttr ($obj + "." + $attr);
        $cmd = "setAttr "+($obj + "." + $attr) + " "+$arg;
        $cmdAr[size($cmdAr)] = $cmd;
    //print(stringArrayToString($cmdAr,"; "));
    $result = stringArrayToString($cmdAr,"; ");
    $result += ";";
    return $result;