Next Previous Contents

6. Scripting Interface

The Ayam scripting interface is mainly a number of Tcl procedures and Tcl commands that are also used internally by the application, e.g. the main menu entry "File/New" calls the scripting interface command "newScene" (among other commands). Using the scripting interface means to call these commands on your own possibly in a mix with standard Tcl script code.

Furthermore, using Tcl and its introspection facilities, you could easily modify the code Ayam consists of. This is, however, not recommended for good reasons (unless you read the Ayam source code and really know, what you are doing). So watch out for already existing procedures and commands when implementing your own! Using procedures and commands not listed in this documentation is dangerous too. Implementation and interfaces of those procedures and commands may change in future versions without notice.

In Tcl, all variables, procedures, and commands are case sensitive, it really is "sL" and not "sl" and not "SL".

The scripting interface may be used directly from the console of Ayam. You can, of course, also write scripts in your own Tcl script files, that may be loaded at any time into Ayam using the console and the Tcl command "source". You can also arrange for a script file to be executed automatically on every application startup using the preference setting "Main/Scripts". Moreover, on the X11 and Aqua window systems, Ayam is able to execute script code sent via the Tk "send" command or the AppleScript "tell" command from external applications.

In contrast to other modelling environments, in Ayam there is another way to run scripts. In Ayam, scripts may also be attached to script objects and run when the notification mechanism updates the scene. See also section Script object. Even normal objects can trigger scripts upon notification using BNS or ANS tags. See also sections Before Notify Script and After Notify Script.

Note that most of the scripting interface commands listed in this documentation work in the background, without changing anything to the Ayam GUI and Ayam view windows, for the sake of execution speed. If you want your changes to become visible you have to update the various parts of the GUI (property GUIs, view windows) explicitly (see also section Updating the GUI). However, since Ayam 1.13 it is also possible to automatically run GUI updating commands in the console by using <Shift+Return> instead of <Return> when issuing scripting interface commands.

If you want your changes to be undoable, you have to arrange for this manually too (see the documentation of the undo command: Undo).

From scripts it may be necessary to check wether an error occured during the execution of a command. All commands return TCL_OK in any case, so checking their return value avails to nothing, but they set the global Tcl variable "ay_error" to a value higher than 1 if an error occured. You need to set it to zero before and check it after the operation in question to see whether the operation performed successfully:


proc myProc { } {
  set ::ay_error 0
  copOb
  if { $::ay_error > 1 } {
    ayError 2 "myProc" "Error copying object!"
  }
}

6.1 Global Variables and Arrays

Several global variables and arrays exist in the Ayam Tcl context, that may be useful for scripts.

Global Variables

The Global Array ay

The global array "ay" holds application state variables. Furthermore, you can find the paths to important widgets (e.g. the tree widget for the object hierarchy or the currently active view) in this array. Use "parray ay" in the console to see what is there. More documentation to come.

The Global Array ayprefs

The global array "ayprefs" holds preferences data. The complete array is saved in the "ayamrc" file upon exit, so be careful when adding new entries. You can reset your "ayamrc" file anytime using the command line option "-failsafe". See also section Ayamrc File. Use "parray ayprefs" in the console to see what is there. More documentation to come.

The Global Property Management and Data Arrays

For every property, a corresponding global array exists, where the data of the property is saved. This global array only holds useful data when the respective property GUI is active, or when it has been filled explicitly by the so called get-property callback. The data may be transferred back to the selected object using the so called set-property callback. The names of the array and the callbacks may be inferred from another global array that is always named like the property itself, e.g. for the tags property the following global array "Tags" is defined:


Tags {
arr   tagsPropData
sproc setTagsp
gproc getTagsp
w     fTagsAttr
}

The entry arr designates the name of the global property data array (thus, tags data is stored in an array called "tagsPropData"). If sproc or gproc are empty (""), a standard callback named "setProp" or "getProp" should be used to get or set the property values. Otherwise sproc and gproc designate the set-property and get-property callbacks respectively. But for the tags property, the procedures "setTagsp" and "getTagsp" should be used. The last entry, "w", is the path and name of the main property GUI window.

Since Ayam 1.16, the global property management array may be created easily using the new scripting interface command "addPropertyGUI".

The following global arrays and callbacks to get or set the data exist:

propertyarrayget-property callbackset-property callback
TransformationstransfPropDatagetTrafosetTrafo
AttributesattrPropDatagetAttrsetAttrp
MaterialmatPropDatagetMatsetMat
TagstagsPropDatagetTagspsetTagsp

Property Arrays and Callbacks


Note that this list is pretty much incomplete, however you can always infer such information using commands like "parray Tags" in the Ayam console!

See also section Manipulating Properties for more information on how to edit property values from the scripting interface.

6.2 Index of Procedures and Commands

This section provides documentation on the most important scripting interface commands and procedures of Ayam sorted by category.

All commands are documented in the following scheme:

Getting Help on Scripting Interface Commands

Since Ayam 1.8.2 a scripting interface command named "help" is available, that displays the help of scripting interface commands using a web browser (similar to the "Help on Object" feature):

Creating Objects

To create new objects the "crtOb" command can be used.

Manipulating the Selection

These commands are probably the most important ones, because many other scripting interface commands operate on selected objects only:

selOb - select object(s):

withOb - execute a command on certain selected object(s):

sL - select last object:

hSL - hidden select last object:

Manipulating Properties

Since Ayam 1.9 two new commands are implemented that ease the manipulation of property values from the scripting interface:

getProperty - get single property value

setProperty - set single property value

In contrast to "setProperty", here is an equivalent example for the direct (fast) access of property values:


getProp
set SphereAttrData(Radius) 3.0
setProp

See also section Global Property Management and Data Arrays.

Clipboard Operations

These commands operate the object clipboard:

copOb - copy object:

cutOb - cut object:

pasOb - paste object:

delOb - delete object:

pasmovOb - paste (move) object:

The following commands operate the property clipboard, which is totally independent from the object clipboard.

pclip_copy/copyProp - copy a property to the property clipboard

pclip_paste/pasteProp - paste a property

Hierarchy Operations

These commands manipulate the current level of Ayam:

goDown:

goUp:

goTop:

Transformations

These commands transform objects or selected points of objects:

movOb - move objects:

rotOb - rotate objects:

scalOb - scale objects:

movPnts - move selected points:

rotPnts - rotate selected points:

scalPnts - scale selected points:

delegTrafo - delegate transformations:

applyTrafo - apply transformations:

Manipulating Shaders

These commands operate the shader properties:

shaderSet:

shaderGet:

Manipulating Tags

These commands may be used to modify the tags of an object:

addTag:

delTags:

getTags:

setTags:

Manipulating NURBS Curves and Surfaces

These are more specialized commands to change NURBS curve and surface properties:

clampNC - clamp NURBS curve:

elevateNC - elevate NURBS curve:

insknNC - insert knot into NURBS curve:

remknNC - remove knot from NURBS curve:

refineNC - refine NURBS curve:

coarsenNC - coarsen NURBS curve:

revertC - revert curves:

revertuS - revert surfaces:

revertvS - revert surfaces:

swapuvS - swap dimensions of surfaces:

rescaleknNC - rescale knots of NURBS curves:

splitNC - split NURBS curve

toXYNC - move NURBS curve to XY plane

trimNC - trim NURBS curve

estlenNC - estimate length of NURBS curve:

reparamNC - reparameterise a NURBS curve:

clampuNP - clamp NURBS patch in U direction:

clampvNP - clamp NURBS patch in V direction:

rescaleknNP - rescale knots of NURBS patches:

insknuNP - insert knot into NURBS patch:

insknvNP - insert knot into NURBS patch:

splituNP - split NURBS patch:

splitvNP - split NURBS patch:

extrNP - extract NURBS patch:

splitNP - split NURBS patch:

buildNP - build NURBS patch:

Manipulating Points

Use these two commands to read or manipulate single points of arbitrary objects. Note that the exact arguments needed depend on the type of the selected object, e.g. a NURBS curve requires just one index parameter (indexu), whereas a NURBS patch requires two index parameters (indexu and indexv).

getPnt:

setPnt:

Updating the GUI

These commands update various parts of the Ayam user interface:

rV - redraw all views:

uS - update select:

uCL - update current level:

uCR - update current level after create:

plb_update - property listbox update:

Since Ayam 1.13 it is also possible to automatically run GUI updating commands in the console by using <Shift+Return> instead of <Return>. The commands from the hidden preference setting "AUCommands" will be executed after the commands from the command line, if the <Shift> key is held down. <Shift+Return> may also be used without commands on the command line. By default, the "AUCommands" are "uS; rV;", leading to updated object tree, property GUI, and views.

Custom Objects

This command manages custom objects (plugins):

io_lc - load custom:

Applying Commands to a Number of Objects

There are two commands that help to apply arbitrary commands to a number of objects, forAll and forAllT:

forAll:

forAllT:

Scene IO

These commands help to load scenes from and save them to Ayam scene files:

newScene:

replaceScene:

insertScene:

saveScene:

RIB Export

This command allows to export the current scene to a RenderMan Interface Bytestream (RIB):

wrib - RIB export:

Reporting Errors

This command is for error reporting from scripts:

ayError:

Miscellaneous

Miscellaneous commands:

getType:

tmpGet:

hasChild:

undo:

convOb:

forceNot:

addToProc:

6.3 Scripting Interface Examples

Here are some complete example scripts for the Ayam Tcl scripting interface.

You may copy and paste all examples directly from the documentation into the console of Ayam.

Moving Objects

The following example script shows how to move a selected object to a specified position in space.


proc placeOb { x y z } {
  global transfPropData

  # copy Transformations-property data to
  # global array "transfPropData"
  getTrafo

  # set array values according to procedure parameters
  set transfPropData(Translate_X) $x
  set transfPropData(Translate_Y) $y
  set transfPropData(Translate_Z) $z

  # copy Transformations-property data from
  # global array "transfPropData" to selected object
  setTrafo
}
# placeOb

In order to move all selected objects to 1 1 1 you may enter the following into the console:
forAll 0 {placeOb 1 1 1}

But perhaps you would rather like a small GUI for that? No problem, the following snippet adds an entry to the custom menu that opens a small requester for the x-, y-, and z-values and calls the "placeOb" procedure (defined above) with them:
global ay
$ay(cm) add command -label "Place Object" -command {
 runTool {x y z} {"X:" "Y:" "Z:"} "forAll 0 {placeOb %0 %1 %2}"
 plb_update; rV
}

The trailing "plb_update; rV" command ensures that the GUI is updated properly and all views display the new position of the moved objects.

Moving NURBS points

The following example script snippet shows how to move control points of a NURBS curve.


# first, we create a new NURBS curve with 30 control points
set len 30
crtOb NCurve -length $len
# update selection
uS
# select last object (the newly created curve)
sL
# prepare moving
set i 0
set r 3.0
set angle 0
set angled [expr 3.14159265/2.0]
while { $i < $len } {

    set x [expr $r*cos($angle)]
    set y [expr $r*sin($angle)]
    set z [expr $i/3.0]

    # move control point to new position
    setPnt $i $x $y $z 1.0

    set angle [expr $angle + $angled]
    incr i
}
# redraw all views
rV

Now use this as path for a Sweep. For instance, using the next small script.

Easy Sweep

The following example script shows how to easily create a sweep from a selected path curve (avoiding the manual and lengthy creation and parameterisation of a suitable cross section).


proc easySweep { } {
 # first, we create a sweep object
 crtOb Sweep

 # now, we need to move the selected curve (path) to
 # the sweep and create a cross-section curve there too
 # for that, we move the currently selected curve to the clipboard
 cutOb

 # enter the Sweep (the last object in the current level)
 goDown -1

 # now, we create a new curve (a closed B-Spline suitable as cross section)
 crtClosedBS 8

 # select the new object
 selOb 0

 # now, we rotate and scale the curve
 rotOb 0 90 0
 scalOb 0.25 0.25 1.0

 # move trajectory back (we use "pasmovOb" and _not_ "pasOb", because we
 # really want to move (and not copy) the curve object
 pasmovOb

 # go up to where we came from
 goUp

 # finally, update the GUI...
 uS
 sL

 # ...and redraw all views
 rV
}
# easySweep

Run this pocedure by selecting a NURBS curve object, then type into the console:


easySweep

You may add this command to the main menu as well:


global ay
$ay(cm) add command -label "Easy Sweep" -command {
 easySweep
}

After running the above script you should have a new menu entry "Custom/Easy Sweep" that calls the easySweep procedure.

Toolbox Buttons

Here is another example script that shows how you may add buttons to the toolbox. myImage should be an image created e.g. from a GIF file of the size 25 by 25 pixels.


global ay ayprefs

# create an image from a GIF file:
image create photo myImage -format gif -file /home/user/giffile

if { $ayprefs(SingleWindow) } {
  set b .fv.fTools.f.mybutton
} else {
  set b .tbw.f.mybutton
}

# if the button does not already exist:
if { ![winfo exists $b] } {

  # create it:
  button $b -padx 0 -pady 0 -image myImage -command myCommand

  # tell Ayam about the new button:
  # you can use "linsert", to insert the button in a specific
  # place or just append to the end of the list using "lappend"
  lappend ay(toolbuttons) mybutton

  # display the button:
  toolbox_layout

  # from now on, it will be under the
  # automatic toolbox layout management
}

This example shows that a) toolbox buttons have to be created in the frame ".tbw.f" for multi-window GUI configurations or ".fv.fTools.f" for single-window GUI configurations, b) Ayam manages a list of all toolbox buttons in the global array ay in "ay(toolbuttons)", the order in that list is the order in which the buttons appear in the toolbox, c) automatic layout management is carried out by the procedure "toolbox_layout".

Adding buttons with just text is a little bit more involved, as the sizes of the new buttons often do not fit well in the icon button scheme with its constant button size. However, since Ayam 1.14, the procedure "toolbox_add" can be of considerable help (see the file "scriptstopoly.tcl"/ for an example).

Here is an example that adds two buttons to the bottom of the toolbox spanning the whole window (this works best with the standard toolbox layout of 4 by 12 buttons used in the multi-window GUI configuration):


# create a frame:
set f [frame .tbw.f.fcollex]

# calculate the row number below the last row:
set row [expr [lindex [grid size .tbw.f] 1] + 1]

# now display the frame at calculated row, spanning the whole window:
grid $f -row $row -column 0 -columnspan [lindex [grid size .tbw.f] 0]\
     -sticky we
# create two buttons inside the frame:
button $f.b1 -width 5 -text "Coll." -command { collMP; rV; }
button $f.b2 -width 5 -text "Expl." -command { explMP; rV; }
pack $f.b1 $f.b2 -side left -fill x -expand yes

6.4 Helper Scripts

This sections contains the documentation of some helper scripts that are distributed with Ayam.

All helper scripts may be run via the context menu of the console, the Tcl "source" command, or the "Scripts" preference setting of Ayam on each start.

Repair Ayam

Since Ayam 1.8.2 an external Tcl script named "repairAyam.tcl" is provided that may be used to repair the application state of Ayam should it be stuck e.g. in an endless loop of Tcl error messages.

On Unix systems "repairAyam" may be started from any shell simply by typing "./repairAyam.tcl" or "wish repairAyam.tcl" (without the quotes) on the command prompt; if the script detects that it is running on Unix and not in Ayam it will send itself to the Tcl interpreter Ayam is running in using the Tk send command. On Mac OS X Aqua (not X11!) AppleScript events will be used instead of the Tk send command. If this does not work as expected "repairAyam.tcl" may still be run via the Ayam console (as on Win32).

On Win32 you have to start "repairAyam.tcl" from the Ayam console using the command: "source scripts/repairAyam.tcl" or using the consoles context menu: "Console/Load File".

The script "repairAyam.tcl" should be considered a last resort to help you save your modified objects!

The script will close all views, clean up the application state variables, reset the mouse cursor and the console prompt, and try to update important main window widgets. Since Ayam 1.9 it will also clear the console and try to break potential endless loops running e.g. in the console or in script objects.

After running "repairAyam.tcl" you should immediately save the scene (or just the important objects you were editing, possibly using "Special/Save Selected") to a new file, not the scene file you were working with initially, and restart Ayam.

Convert Everything to Polygons

Since Ayam 1.13 there ist a script named "topoly.tcl" that recursively browses through the scene and converts everything to a polygonal representation.

After running the script, there is a new button in the toolbox named "ToPolyMesh". Additionally, there is a corresponding entry in the "Custom" main menu. Pressing the button or using the menu entry immediately starts the conversion process.

Since the changes of the conversion are not undoable, the conversion will not run if the scene contains unsaved changes.

The conversion will use the parameters from the preference settings "SMethod", "SParamU", and "SParamV" or from "TP" tags (if present). TP tags may be created easily using the tesselation tool, see also section The Tesselation Tool.

Restrict the Console

The script "2lcons.tcl" (for two line console), may be used to restrict the screen space occupied by the console.

Normally, the Ayam console is resized with the main window and occupies a varying amount of screen space. After running the script, the console will always resize to exactly two lines. Different values may be chosen easily by adapting the script.

Use Ayam as Command Line Converter

Since Ayam 1.15 there is an external Tcl script named "bgconvert.tcl" that converts its arguments, with the help of Ayam running in the background, from one 3D file format to another. In the most simple form, it may be used from a UNIX command line (or shell script) like this:


bgconvert.tcl infile.x3d outfile.dxf

The above command would load the X3D file "infile.x3d" into Ayam and export the scene as DXF file to "outfile.dxf".

Ayam has to run already and the plugins required for the import and export processes need to be available and properly configured ("Plugins" preference setting). The plugins necessary for the conversion will be loaded automatically.

Import and export options may also be given like this:


bgconvert.tcl "infile.rib -p 1" outfile.dxf

In the example above the "-p 1" option switches on reading of partial RIB files. Available options and their syntax may be inquired from the import and export plugin Tcl scripts (e.g. "plugins/rrib.tcl").

Access Core Functions from the Toolbox

The script "zap.tcl" demonstrates, how arbitrary core functionality that is just available through a main menu entry or the scripting interface might be accessed easily via the toolbox window.

After running the script "zap.tcl", there will be a new toolbox button, labeled "Zap!", that simply runs the zap command (which iconifies the complete application).

Switch File Dialogs to Kdialog

The script "kdialog.tcl" switches all file dialogs of Ayam to use the kdialog application of the KDE project instead of the native Tk file dialog.

Switch File Dialogs to Zenity

The script "zdialog.tcl" switches all file dialogs of Ayam to use the zenity application of the Gnome project instead of the native Tk file dialog.

Use Aqsis from Application Directory

The script "useaqsisapp.tcl" sets up Ayam to use Aqsis from the application directory structure ("/Applications/Aqsis.app") on Mac OS X. This is the default installation location of Aqsis on Mac OS X.

The script adapts the executable and shader search paths. Furthermore, environment variables vital for Aqsis to work will be set up properly.

Note that the script does not change the "RIB-Export/Renderer" preferences, you still have to switch to Aqsis using the main menu "Special/Select Renderer" once.

Use Pixie from Library Directory

The script "usepixie.tcl" sets up Ayam to use Pixie from the "/Library/pixie" directory on Mac OS X. This is the default installation location of Pixie on Mac OS X.

The script adapts the executable, shared library, and shader search paths. Furthermore, environment variables vital for Pixie to work will be set up properly.

Note that the script does not change the "RIB-Export/Renderer" preferences, you still have to switch to Pixie using the main menu "Special/Select Renderer" once.


Next Previous Contents