Category Archives: SCRIPTING

File Handling in MEL – Part2


Problem:
To perform a set of file operations including creation, deletion and listing of files and directories
Solution:

Creating  folders using sysFile command

 sysFile -makeDir "/home/user/mayaFolder"; //unix
 sysFile -makeDir "C:/Documents and Settings/MayaFolder"; //windows
 

Get the list of mel scripts in the  maya scripts directory

 getFileList -folder "/home/user/maya/scripts" -filespec "*.mel";
 

Stripping a file path in to directory name and base name.

 $filePath = "/home/user/maya/2011-x64/scripts/userSetup.mel";
 $dirName = dirname($filePath);
 $baseName = basename($filePath , "/");
 

Commands:
sysFile, dirname, basename
Discussion:
The sysFile command can be used to create, delete or rename files and directories from within Maya. The dirname and basename commands can be used to strip a file path in to the absolute path and filename. Using a combination of these three commands its possible to perform a variety of OS level operations from within the Maya workspace itself.

Advertisements

File Handling in MEL – Part1

In this tutorial, we will be covering the file handling functionality provided by MEL.
Problem:
Writing out to and reading from file formats other than maya ascii and binary.
Solution:
Write the file location of texture maps used in a scene

 $fileId = `fopen "/home/user/textureList.txt" "w"`;
 $fileNodes = `ls -type "file"`;
 if( size($fileNodes)==0 ) {
 fprint $fileHandle "No File Nodes found in scene";
 }
 else {
 for ($each in `ls -type "file"`) {
 fprint $fileHandle (getAttr ($each + ".fileTextureName") + "n");
 }
 }
 fclose $fileHandle;
 

Read the contents of the written file and print the contents of each line.

 $fileHandle = `fopen "/home/user/textureList.txt" "r"`;
 while (! `feof $fileHandle`) {
 $eachLine = `fgetline $fileHandle`;
 print $eachLine;
 }
 fclose $fileHandle;
 


Commands:

fopen,fprint,fgetline,fclose,getAttr

Discussion:

The first code block writes the file paths of all the texture maps in the scene to a text file names textureList.txt. The fopen command returns a file identifier which can be used to write in to or read from the file specified in the command.An additional string can also be mentioned to denote whether to open the file for read,write or append operation(r ,w or a). Data can be written to the file using fprint command. Its advised to close the file handle once the read, write or append operation is finished. This can be done using the command fclose.

Data can be read by opening the file handle in “r” mode. The fgetline command reads the contents of the file line by line, which is then printed on to the screen.

Adding Maya Panels to MEL GUIs

Problem:
Adding default scripted panels(Visor, Reference Editor etc) in Maya to custom UIs created using MEL
Solution:

 if(!`scriptedPanelType -exists visorPanel1`)
 scriptedPanelType
 -createCallback "createVisorPanel"
 -initCallback "initVisorPanel"
 -addCallback "addVisorPanel"
 -removeCallback "removeVisorPanel"
 -saveStateCallback "saveStateVisorPanel"
 -deleteCallback "deleteVisorPanel"
 -unique true
 visorPanel1;

if (`window -exists myWindow`)deleteUI myWindow;
 {
 window -t "My Window" myWindow;
 frameLayout -lv false -bv false myLayout;
 scriptedPanel -e -p myLayout -type visorPanel1 visorPanel1;
 showWindow myWindow;
 }
 

Commands:
scriptedPanelType, scriptedPanel, getMayaPanelTypes

Discussion:

Default Scripted panels can be added to your custom GUIs using the scriptedPanel command. Before specifying the command the scripted panel should be defined using the command scriptedPanelType. By specifying the type of scripted panel using the -type flag in scriptedPanel command creates an instance of the specific scripted panel. You can also get a list of the default scripted panels in Maya using the command getMayaPanelTypes(1). In the above example an instance of Visor panel is created and then added to the custom UI myWindow.

The query regarding this functionality in MEL was raised by one of the visitors to this blog. Hence I thought it would be great to include this as a tutorial just in case some of you might find it useful. You may feel free to mail me in case you have any topics which you feel could be included in the Tutorials section. I am not guaranteeing a quick reply, but whenever I get free time from my work schedule I would try to include those topics too (provided I know the answer to your question).

Array manipulation in MEL – Part 2

As we saw in PART 1, stringArrayContains() and stringArrayInsertAtIndex() are two handy commands that can be used to manipulate arrays. In this Tutorial we will explore few more commands that can be used in the context of strings.

Commands:
stringArrayRemoveDuplicates(), stringArrayCatenate(), stringArrayToString()

stringArrayRemoveDuplicates() can be used to remove duplicate entries from an array. The code block in PART1 can be simplified to something like this.

 for ($each in $transformList)
 {
 if (stringArrayContains($each,$cleanList)!=1)
 {
 stringArrayInsertAtIndex($i,$cleanList,$each);
 $i++;
 }
 }
 

can be simplified to something like this


$cleanList = stringArrayRemoveDuplicates($transformList);

stringArrayCatenate() can be used to catenate two arrays together. Suppose we want to add a suffix “_geo” to all geometries in the scene, the following script can be made use of

 global proc ak_addSuffixAllGeo()
 {
 string $polyList[],$nurbsList[];
 $polyList = `ls -type "mesh"`;
 $nurbsList = `ls -type "nurbsSurface"`;
 $allList = stringArrayCatenate($polyList,$nurbsList);
 $transformList = `listRelatives -p $allList`;
 $cleanList = stringArrayRemoveDuplicates($transformList);
 for ($each in $cleanList)
 {
 $newName = $each + "_geo";
 rename $each $newName;
 }
 }
 

stringArrayToString() can be used to generate a string containing elements of the array separated using a separator string mentioned in the command.

 $myFolderTree = {"My Documents","maya","scripts"};
 $backSlash = "\";
 print (stringArrayToString($myFolderTree,$backSlash));
 

This would print My Documentsmayascripts” when executed in the Script Editor. This can be handy in cases where you create an UI from which the user selects a list of options which can include a scene name, a scene type (model, tex, rig), scene location etc and saving the file to particular location. You can build an array which includes all these individual user choices and encode it in to a OS recognizable string, which can be used for reading from or writing to the particular file location.

Array manipulation in MEL – Part 1

Here, in this tutorial we will see some of the array manipulation commands in MEL that can be put to use while creating your own scripts.
Problem:
Getting a List of objects that are of a particular type, based on user input.
Solution:

ak_listObjectsOfType(“$type”)

where $type can be mesh, nurbsCurve, ikHandle, joint, multiplyDivide….

 global proc ak_listObjectsOfType(string $type)
 {
 string $transformList[],$cleanList[],$conflictList[];
 string $newName,$each;
 $choiceList = `ls -type $type`;
 if ($type == "nurbsCurve" || $type == "mesh")
 {
 $transformList = `listRelatives -parent $choiceList`;
 }
 else
 {
 $transformList = $choiceList;
 }
 int $i = 0;
 for ($each in $transformList)
 {
 if (stringArrayContains($each,$cleanList)!=1)
 {
 stringArrayInsertAtIndex($i,$cleanList,$each);
 $i++;
 }
 }
 print $cleanList;
 }
 

Commands:
ls, listRelatives, stringArrayContains, stringArrayInsertAtIndex
Discussion:
The result can be easily achieved using the command ls. Using the -type flag followed by the object type will give a list of objects of that specific type.
For eg: ls -type “ikHandle” will return a list of all ik handles in the scene
But specifying mesh or nurbsCurve will give the shape names instead of the transform names. By running a listRelatives -parent on the returning list will give the transform nodes, but this will include duplicate entries if the mesh is having a deformer attached to it since ls -type “mesh” return a list of all the intermediate objects too. So we will be using the script listed above to print out objects that matches the user entry type.

The pseudocode for the script is as follows.


global procedure ak_listObjectsOfType($type of type string )
 {
 declare String Arrays $transformLis,$cleanList and $conflictList
 declare String $newName and $each;
 store the value of ls command of node type $type in $choiceList
 if ($type  is "nurbsCurve" or   "mesh")
 {
 store the parents of $choiceList in $transformList;
 }
 else
 {
 Assign  the value of $choiceList itself to $transformList
 }
 initialize index number $i  to zero;
 for (each element  in $transformList)
 {
 if (string Array $cleanList doesn't contain $each)
 {
 insert $each at position $i of $cleanList
 increment the index value $i by 1
 }
 }
 print the $cleanList
 }

The command stringArrayContains() checks a string exists in a string Array or not and returns true of false. stringArrayInsertAtIndex() will insert a string in to the index position position in the string Array. Both the command names are self-explanatory.

CODE – CG – MEL Scripting – Preface

After coming across so many queries about MEL Scripting in several computer graphics forums, I felt it would be a great idea to start a MEL Scripting Tutorial Series under CODE-CG where Artists and Programmers can learn how to get their job done by making use of MEL. You might be skeptical why we need a Tutorial series when we already have numerous books available in the market that cover MEL. I would say, all those books will tell you how to write a MEL Script but fail to tell where to use them. Having spend a couple of years in the Computer Graphics industry this is the pattern that I observed.

1. Artists are too lazy to learn Scripting even if they know that scripting knowledge can streamline their workflow a lot.

2. Programmers who know Scripting, never always come up with the Scripts that completely makes use of the techniques an experienced Artist is equipped with.

There will always be a communication gap between the Artists and the Programmers which results in a few thousand lines of code, which would have made use of better logic, if they both knew what the other person was looking for.

Hence I decided that the structure of the Tutorials should be in such a way that each MEL command that we examine here should point to the exact production scenario where it can be made use of, so that whether you are an Artist or a Programmer, you know exactly Where and How you gotta use it.