Using the TCLBox

return to main index

Pixar's documentation provides a general description of SLIM's TCLBox. However, it doesn't give an explicit example of using, say, an "external" Tcl script with a TCLBox in order to control the generation of RIB from a RIBBox that has been attached to an object in a Maya scene. This tutorial gives an example of the kind of work-flow shown on the right.

Suppose you wish to generate an animation consisting of many expanding spherical clouds of points. Maya's particle system could be used but if the effects shot requires several dozen clouds each of which consists of hundreds of thousands of points then clearly the performance of Maya, the animator, the graphics card and the cpu are going to deteriate.

Using a helper app to procedurally generate the points when, and only when, prman needs to render each cloud is far more efficient. Instead of the animator trying to directly manage huge amounts of on-screen complexity, simple proxy objects can act as surrogates, or "stand-ins", for each of the clouds. However, for the clouds to be rendered properly accurate values for the bounding box must be given when the helper app is assigned to the proxy objects.


next >>


Suppose, we have a helper app called cloud.exe that needs to be passed the radius of the cloud of points it is to generate. The script within an mtor RIBBox might look like this,

Procedural "RunProgram" \["H:/helper_apps/cloud" "2.0"\] 
\[-2 -2 -2 2 2 2\]

The backslashes are required before each of the square brackets because the text in a RIBBox is processed ie. parsed, by the Tcl interpreter before it is written into the RIB file. If the radius changes during the course of the animation, then fixed values for its bounding box ie. [-2 -2 -2 2 2 2] will result in rendering errors. Obviously, we must compute new bounding box values for each frame.

The easiest solution is to keyframe the size of the (cube) proxy object, then use mtor's built-in Tcl procedure mattr to reference, say, the width of the cube. Because the radius of the cloud is half the size of the bounding box we must use the Tcl procedure expr to divide the width. For example,

Procedural "RunProgram" \["H:/helper_apps/cloud" 
"[expr [mattr "polyCube1.width" $F] / 2]"\]
\[ -[mattr "polyCube1.width" $F] -[mattr "polyCube1.width" $F]
   -[mattr "polyCube1.width" $F]  [mattr "polyCube1.width" $F] 
    [mattr "polyCube1.width" $F]  [mattr "polyCube1.width" $F] \]

The text in the ribbox is getting messy. But what should we do if we wish to resize the proxy object procedurally rather than using key framing? If you have used Procedural "RunProgram" in a RIBBox you will know the frustration, on Windows at least, of slim crashing when the script is run as a result of pressing the RIBBox preview window!! Loosing scripts as a result of such crashes is no fun.

<< prev

next >>


One way of avoiding clutter, as well as being able to pre-calculate values prior to their use in a RIBBox is to write and save an "external" Tcl script that is accessed via slim's TCLBox interface which in turn makes its output available to a RIBBox. A side benefit of the approach shown below is that should SLIM crash then at least the external Tcl script is unaffected and besides which its easier to build up a library of useful scripts for use across different projects.

Lets assume you have a helper app, for example, cloud.c. Using Cutter you can test cloudsize.tcl - this is explained within the script itself. In a Maya scene add a RIBBox and a TCLBox to a SLIM palette - as shown on the right - and attach them to a simple poly cube.

Insert the following text into the TCLBox,

source "H:/tcl/cloudsize.tcl"
set statement [ribout [mattr "polyCube1.width" $F]]

Insert this text into the RIBBox,

Surface "plastic" "Kd" 1
Opacity 0 0 0


<< prev

next >>


To understand what is happening lets begin with the external Tcl script itself.

proc ribout { bBox } {
set radius [expr double($bBox) / 2.0]
set path "H:/helper_apps/cloud"
return "Procedural \"RunProgram\" \[\"$path\" \"$radius\"\] \[-$bBox -$bBox -$bBox $bBox $bBox $bBox\]"

The script implements a Tcl procedure named ribout. The procedure receives a single value representing the side of the bounding box of a cube. Two local variables, radius and path, are assigned values that will be used when an output string, something like...

Procedural "RunProgram" \["H:/helper_apps/cloud" "2.0"\] 
\[-2 -2 -2 2 2 2\]

is returned from the procedure. The sole purpose of this procedure is to write the text that will eventually be inserted into a RIBBox. In the TCLBox the script file is sourced which means it is processed or parsed by the Tcl interpreter. As a consequence of sourcing the ribout procedure can be called from the TCLBox ie.

set statement [ribout [mattr "polyCube1.width" $F]]

The variable, statement, is assigned the text returned from the procedure. The procedure is passed the output from the slim function mattr that extracts the "width" attribute of the cube to which the TCLBox is attached. We now have a variable statement containing the text to be inserted into the RIBBox.

Accessing the text from the RIBBox is simply a matter of getting Tcl to reference the value of the variable ie. $statement.

An explanation about setting values procedurally will be presented later (5.5.03).

<< prev

next >>

© 2002-4 Malcolm Kesson. All rights reserved.