The scripting interface is mainly a bunch of Tcl procedures and Tcl commands that a big part of Ayam uses internally.
Using Tcl, you could directly modify the code Ayam consists of. This is, however, not recommended for good reasons. 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 that commands may change unnoticed in future versions.
The scripting interface may be used directly from the console
of Ayam. You can, of course, also write procedures 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 to be executed automatically
on startup using the preference setting "Main/Scripts"
.
In contrast to other modeling environments, in Ayam there is a
third 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.
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).
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!" } }
Several global variables exist in the Ayam Tcl context, that may be useful for scripts.
"ay_error"
variable holds the current error state.
See also section
Reporting Errors."i"
is used by all "forAll"
command variants. See also section
Applying Commands to a Number of Objects.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"
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.
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 }
""
), 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.
The following global arrays and callbacks to get or set the data
exist:
property | array | get-property callback | set-property callback |
Transformations | transfPropData | getTrafo | setTrafo |
Attributes | attrPropData | getAttr | setAttrp |
Material | matPropData | getMat | setMat |
Tags | tagsPropData | getTagsp | setTagsp |
Property Arrays and Callbacks
See also section Manipulating Properties for more information on how to edit property values from the scripting interface.
This section provides documentation on the most important scripting interface commands and procedures of Ayam sorted by category.
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):
"help command"
"help help"
displays the help of the help command.
To create new objects the "crtOb"
command can be used.
"crtOb type [args]"
"crtOb"
,
type may be derived from the type name, as displayed in the tree view.
Depending on the type, further arguments may (or have to) be given, some object types expect other objects to be selected:
"NCurve"
: NURBS curves accept a single integer as length of
the new curve, the length defaults to 4. Example:
"crtOb NCurve -length 10; uS; rV"
"NPatch"
: NURBS patches accept two integers as width and
height of the new patch, width and height both default to 4. Example:
"crtOb NPatch -width 2 -height 2; uS; rV"
"Level"
: Levels must be given an additional argument
determining the type of the new level, this argument may be one of:
"0"
(level), "1"
(union), "2"
(intersection),
"3"
(difference), "4"
(primitive)."Material"
: Materials must be given an additional
argument giving the name of the new material. Example:
"crtOb Material default; uS; rV"
"Instance"
: creates an instance of the selected object."crtOb Sphere; uS; rV"
.These commands are probably the most important ones, because many other scripting interface commands operate on selected objects only:
"selOb [index]"
"selOb"
clears the current selection, "selOb 0"
selects the first object in the current level, "selOb 0 1"
selects
the first two objects in the current level.withOb - execute a command on certain selected object(s):
"withOb index [do] command"
"withOb 2 {movOb 0 1 0}"
moves the third
object from multiple selected objects. All objects stay selected."sL"
# create object crtOb NCurve # update tree uCR # select new object sL
hSL - hidden select last object:
"hSL"
Since Ayam 1.9 two new commands are implemented that ease the manipulation of property values:
getProperty - get single property value
"getProperty propname(elemname) varname"
"r"
easily using the command
"getProperty SphereAttr(Radius) r"
setProperty - set single property value
"setProperty propname(elemname) value"
"3.0"
easily using the command
"setProperty SphereAttr(Radius) 3.0"
In contrast to "setProperty"
, here is an equivalent example for the
direct (fast) access of property values:
getProp set SphereAttrData(Radius) 3.0 setProp
These commands operate the object clipboard:
"copOb"
"cutOb"
"pasOb"
"delOb"
"cmovOb"
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_copy mode"
or "copyProp mode"
"copyProp"
.pclip_paste/pasteProp - paste a property
"pclip_paste"
or "pasteProp"
"pasteProp"
.These commands manipulate the current level of Ayam:
"goDown index"
"goUp"
"goTop"
These commands transform objects or selected points of objects:
"movOb dx dy dz"
"rotOb dx dy dz"
"scalOb dx dy dz"
movSel - move selected points:
"movSel dx dy dz"
rotSel - rotate selected points:
"rotSel dx dy dz"
scalSel - scale selected points:
"scalSel dx dy dz"
delegTrafo - delegate transformations:
"delegTrafo"
applyTrafo - apply transformations:
"applyTrafo sel|all"
These commands operate the shader properties:
"shaderSet shadertype [varname]"
"surface"
, "displacement"
,
"light"
, "imager"
, "atmosphere"
, "exterior"
or "interior"
. If varname is not given, the shader in question
is deleted from the object instead."shaderGet shadertype varname"
"surface"
, "displacement"
,
"light"
, "imager"
, "atmosphere"
, "exterior"
or "interior"
. The shader will be written to an array
pointed to by varname.These commands may be used to modify the tags of an object:
"addTag type value"
""
as value parameter. This is e.g.
needed for the "NoExport"
tag."delTags type"
"all"
, all tags are deleted from the
currently selected objects(s)."getTags tvname vvname"
"setTags tags"
These are more specialized commands to change NURBS curve and surface properties:
"clampNC"
"Custom"
and
the knots will have o equal values at start and end (where o is the
order of the curve).
See also section
The Clamp Tool.elevateNC - elevate NURBS curve:
"elevateNC n"
"Custom"
.
See also section
The Elevate Tool.insknNC - insert knot into NURBS curve:
"insknNC u r"
U[p] <= u <= U[n]
, where
p is the degree (order-1) of the curve and n is the length of the curve.
The knot type of the curves will always be changed to custom but
the shape of the curves will not change!
See also section
The Insert Knot Tool.remknNC - remove knot from NURBS curve:
"remknNC u r"
refineNC - refine NURBS curve:
"refineNC [{u1 u2 un}]"
"Custom"
.
See also section
The Refine Tool.coarsenNC - coarsen NURBS curve:
"coarsenNC"
"revert"
rescaleKnNC - rescale knots of NURBS curves:
"rescaleKnNC [-r rmin rmax|-d mindist]"
[0.0, 1.0]
(if no argument is present) or to the range
[rmin, rmax]
if the "-r"
argument is given or to the minimum
distance mindist if the "-d"
argument is used. Scaling to a minimum
distance ensures that all knots (except for multiple knots) have a distance
bigger than mindist afterwards. The knot type of the curve has to be
"Custom"
!
This operation does not change the shape of the curve."splitNC u"
"trimNC umin umax"
clampNPU - clamp NURBS patch in u-direction:
"clampNPU"
"Custom"
and the knots will have o
equal values at start and end (where o is the order of the patch in
u-direction). See also section
The Patch Clamp Tool.clampNPV - clamp NURBS patch in v-direction:
"clampNPV"
"Custom"
and the knots will have o
equal values at start and end (where o is the order of the patch in
v-direction). See also section
The Patch Clamp Tool.rescaleKnNP - rescale knots of NURBS patches:
"rescaleKnNP [-r[u|v] rmin rmax|-d[u|v] mindist]"
[0.0, 1.0]
(if no argument is present) or to the range
[rmin, rmax]
if the "-r"
argument is given or to the minimum
distance mindist if the "-d"
argument is used. The "-ru"
, "-rv"
,
"-du"
, and "-dv"
variants scale only the designated dimension.
Scaling to a minimum distance ensures that all knots (except for multiple
knots) have a distance bigger than mindist afterwards. Trim curves, if
present, will also be scaled to match the new range.
The knot types of the patch have to be "Custom"
!
This operation does not change the shape of the patch.
See also sections
The Patch Rescale Knots to Range Tool
and
The Patch Rescale Knots to Mindist Tool."rescaleKnNP -ru 0.2 0.3"
scales the u knot vector
of the selected NURBS patch objects to the new range (0.2, 0.3).insknNPU - insert knot into NURBS patch:
"insknNPU u r"
U[p] <= u <= U[n]
, where
p is the degree (order-1) of the patch in u-direction and n is the
width of the patch.
The u knot type of the patches will always be changed to "Custom"
but
the shape of the patches will not change!
See also section
The Patch Insert Knot Tool.insknNPV - insert knot into NURBS patch:
"insknNPV v r"
V[p] <= v <= V[n]
, where
p is the degree (order-1) of the patch in v-direction and n is the
height of the patch.
The v knot type of the patches will always be changed to "Custom"
but
the shape of the patches will not change!
See also section
The Patch Insert Knot Tool."splitNPU u"
"splitNPV v"
"extrNP umin umax vmin vmax"
"splitNP (u|v)"
"buildNPatch"
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 [-trafo|-p] indexu [indexv] varx vary varz [varw]"
"-trafo"
is given, the coordinates
will additionally be transformed by the values given in the objects
Transformation property.
If the argument "-p"
is given, the "indexu"
and "indexv"
values are interpreted as parametric values of a NURBS curve or surface
and the corresponding point on the curve or surface is delivered in
varx, vary, and varz."getPnt 1 x y z w"
gets the coordinate
values of the second point of the selected NURBS curve and writes
the values to the variables "x y z w"
. "getPnt -p 0.5 x y z w"
gets the curve point at parametric value "0.5"
and writes
the values to the variables "x y z w"
."setPnt indexu [indexv] x y z [w]"
"setPnt 1 0.0 0.2 0.3 1.0"
sets the coordinate
values of the second point of the selected NURBS curve object to
"0.0 0.2 0.3 1.0"
.These commands update various parts of the Ayam user interface:
"rV"
"uS [update_prop maintain_selection]"
If update_prop is 0 no update of the property GUIs will take place. If maintain_selection is 1 the old selection will be established again. If both arguments are omitted update_prop defaults to 1 and maintain_selection to 0.
"ay(ul)"
(UpdateLevel) may be set
to the current level before calling "uS"
. This will not remove
and update the complete scene but just the part below "ay(ul)"
.
Example:
global ay; set ay(ul) $ay(CurrentLevel); uS;
"uCR"
may be used instead of "uS"
."uCL cl"
may be used instead of "uS"
."uCL mode [args]"
"uS"
above.
The parameter "mode"
may be "cl" or "cs", where "cl" is the normal
operation mode, and "cs" just clears the selection.uCR - update current level after create:
"uCR"
"uS"
above.plb_update - property listbox update:
"plb_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.
This command manages custom objects (plugins):
"io_lc filename"
There are two commands that help to apply arbitrary commands to a number of objects, forAll and forAllT:
"forAll recursive command"
"forAllT"
in this case."forAll 0 { uplevel #0 { commands } }"
"forAll 0 { global arrayname; commands }"
"forAll"
correctly maintains the current selection."forAllT type recursive command"
Note that the type strings will be converted to lowercase before comparison, so that it is legal to use forAllT e.g. this way:
"forAllT ncurve 0 {puts $i}"
"forAllT ncurve 0 {uplevel #0 {commands} }"
"forAllT ncurve 0 { global arrayname; commands }"
"forAllT"
correctly maintains the current selection.These commands help to load scenes from and save them to Ayam scene files:
"newScene"
"replaceScene filename"
"insertScene filename"
"saveScene filename"
This command allows to export the current scene to a RenderMan Interface Bytestream (RIB):
"wrib -file filename [-image imagename] [-smonly|-selonly]"
"filename"
. If the argument "-image"
is given, the RIB file
will create an image file named "imagename"
upon rendering. The export
will use the camera transformation from the currently selected Camera
object.
If the argument "-smonly"
is provided, a RIB to render shadow maps
will be created and the argument of "-image"
will be ignored.
If the argument "-selonly"
is given, only the selected (geometric)
objects will be exported, which will result in a RIB file not
suitable for rendering (no setup, camera transformation, or lights
are in it) but for inclusion into other scenes via RiArchive.
The "wrib"
command always needs a selected camera object; if
there is none or if the camera transformations of the camera associated
with a view window shall be used, the corresponding Togl callback for
the view might be used like this instead:
.view1.f3D.togl wrib -file filename.rib
"wrib"
command.This command is for error reporting from scripts:
"ayError code place detail"
Miscellaneous commands:
"getType varname"
"tmpGet tmpdir varname"
"hasChild"
"undo [redo|save opname|clear]"
"redo"
, this command performs the redo
operation."save"
, the currently selected objects
are saved to the undo buffer for future undo operations. The name
of the now following modelling operation has to be provided in a second
argument ("opname"
).
This name will be displayed in the default console prompt, to inform the
user about which operation would be undone/redone, if undo/redo would be
used."clear"
, all currently saved states
will be cleared from the undo buffer."convOb [-inplace]"
"-inplace"
is
used, the new object(s) will replace the old object(s)."forceNot [mod|all]"
"mod"
parameter is used, only modified objects
will be notified.
If the "all"
parameter is used, all objects
will be notified regardless of the selection."addToProc procedure addition"
"return;"
statement.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.
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
forAll 0 {placeOb 1 1 1}
"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 }
"plb_update; rV"
command ensures that the GUI is updated
properly and all views display the new position of the moved objects.
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
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 uS # how does the current level look like? getLevel a b # enter the Sweep (the last object in the current level) goDown [expr [llength $a]-1] uS # now, we create a new curve (a closed B-Spline suitable as cross section) crtClosedBS 8 uS # how does the current level look like? getLevel a b # select last object (the newly created curve) selOb [expr [llength $a]-1] # now, we rotate and scale the curve rotOb 0 90 0 scalOb 0.25 0.25 1.0 # move trajectory back (we use "cmovOb" and _not_ "pasOb", because we # really want to move (and not copy) the curve object cmovOb # go up to where we came from goUp # update GUI uS sL # 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 }
"Custom/Easy Sweep"
that calls the easySweep
procedure.
Here is another example 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 # create an image from a GIF file: image create photo myImage -format gif -file /home/user/giffile set b .tbw.f.mybutton # if the button not already exists: 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 lappend ay(toolbuttons) mybutton # display the button: # from now on, it will be under the # automatic toolbox layout management toolbox_layout }
This example shows that a) buttons have to be created in the
frame ".tbw.f"
b) Ayam manages a list of all buttons in the global array ay
in "ay(toolbuttons)"
, the order in that list is the order
in which 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.
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):
# 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
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
"source"
command, or the "Scripts"
preference
setting of Ayam on each start.
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 scratch file and restart Ayam.
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).
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.
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.
After running the script, there will be a new toolbox button, that runs the zap command.