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.

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.

Qcalendar widget for Maya GUI using PyQt

QCalendar widget is one of the handy widgets provided by PyQt that can be included in your maya custom UI for the user to deal with date information.Apart from providing current date information to the user, Qcalendar widget can be used to get valid date inputs from the user.It includes a set of signals like selectionChanged() and currentPageChanged() which can be used to update the information based on user selection.

The selected date can be retrieved using the method selectedDate() which will return a Qdate.The day() and month() methods of QDate can be used to get seperate day and month values. Similarly longMonthName() method can be used to get the long names of the month since the method month() gives the month in number format (12 for December).

The usage is as follows:

myDate = myCalendar.selectedDate()

month = myDate.month()

day = myDate.day()

monthName = myDate.longMonthName(myDate.month())

The calendar grid visibility can be set for east readability using the setGridVisible() method which will accept a boolean value.

myCalendar.setGridVisible(True)

Autodesk Backburner job submission using cmdjob.exe

Autodesk’s decision to ship Backburner 2008 with Maya2010 has leveraged  the utilisation of resources across the network for executing batch rendering task from a single node point. Backburner jobs can be easily created from within Maya 2010 using the Create Backburner Job command under the Render menuset as shown in the  figure below.

This will bring up a window similar to the one shown below.

Here you can specify the job name, frame range, number of tasks, Renderer and also specify the IP address of the machine in which the backburner Manager is running.

But the real power of backburner is revealed when you get under the hood and explore the power of the command line based utiliy cmdjob.exe. This is a handy tool for adding jobs to backburner manager for  literally any version of maya and not even just maya even Softimage, Aftereffects, and Nuke projects with a change in the passed arguments.The cmdjob utility can be accessed from within the backburner installation directory.

The basic syntax for the cmdjob is as follows CMDJOB <Options> executable to run <executable parameters>

By specifying the executable for the specific version of maya and passing the arguments for the maya batch we can trigger renders across multiple machines in the network and still monitor the progress using the backburner monitor.For example:

cmdjob.exe -jobName myRenderJob -jobNameAdjust -manager localhost -priority 50 -numTasks noOfTasks -taskName 1 -leaveInQueue “C:Program Files (x86)AutodeskMaya2009binRender.exe” -r mr -s 0 -e 196 -of tiff -proj projectPath -rd renderDirectory fileName.ma

will add a job named myRenderJob to manager running in the same machine(localhost) using Maya2009 batch using renderer mentalray(mr) for frame range o to 196 with file format of tiff to renderDirectory location for file named fileName.ma.It will distribute the job to noOfTasks number of machines in which backburner server is running.

You can get a list of all the valid parameters accepted by cmbjob from the list below

Maya Muscle Smart Collision Test

This is one of the demo videos from the Maya muscle smart collision test, which I  have been doing for the past few days.My initial plan was to start of with the skinning using Maya joints itself and convert it to Maya muscle system.But later I changed my mind and decided to go with rigorous testing of all the options provided by the Maya muscle menu set.Even though I had a glimpse at the options during the release of maya 2008 extension 2 itself, this was the first time I got to explore the skin weight options provided by Autodesk. Believe me, Autodesk has packed a lot of options keeping in mind the immediate need of a character setup artist that you will never want to go back again.

This one is the image of the muscle setup I used for testing the deformations.I didn’t spend much time on sculpting the muscle shapes.The target was to simplify various muscle groups in to one which would provide me enough options to test out the deformations.

maya_muscle_arm

Of course there were some bugs here and there which I found quite irritating, I was fortunate enough to find some solutions to them.

1.Maya was retaining the selection of the first muscle objects created showing some garbage values in the channel box.Unless you undo the first muscle and start it all over again, Maya wont show any signs of defeat.

2.Maya would end up in a fatal error if you ever happen to scrub the time line once the muscles have been bound to the mesh.This can of course be fixed by caching the geometry, But users like me who got accustomed to  skinning the models by setting keys on the joints, are left with no choice other that creating floating GUI to control the joint rotation without deselecting the geometry.

Overall the collision feedback is fairly good with lot of skinning options  to control each invidual portion of the geometry.

strechy ik with variable autostretch tutorial

This tutorial will demonstrate the procedure to setup a stretchy ik setup in maya using utility nodes.The procedure involves the use of maya utility nodes (clamp,addDoubleLinear and multiplyDivide) to setup a stretchy ik chain with custom attribute autostretch that will allow the animator to predefine the extend to which the joints get stretched.

you can download the example file here