Home Coding, Scripting, Shaders

Help with MEL script to automate blendshape creation

Robstein
polycounter lvl 3
Offline / Send Message
Robstein polycounter lvl 3
Hi everyone! I'm currently learning how to use MEL to automate some repetitive tasks in my rigging/animation workflow and I've run into a problem. I thought I'd post my script here to see if anyone can point me in the right direction.

Basically, this script is designed to create blendshapes for clothing and accessories to match a rigged character's blendshapes. The character is going to be exported to Unity, which doesn't support wrap deformers, so I've had to come up with another solution to get the clothing to match the body deformation.

The script takes a selection of clothing objects. For each object, it assigns a wrap deformer that connects the object to the main body geometry, enables each body blendshape one at a time, bakes out a new mesh, and then disables the blendshape before moving onto the next one. When all the blendshapes have been baked, it deletes the wrap deformer, assigns all the blendshapes to the clothing object, and connects each blendshape's value to the corresponding blendshape in the main body.

    //Apply these steps to each selected object
    
    string $array[] = `ls -sl`;
    string $blendShape[] = `listAttr -m ("Genesis8FemaleBlendShapes.w")`;

    for ($item in $array)
    {
                
        //Create a wrap deformer from base G8F mesh
        
        select -r $item Genesis8FemaleFBXASC046Shape ;
        CreateWrap;
        select -r $item;
        
        //Iterate through each blendshape
    
        for($target in $blendShape)
        
        {
            
            //Get the name of the current object
            
            string $currentBlendShape = $target;
            
            //Enable the blendshape, duplicate and rename the geoemetry, and disable the blendshape
            
            setAttr ("Genesis8FemaleBlendShapes." + $currentBlendShape) 1;
            duplicate -rr;
            rename $currentBlendShape;
            setAttr ("Genesis8FemaleBlendShapes." + $currentBlendShape) 0;
            select -r $item;
        
        }

..........

}

I've isolated just the first part of the script, which is where the problems seem to be originating. There are two issues-

1) Upon running the script, I get two warning messages:
// Warning: Line 3.31 : Redeclaration of variable "$array" shadows previous declaration at line 1. Previous value will be overwritten by explicit initializer. // 
// Warning: Line 4.73 : Redeclaration of variable "$blendShape" shadows previous declaration at line 2. Previous value will be overwritten by explicit initializer. // 
2) The script takes more than 10 minutes to run, and on more than one occasion has caused Maya to run out of memory and crash. I am dealing with a large number of blendshapes (between 100-200), but in an earlier version of the script where I specifically called each blendshape by name, the entire script would finish in less than 30 seconds. I'm trying to update the script now so I don't have to edit the script manually every time I add or remove additional blendshapes to the main body.

Does anyone know what these warnings mean and if they're going to cause problems when I run the script? And is there anything I've overlooked that could account for the performance issues?

Thanks in advance :)
-Robbie

Replies

  • Panupat
    Offline / Send Message
    Panupat polycounter lvl 17
    A bit difficult to debug without the actual scene to test it on.
    I assume you only select 1 cloth before running this right? In that case you don't need to loop through $array and can simply use $array[0]
  • Robstein
    Offline / Send Message
    Robstein polycounter lvl 3
    I managed to figure out the solution to both issues! The warnings seem to have been caused by trying to declare and set both arrays before the first for loop. I reordered things a bit and now it runs without any problems.

    As for the slowdown, there was actually nothing wrong with the script - it was due to the viewport trying to display all the newly created blendshapes at once, which added up to over 64 million polys. No wonder Maya kept crashing  :#

    Here's the updated code:

        //Create an array of selected objects
        
        string $array[] = `ls -sl`;
        
        //Iterate through each object
        
        for ($item in $array)
        {    
             
            //Create a wrap deformer from base G8F mesh
            
            select -r $item Genesis8FemaleFBXASC046Shape ;
            CreateWrap;
            select -r $item;
            
            //Create an array of all blendshapes
            
            string $blendShape[] = `listAttr -m ("Genesis8FemaleBlendShapes" + ".w")`;
            
            //Iterate through each blendshape
            
            for($i=0;$i<size($blendShape);$i++)
            
            {
                
                //Get the name of the current blendshape
                
                string $currentBlendShape = $blendShape[$i];
                
                //Enable the blendshape, duplicate and rename the geoemetry, and disable the blendshape
                
                setAttr ("Genesis8FemaleBlendShapes." + $currentBlendShape) 1;
                duplicate -rr;
                rename $currentBlendShape;
                setAttr ("Genesis8FemaleBlendShapes." + $currentBlendShape) 0;
                select -r $item;
            
            }
                    
    ...

    }
  • haiddasalami
    Offline / Send Message
    haiddasalami polycounter lvl 14
    Something you can try to do is turn off the refreshing on the viewport might get a bit of performance there. 
Sign In or Register to comment.