Thursday, July 25, 2013

Workflow rigging tip exporting and reimporting geometry (and na_cleanMaterial.mel)

Happy Thursday!

I needed to add an eye rig to a character I was working on, but i didnt want to deal with the whole rig while adding just the eye part also I didnt want to worry about redundant materials. so i wrote a couple tips and a script to help do that. (Inspired by Andrew Hunt's Pragmatic Programmer discussion on orthogonality, that is can change one part without affecting all the other parts and Todd Henry's discussion on pruning that is by removing unnecessary complexity it may make it easier to increase focus)

So for the tip say want to add eye rig, dont need to work on whole scene. can export the eye geos into a new maya file and put rig in there, then can bring the rig into the maya scene and place it so it moves with the existing thing.

When I imported the eye rig to the scene all of its materials came in but with an underscore. I didnt want these imported materials instead I wanted to use the current scenes materials. That is why I wrote na_cleanMaterial.mel. It figures out how to reassign imported object to materials that are already on scene. It uses naming conventions. Then it removes the unneeded imported materials. There may be some bugs but hope it is helpful. I also posted a video demo on Vimeo.


Inspired by Andrew Hunt and David Thomas's Pragmatic Programmer
Inspired by Todd Henry's The Accidental Creative (toddhenry dot com)

Heres the code I wrote for the material stuff in MEL:

----  This is useful when you export some things to a new scene then reimport them but dont want to use their imported materials
----  since there are already materials on scene.

@note Run na_cleanMaterial(); in MEL script editor after sourcing this script 
@author Nathaniel Anozie
ogbonnawork at gmail dot com
@note created: 07/25/2013
@note Inspired by Rik Poggi online tutorial on using rfind in python
@note Modify at your own risk

//last updated: 07/25/2013 -- initial release

/*clean up imported materials
go through all supported material shaders and if there is a underscore and the end part of name is already on scene 
1. save objects assigned (objects could be face,shapes, … )
2. reassign scene material to them
3. remove imported material shader, and remove imported material shading group.
global proc
    print("[na_cleanMaterial] Starting . . . \n");
    string $sel[] = `ls -sl`;
    string $shader[] = `ls -type surfaceShader -type lambert -type blinn`; //PUT MORE MATERIALS TO SUPPORT HERE
    for($arg in $shader){
        if( strcmp($arg,"lambert1") != 0){
            string $maybeSceneMat = na_cleanMaterial_getNonImportedName($arg);
            //reassign to material when needed
            if(  (strcmp($arg, $maybeSceneMat) != 0)  && objExists($maybeSceneMat) ){
                string $sgAr[] = `listConnections -source true -type shadingEngine $maybeSceneMat`;
                if(size($sgAr) == 1){
                    print("[na_cleanMaterial] Great! reassigning material for-->"+$sgAr[0]+"!\n");
                    string $nonImportMatSG = $sgAr[0];
                    select -cl;
                    //select objects with material
                    //if no objects with material nothing gets selected
                    hyperShade -objects $arg;
                    //assign to scenes non imported material via its shading group
                    if(size(`ls -sl`) > 0){
                        sets -e -forceElement $nonImportMatSG;
                    else{ print("[na_cleanMaterial] Skipping! Nothing needed to reassign for material -->"+$sgAr[0]+"\n"); }
                    //remove imported non used material
                    string $importedSGAr[] = `listConnections -source true -type shadingEngine $arg`;
                    if( size($importedSGAr) == 1){ 
                        print("[na_cleanMaterial] removing-->"+$importedSGAr[0]+"!\n");
                        delete $importedSGAr[0];
                    print("[na_cleanMaterial] removing-->"+$arg+"!\n");
                    delete $arg;
                else{ print("[na_cleanMaterial] Warning Cannot Find Shading Group For-->"+$maybeSceneMat+"!\n"); }
            else{ print("[na_cleanMaterial] Skipping -->"+$arg+"! No objects need reassigning\n"); } 
    select -r $sel;
    print("[na_cleanMaterial] Great Day its Complete !!!\n");

//gives back either the input or the ending part of input if input is of imported name form
//should support materials with underscores in name
global proc string
na_cleanMaterial_getNonImportedName(string $arg)
    string $shader = "";
    //string $arg = "toImport_materialName";
    $shader = $arg;
    //get last zero based index of underscore in string
    int $last = python(  "'"+$arg+"'"+".rfind('_')"  ); //if cant find it gives a -1
    //---getting last part of name if possible
    //strict less is important here
    if($last != -1 && ($last < size($arg) ) ){
        $shader = python( "'"+$arg+"'"+"["+ ($last+1) +":]"  );
    return $shader;
    //print $shader;