Optional Variables in MEL

   My biggest problem with MEL Script is that once I’ve written a function and released it I can’t add any new variables to it.  This is an issue when you’re writing rig tools that are used across multiple studios and projects, and then an animator asks for a new addition to the rig.

   So late last year I had this idea.  What if every function I wrote had an extra input variable, a string that could contain any optional flag, which I can use to add extra options to a procedure without breaking existing uses of it?  Inside the function I could specify all my default values, that get replaced if it finds a different value in the string.

   I decided that I’m not likely to ever use tilde (~) so I’m using it to identify flags. (Maya’s own functions use the minus symbol, but it’s also used for negative numeric values, so I wanted something I’d never use)

// Create Cube Function has two input strings: name, and optional flags ;

createCube( “testCube” , “~visible 0 ~scale 2” ) ;

   I figured I couldn’t be the only person to think of using a string to contain multiple optional flags.  After a bit of googling I found a few people talking about the same idea, and I discovered ZooTools is doing the same thing, but instead of returning a single string, it returns a string array, which is a bit nicer than the single string because you don’t have to convert it into an array afterwards.  So I added that this afternoon.

Example code:

global proc string[] FlagValue ( string $flag , string $string )
{
    string $allFlags[] ;
    // find all flags in string
    int $tokens = `tokenize $string “~” $allFlags` ;
    for( $i = 0 ; $i < $tokens ; $i++ )
    {
       
        // find all values for each flag
        string $buffer[] = {};
        int $num = `tokenize $allFlags[$i] ” ” $buffer` ;
       
        // if found desired flag, spit it into an array
        if( $buffer[0] == $flag )
        {
            string $values[] ;
           
            for( $v = 1 ; $v < $num ; $v++ )
                {
                    $values[ size( $values ) ] = $buffer[$v] ;
                }
            print $values ;
            return $values ;
        }
    }
    return {} ;
}


global proc createCube ( string $name , string $flags )
{
    //////////////////////
    // Variables
    //////////////////////
    
    // defaults
    int $visible = 1 ;
    float $scale[] = { 1 , 1 , 1 } ;

    // Search $flags string for a match
    string $temp[] ;
    $temp = FlagValue( “visible” , $flags ) ; if ( size($temp) > 0 ) $visible = (int)$temp[0] ;
    $temp = FlagValue( “scale” , $flags ) ;
    if ( size($temp) > 0 ) $scale = { (float)$temp[0] , (float)$temp[1] , (float)$temp[2] } ;

    ////////////////////////
    // Create poly Cube
    ////////////////////////
    string $cube[] = `polyCube -name $name` ;
    setAttr ( $cube[0] + “.visibility” ) $visible ;
    scale -r $scale[0] $scale[1] $scale[2] $cube[0] ;
}

createCube( “testCube” , “~visible 0 ~scale 2 1 5” ) ;