Occasionally, in the course of a production, reports need to be generated on the status of the assets that have been created. This could be to monitor the work of an artist, to aid in the construction of a schedule, or to simply gain an understanding of the status of the current project. In this project, we will create a simple tool to write out a text file, formatted for human consumption. In this text file we will catalog all the polygonal objects in the scene, with details such as their associated materials and their component objects.
Similar to the examples seen previously in this chapter, the first task with any script that will write out the file is to gather the data, sort the data, and then to finally write the data out to the file in a format of our own design. The data gathering process is seen in Flowchart 12.1.
The procedures shown in the flowchart are a rather simple task at this point. Our concern for this project will be with constructing and formatting the text. Our goal will be to format the text into something resembling the following:
Polygonal Objects : Transform : TransformNode Name Shape : ShapeNode Name Geometry Info : Vertices : # of vertices Faces : # of faces Triangles : # of triangles Edges : # of edges Shader Info : Uses Shader : shader name Uses Shader : shader name
We will also place the name of all the file textures used, along with their resolutions , at the bottom of the text file, after all the object information. The format for this will be as follows :
Texture Files : File : full path to file Resolution : width x height
Notice that the colons of each section are aligned. We will have to carefully construct our strings to keep this alignment, with empty spaces, and possibly tab escape character, \t , used.
In Example 12.6, we begin gathering the information on which we want to base our report. For now, we will print out the gathered information to the Script Editor for testing.
Example 12.6: The code to find each polygon object and the associated information.
global proc sceneReport () { // get a list of every polygonal // object in the scene string $meshes[] = `ls -type "mesh"`; for ($each in $meshes) { // Gather Data on each polygon object // The parent object of any mesh node will be the // transform node associated with the shape node string $parents[] = `listRelatives -parent $each`; print $parents; // Testing print ($each + "\n"); // Testing // find the component information int $components[] = `polyEvaluate -vertex -face -triangle -edge $each` ; print $components; // Testing // gather the shader information string $connections[] = `listConnections $each`; string $shaders[]; for ($node in $connections) if (`nodeType $node` == "shadingEngine") $shaders[`size $shaders`] = $node; $shaders = `stringArrayRemoveDuplicates $shaders`; print $shaders; // Testing clear $shaders; } // Get list of Image files string $imageFiles[] = `ls -type "file"`; { string $actualFile = `getAttr ($iFile + ".fileTextureName")`; int $xRes = `getAttr ($iFile + ".outSizeX")`; int $yRes = `getAttr ($iFile + ".outSizeY")`; print ($actualFile + "\n"); // Testing print ($xRes + " "); // Testing print ($yRes + "\n"); // Testing } }
On the CD | The text for this script is found on the companion CD-ROM as Chapter_12/project_08/v01/sceneReport.mel. |
Obviously, our formatting needs some work, but we can see that we have successfully gathered all our data. Next, in Example 12.7, we add formatting. To adjust our formatting, we first print to the Script Editor, using the command scriptEditorInfo “clearHistory to clean out the History portion of the Script Editor first. After using print statements to properly format the output in the Script Editor window, we can simply change the print statement to fprint statements to write to the file. We will place our information in a file in the temporary directory.
Example 12.7: By changing our print statements to fprint , we create our file.
global proc sceneReport () { // create a string naming the file. Place it in // the users temp directory. string $fileName = (`internalVar -userTmpDir` + "sceneReport.txt") ; // Open the file for writing and capture the file // identifier for later use int $fileID = `fopen $fileName "w"`; // get a list of every polygonal object in the scene string $meshes[] = `ls -type "mesh"`; for ($each in $meshes) { // Gather Data on each polygon object // The parent object of any mesh node will be the // transform node associated with the shape node string $parents[] = `listRelatives -parent $each`; for ($item in $parents) fprint $fileID ($item + "\n"); // Testing fprint $fileID ($each + "\n"); // Testing fprint $fileID ($each + "\n"); // find the component information int $components[] = `polyEvaluate -vertex -face -triangle -edge $each` ; for ($item in $components) fprint $fileID ($item + "\n"); // Testing // gather the shader information string $connections[] = `listConnections $each`; string $shaders[]; for ($node in $connections) if (`nodeType $node` == "shadingEngine") $shaders[`size $shaders`] = $node; $shaders = `stringArrayRemoveDuplicates $shaders`; for ($item in $shaders) fprint $fileID ($item + "\n"); // Testing clear $shaders; } // Get list of Image files string $imageFiles[] = `ls -type "file"`; for ($iFile in $imageFiles) { string $actualFile = `getAttr ($iFile + ".fileTextureName")`; int $xRes = `getAttr ($iFile + ".outSizeX")`; int $yRes = `getAttr ($iFile + ".outSizeY")`; fprint $fileID ($actualFile + "\n"); // Testing fprint $fileID ($xRes + " "); // Testing fprint $fileID ($yRes + "\n"); // Testing } fclose $fileID; }
On the CD | The text for this script is found on the companion CD-ROM as Chapter_12/project_08/v02/sceneReport.mel. |
Now, in the temp directory, we find a properly formatted text file with all the information in it. Obviously, we don t want to force the user to change the MEL code or go searching for the file in his temp directory. We will now add a modal dialog window provided specifically for this situation, the File dialog. The File dialog, shown in Figure 12.1, creates a window allowing the user to point to a directory and select a pre-existing file. Unfortunately, MEL provides no browser for creating a new file.
By capturing the return string from the command, fileDialog , we get the name of the user s target file. Note that to Maya for Windows, an additional type of file dialog exists, the fileBrowserDialog , which provides additional options. If the script is for public distribution and uses the fileBrowserDialog , always use the about command to confirm that the user is operating in a Windows environment, and use the fileDialog if not. In Example 12.8, we implement the fileDialog and add some header information to the file. Also note, referring to the complete script on the companion CD-ROM, that we have added a string return , the name of the file created. This follows the standard set by Maya, and is simply good practice.
Example 12.8: Implementation of the fileDialog command.
global proc sceneReport () { // open a file dialog to name the file. string $fileName = `fileDialog` ; // Open the file for writing and capture the file // identifier for later use int $fileID = `fopen $fileName "w"`; // Add scene file name string $mayaFile = `file -query -sceneName`; fprint $fileID ("Scene Report : " + $mayaFile + "\n"); // add Maya version information string $mayaVer = `about -version`; fprint $fileID ("Maya Version : " + $mayaVer + "\n\n"); // get a list of every polygonal object in the scene . . .
On the CD | The text for this script is found on the companion CD-ROM as Chapter_12/project_08/v03/sceneReport.mel. |
While we could, at this point, consider this tool done, the simple text file, while usable, is somewhat less than presentable. It also is somewhat less than convenient . We will now alter the script to instead create our file in HTML, which can easily be shared on a company s intranet. It also gives us much more robust formatting options.
To begin, we create a template Web page. Using any of the many visual editors available, we can create the Web page to appear in the format we want, including any tables, fonts, and so forth. We can also include images of our texture maps, assuming we are using a format readable by our Web browser as the texture map. Even if that is not the case, we could use system to call on a command-line image editor, like AliasWavefront s imgcvt command to convert and resize the image to a Web-compatible format. The Web version of our scene report is seen in Figure 12.2, page 426.
This HTML file, created with Microsoft Word, is then opened in a text editor to take the essential elements. Ideally, a person skilled in hand coding HTML documents could assist, both to optimize the code, and likely improve the overall design of the page.
After editing the HTML code that generates our page to its essential elements, we get the HTML code on the CD-ROM under /chapter12/project_08/html/layout.html. We have used some slightly more advanced features, such as using a font called Tahoma, available on most default OS installations, and thanks to the nature of HTML doesn t do any harm if the font is not installed. By simply adapting this code to our MEL script and judiciously using the fprint command, we can have Maya generate out a file readable by our Web browser. See Example 12.9.
Note | This script uses an accessory script found on the CD-ROM under /bonus_scripts called dirNameExt.mel . dirNameExt returns a string array, the first index holds the directory, the second holds the filename, and the third holds the extension. |
Example 12.9: Formatting our text into HTML.
global proc string sceneReport () { // open a file dialog to name the file. string $fileName = `fileDialog` ; // Open the file for writing and capture the file // identifier for later use int $fileID = `fopen $fileName "w"`; // Get scene file name string $mayaFile = `file -query -sceneName`; // Add HTML header code fprint $fileID "<html>\n"; fprint $fileID "<head>\n"; fprint $fileID "<title>\n"; fprint $fileID $mayaFile; fprint $fileID "</title>\n"; fprint $fileID "<style>\n"; fprint $fileID "<!--\n"; fprint $fileID "@font-face\n"; fprint $fileID "\t{font-family:Tahoma;\n"; fprint $fileID "\tpanose-1:0 2 11 6 4 3 5 4 4 2;}\n"; fprint $fileID "-->\n"; fprint $fileID "</style>\n"; fprint $fileID "</head>\n\n"; fprint $fileID "<body bgcolor=white style='tab- interval:.5in'>\n"; // Add File Name Info fprint $fileID "<p>\n"; fprint $fileID "<span style='font-size:13pt; font-family:Tahoma'>\n"; fprint $fileID ("<b>Scene Report: " + $mayaFile + "</b>\n"); fprint $fileID "</span>\n"; fprint $fileID "</p>\n"; // add Maya version information string $mayaVer = `about -version`; fprint $fileID "<p>\n"; fprint $fileID "<span style='font-size:11pt; font- family:Tahoma'>\n"; fprint $fileID ("<b>Maya Version " + $mayaVer + "</b>\n"); fprint $fileID "</span>\n"; fprint $fileID "</p>\n"; // get a list of every polygonal object in the scene string $meshes[] = `ls -type "mesh"`; fprint $fileID "<p>\n"; fprint $fileID "<span style='font-size:12pt; font- family:Tahoma'>\n"; fprint $fileID "<b><i>Polygonal Objects :</i></b> </span>\n"; fprint $fileID "</p>\n"; for ($each in $meshes) { // Gather Data on each polygon object // The parent object of any mesh node will be the // transform node associated with the shape node string $parents[] = `listRelatives -parent $each`; // Build table for transform and shape node fprint $fileID "<table border=0 cellspacing=0 cellpadding=0 style= 'border- collapse:collapse'>\n"; fprint $fileID "<tr>\n"; fprint $fileID "<td width=145 valign=top style = 'width:145pt;padding:0in 5.4pt 0in 5.4pt'>\n"; fprint $fileID "<p align=right style= 'text- align:right'>\n"; fprint $fileID "<span style='font-size:12pt; font- family:Tahoma'>\n"; fprint $fileID "<b>Transform :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=300 valign=top style= 'width:300pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p> <span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $parents[0] ; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "<table border=0 cellspacing=0 cellpadding=0 style= 'border- collapse:collapse'>\n"; fprint $fileID "<tr>\n"; fprint $fileID "<td width=145 valign=top style = 'width:145pt;padding:0in 5.4pt 0in 5.4pt'>\n"; fprint $fileID "<p align=right style= 'text- align:right'>\n"; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n"; fprint $fileID "<b>Shape :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=300 valign=top style= 'width:300pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p> <span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $each ; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "</table>\n" ; fprint $fileID " \n" ; // find the component information int $components[] = `polyEvaluate -vertex -face -triangle -edge $each` ; // Write the table for the component info fprint $fileID "<table border=0 cellspacing=0 cellpadding=0 style='border- collapse:collapse'>\n\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text- align:right'>\n" ; fprint $fileID "<span style='font-size:10.0pt; font-family:Tahoma'>\n"; fprint $fileID "<b>Geometry Info :</b> </span> </p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p> </p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n" ; fprint $fileID "<b>Vertices :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; font-family:Tahoma'>\n" ; fprint $fileID $components[0]; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n" ; fprint $fileID "<b>Faces :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p><span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $components[1]; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n" ; fprint $fileID "<b>Triangles :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p><span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $components[2]; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n" ; fprint $fileID "<b>Edges :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; font-family:Tahoma'>\n" ; fprint $fileID $components[3]; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "</table>\n" ; fprint $fileID " \n" ; // gather the shader information string $connections[] = `listConnections $each`; string $shaders[]; for ($node in $connections) if (`nodeType $node` == "shadingEngine") $shaders[`size $shaders`] = $node; $shaders = `stringArrayRemoveDuplicates $shaders`; fprint $fileID "<table border=0 cellspacing=0 cellpadding=0 style='border - collapse:collapse'>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style='text - align:right'>\n" ; fprint $fileID "<span style='font-size:10.0pt; font-family:Tahoma'>\n" ; fprint $fileID "<b>Shader Info :</b></span></p>\n"; fprint $fileID "</td>\n" ; fprint $fileID "<td width=280 valign=top style= 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID " \n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; // Loop builds table of every shader used for ($eachShader in $shaders) { fprint $fileID "<tr>\n" ; fprint $fileID "<td width=163 valign=top style= 'width:163pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style= 'text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID "<b>Uses Shader :</b>"; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; 'width:280pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p><span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $eachShader; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; } fprint $fileID "</table>\n" ; fprint $fileID " \n\n" ; fprint $fileID " \n\n" ; fprint $fileID " \n\n" ; } // Get list of Image files string $imageFiles[] = `ls -type "file"`; fprint $fileID " \n\n" ; fprint $fileID "<p><span style='font-size:12pt;font- family:Tahoma'>\n" ; fprint $fileID "<b><i>Texture Files :" ; fprint $fileID "</i></b></span></p>\n" ; for ($iFile in $imageFiles) { string $actualFile = `getAttr ($iFile + ".fileTextureName")`; int $xRes = `getAttr ($iFile + ".outSizeX")`; int $yRes = `getAttr ($iFile + ".outSizeY")`; fprint $fileID "<img width=256 height=256 src=\"\n" ; fprint $fileID $actualFile ; fprint $fileID "\">\n" ; fprint $fileID "<table border=0 cellspacing=0 cellpadding=0 style='border- collapse:collapse'>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=60 valign=top style= 'width:60pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style= 'text- align:right'>\n" ; family:Tahoma'>\n" ; fprint $fileID "<b>File :</b></span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "<td width=352 valign=top style= 'width:352pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p><span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID $actualFile ; fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "<tr>\n" ; fprint $fileID "<td width=60 valign=top style= 'width:60pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p align=right style= 'text- align:right'>\n" ; fprint $fileID "<span style='font-size:9pt; font- family:Tahoma'>\n" ; fprint $fileID "<b>Resolution:</b></span></p>\n"; fprint $fileID "</td>\n" ; fprint $fileID "<td width=352 valign=top style= 'width:352pt;padding:0in 5.4pt 0in 5.4pt'>\n" ; fprint $fileID "<p><span style='font-size:9pt; font-family:Tahoma'>\n" ; fprint $fileID ($xRes + "x" + $yRes); fprint $fileID "</span></p>\n" ; fprint $fileID "</td>\n" ; fprint $fileID "</tr>\n" ; fprint $fileID "</table>\n" ; } // print the footer fprint $fileID "</body>\n" ; fprint $fileID "</html>\n" ; // Close the file fclose $fileID ; // Return the created file return $fileName; }
On the CD | The text for this script is found on the companion CD-ROM as Chapter_12/project_08/final/sceneReport.mel. |
We have seen how by using the file writing capabilities of MEL, we are able to create both simple text files and more robust documents for human consumption. Note that the second file we created was, in fact, code to be interpreted by other software. Using Maya to create external files is a wonderful way to share information about a scene with users who might not have ready access to Maya, or to coordinate productions from remote locations.