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 of Ayam 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 recorded in the undo buffer, you have to arrange for this manually too (see the documentation of the undo command: Undo).

From scripts it may be necessary to check whether 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 ay_error 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 `"ay_error"` variable holds the current error state. See also section Reporting Errors.
- The variable `"i"` is used by all `"forAll"` command variants. See also section Applying Commands to a Number of Objects.

### 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 elements to this array. See also section Ayamrc File. Use `"parray ayprefs"` in the console to see what is there. More documentation to come.

Note that changes to this array on the Tcl side do not immediately take effect as the data needs to be transferred to the C context using the `"setPrefs"` command. See also section Managing Preferences.

### The Global Property Management and Data Arrays

For every property, a corresponding global arrays exists, where the property is managed. For the Transformations property, this array looks like this:

    Transformations {
    arr   transfPropData
    sproc setTrafo
    gproc getTrafo
    w     fTrafoAttr
    }

The first entry, `"arr"`, designates the name of the global property data array (thus, transformation data is stored in an array called `"transfPropData"`). The entries `"sproc"` and `"gproc"` designate the set-property and get-property callbacks (procedures or commands) respectively. If sproc or gproc are empty strings (`""`), standard callbacks named `"setProp"` or `"getProp"` should be used to get or set the property values. But for the transformations property, the `"setTrafo"` and `"getTrafo"` commands should be used. The last entry, `"w"`, is the name of the main property GUI window. To get the full widget path of this window, the current value of ay(pca) needs to be prepended.

Note that the global property data 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 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

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.

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

## 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:

- Synopsis: `"command param1 param2 [optionalparam1]"` (syntax of the command and its parameters),
- Background: does the command run in the background, Undo: can the result of the command be undone, Safe: is the command available in the safe interpreter (for Script objects and notify script tags),
- Description: detailed description of the command and its parameters,
- Notes: additional information completing the detailed description,
- Example: `"command 1 2"` (example application of the command with explanation of expected results).

### 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):

- Synopsis: `"help command"`
- Background: N/A, Undo: No, Safe: No
- Description: Fire up a web browser and display the help for the designated Ayam scripting interface command.
- Example: `"help help"` displays the help of the help command.

### Creating Objects

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

- Synopsis: `"crtOb type [args]"`
- Background: Yes, Undo: No, Safe: Yes
- Description: New objects may be created with the command `"crtOb"`, `"type"` may be derived from the object type names, as displayed in the tree view. The new object will be created and linked to the scene as last object in the current level, no part of the GUI (object selection widget, property GUI, views) will be updated. Furthermore, the new object will not be selected.

  Depending on the type, further arguments may (or have to) be given; some object types expect other objects to be selected upon creation.

  All arguments consist of a option name part and a value part (i.e. it is `"-center 1"` and not `"-center"` and also not `"-center=1"`). The option names can be abbreviated. Useful default and fallback values exist (see below). The arguments can be mixed freely (their order is not important) and repeated. If arguments are repeated, only the last set value is used, even if this leads to errors and application of fallback values later on.

  Here is a comprehensive list of available arguments sorted by object type:

  - `"NCurve"`: NURBS curves accept the following arguments:
    - `"-length"`: length of the new curve, the length defaults to 4.
    - `"-order"`: order of the new curve, the order defaults to 4. If a value greater than the length is specified, the order will be made identical to the length value.
    - `"-kt"`: the knot type of the new curve, must be one of 0 – Bezier, 1 – BSpline, 2 – NURB, 3 – Custom, 4 – Chordal, 5 – Centripetal. A knot vector of specified type will automatically be created. The knot type defaults to 2 – NURB. If a custom knot vector is specified using the `"-kv"` option below, the knot type will always be set to 3 – Custom.
    - `"-kv"`: the knot vector of the new curve. The value of this option is a list of floating point numbers of length curve length plus curve order, e.g. for a curve with 2 control points and order 2, specify 4 knots: `"-kv {0.0 0.0 1.0 1.0}"`. The knot vector defaults to an automatically created knot vector of the type specified by the `"-kt"` option above.
    - `"-kn"`: the knot vector of the new curve. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-kv"` option above.
    - `"-cv"`: the control vector of the new curve. The value of this option is a list of floating point numbers that describe the 4D euclidean rational (weight not multiplied in) coordinates of the control points. This list may also only specify one point, which is then taken as starting point and DX/DY/DZ (see below) are used to create the missing control points automatically. To specify a complete control vector, this list should have curve length by 4 elements, e.g. for a curve of length 3, specify 12 values: `"-cv {0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 2.0 0.0 0.0 1.0}"`.
    - `"-cn"`: the control vector of the new curve. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-dx"`: the value of this option specifies the distance of automatically created control points in the x dimension, default is 0.25.
    - `"-dy"`: the value of this option specifies the distance of automatically created control points in the y dimension, default is 0.0.
    - `"-dz"`: the value of this option specifies the distance of automatically created control points in the z dimension, default is 0.0
    - `"-center"`: If the value of the `"-center"` option is 1, the new curve will be centered. The default value is 0, no centering. This option is only in effect if no `"-cv"` option is specified.
    - `"-createmp"`: The `"-createmp"` option toggles creation of multiple points. The default value is 0.
    Examples:
    1. `"crtOb NCurve"`
       creates a curve with length 4, order 4, standard (clamped) NURBS knot vector, control points at 0 0 0, 0.25 0 0, 0.5 0 0, 0.75 0 0 (all weights 1).
    2. `"crtOb NCurve -center 1"`
       creates a centered curve with length 4, order 4, standard (clamped) NURBS knot vector, control points at -0.375 0 0, -0.125 0 0, 0.125 0 0, 0.375 0 0 (all weights 1).
    3. `"crtOb NCurve -length 5 -center 1 -dx 0.5"`
       creates a centered curve with length 5, order 4, standard (clamped) NURBS knot vector, control points at -1 0 0, -0.5 0 0, 0 0 0, 0.5 0 0, 1 0 0 (all weights 1).

    In versions of Ayam prior to 1.17, NURBS curves only accepted the `"-length"` argument.

  - `"ICurve"`: Interpolating curves accept the following arguments:
    - `"-type"`: the type of the new curve, must be one of 0 – Open, 1 – Closed; default is 0.
    - `"-length"`: length (number of data points to interpolate) of the new curve; the length defaults to 4.
    - `"-order"`: order of the new curve, the order defaults to 4. If a value greater than the length is specified, the order will be made identical to the length value.
    - `"-pt"`: the parameter type of the new curve, must be one of 0 – Chordal, 1 – Centripetal, 2 – Uniform; default is 0.
    - `"-cv"`: the control vector of the new curve. The value of this option is a list of floating point numbers that describe the 3D (non rational) coordinates of the control points. This list may also only specify one point, which is then taken as starting point and DX/DY/DZ (see below) are used to create the missing control points automatically. To specify a complete control vector, this list should have curve length by 3 elements, e.g. for a curve of length 3, specify 9 values: `"-cv {0.0 0.0 0.0 1.0 0.0 0.0 2.0 0.0 0.0}"`.
    - `"-cn"`: the control vector of the new curve. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-dx"`: the value of this option specifies the distance of automatically created control points in the x dimension, default is 0.25.
    - `"-dy"`: the value of this option specifies the distance of automatically created control points in the y dimension, default is 0.0.
    - `"-dz"`: the value of this option specifies the distance of automatically created control points in the z dimension, default is 0.0
    - `"-center"`: If the value of the `"-center"` option is 1, the new curve will be centered. The default value is 0, no centering. This option is only in effect if no `"-cv"` option is specified.
    - `"-derivs"`: the value of this option controls whether user defined end derivatives should be used: 0 – no, 1 – yes, default is 0.
    - `"-sdlen"`: the value of this option specifies the relative length (in relation to the distance of the first and second control point) of the start derivative, default is 0.125.
    - `"-sderiv"`: is the start derivative, specified as a list of three float values. The derivative is specified relative to the first control point. The start derivative defaults to an automatically created derivative of a direction taken from the first two control points and length specified by the `"-sdlen"` option.
    - `"-edlen"`: the value of this option specifies the relative length (in relation to the distance of the second to last and last control point) of the end derivative, default is 0.125.
    - `"-ederiv"`: is the end derivative, specified as a list of three float values. The derivative is specified relative to the last control point. The end derivative defaults to an automatically created derivative of a direction taken from the last two control points and length specified by the `"-edlen"` option.
    Examples:
    1. `"crtOb ICurve"`
       creates a curve with length 4, order 4, data points at 0 0 0, 0.25 0 0, 0.5 0 0, 0.75 0 0.
    2. `"crtOb ICurve -l 5 -sderiv {0.0 -0.5 0.0} -ederiv {0.0 -0.5 0.0} -derivs 1 -center 1"`
       creates a curve with length 5, order 4, data points at -0.5 0 0, -0.25 0 0, 0 0 0, 0.25 0 0, 0.5 0 0, end derivatives pointing straight upwards with length 0.5 in their respective end.

    In versions of Ayam prior to 1.17, interpolating curves only accepted the `"-length"` argument.

  - `"ACurve"`: Approximating curves accept the following arguments:
    - `"-type"`: the type of the new curve, must be one of 0 – Open, 1 – Closed; default is 0.
    - `"-length"`: length (number of data points to approximate) of the new curve, the length defaults to 4.
    - `"-alength"`: number of control points to use for the approximating curve, the alength defaults to 3.
    - `"-order"`: order of the new curve, the order defaults to 3. If a value greater than the length is specified, the order will be made identical to the length value.
    - `"-symmetric"`: toggles creation of symmetric curves, must be one of 0 – Asymmetric, 1 – Symmetric; default is 0.
    - `"-cv"`: the control vector of the new curve. The value of this option is a list of floating point numbers that describe the 3D (non rational) coordinates of the control points. This list may also only specify one point, which is then taken as starting point and DX/DY/DZ (see below) are used to create the missing control points automatically. To specify a complete control vector, this list should have curve length by 3 elements, e.g. for a curve of length 3, specify 9 values: `"-cv {0.0 0.0 0.0 1.0 0.0 0.0 2.0 0.0 0.0}"`.
    - `"-cn"`: the control vector of the new curve. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-dx"`: the value of this option specifies the distance of automatically created control points in the x dimension, default is 0.25.
    - `"-dy"`: the value of this option specifies the distance of automatically created control points in the y dimension, default is 0.0.
    - `"-dz"`: the value of this option specifies the distance of automatically created control points in the z dimension, default is 0.0
    - `"-center"`: If the value of the `"-center"` option is 1, the new curve will be centered. The default value is 0, no centering. This option is only in effect if no `"-cv"` option is specified.
    Examples:
    1. `"crtOb ACurve -length 6"`
       creates an approximating curve from 6 data points: 0 0 0, 0.25 0 0, 0.5 0 0, 0.75 0 0, 1 0 0, 1.25 0 0.
    2. `"crtOb ACurve -l 5 -center 1"`
       creates a centered approximating curve from 5 data points: -0.5 0 0, -0.25 0 0, 0 0 0, 0.25 0 0, 0.5 0 0.

    In versions of Ayam prior to 1.17, approximating curves only accepted the `"-length"` argument.

  - `"NPatch"`: NURBS patches accept the following arguments:
    - `"-width"`: width of the new patch, the width defaults to 4.
    - `"-height"`: height of the new patch, the height defaults to 4.
    - `"-uorder"`: order of the new patch in U parametric dimension, the order defaults to 4. If a value greater than the width is specified, the order will be made identical to the width value.
    - `"-ukt"`: the U knot type of the new patch, must be one of 0 – Bezier, 1 – BSpline, 2 – NURB, 3 – Custom, 4 – Chordal, 5 – Centripetal. A knot vector of specified type will automatically be created. The knot type defaults to 2 – NURB. If a custom knot vector is specified using the `"-ukv"` option below, the knot type will always be set to 3 – Custom.
    - `"-ukv"`: the U knot vector of the new patch. The value of this option is a list of floating point numbers of length width plus patch U order, e.g. for a patch with width 2 and U order 2, specify 4 knots: `"-ukv {0.0 0.0 1.0 1.0}"`. The knot vector defaults to an automatically created knot vector of the type specified by the `"-ukt"` option above.
    - `"-un"`: the U knot vector of the new patch. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-ukv"` option above.
    - `"-vorder"`: order of the new patch in V parametric dimension, the order defaults to 4. If a value greater than the height is specified, the order will be made identical to the height value.
    - `"-vkt"`: the V knot type of the new patch, must be one of 0 – Bezier, 1 – BSpline, 2 – NURB, 3 – Custom, 4 – Chordal, 5 – Centripetal. A knot vector of specified type will automatically be created. The knot type defaults to 2 – NURB. If a custom knot vector is specified using the `"-vkv"` option below, the knot type will always be set to 3 – Custom.
    - `"-vkv"`: the V knot vector of the new patch. The value of this option is a list of floating point numbers of length height plus patch V order, e.g. for a patch with height 2 and V order 2, specify 4 knots: `"-vkv {0.0 0.0 1.0 1.0}"`. The knot vector defaults to an automatically created knot vector of the type specified by the `"-vkt"` option above.
    - `"-vn"`: the V knot vector of the new patch. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-vkv"` option above.
    - `"-cv"`: the control vector of the new patch. The value of this option is a list of floating point numbers that describe the 4D euclidean rational (weight not multiplied in) coordinates of the control points. This list may also only specify one point, which is then taken as starting point and UDX/UDY/UDZ and VDX/VDY/VDZ (see below) are used to create the missing control points automatically. To specify a complete control vector, this list should have width by height by 4 elements, e.g. for a patch of width 2 and height 2, specify 16 values: `"-cv {0.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 2.0 0.0 0.0 1.0 2.0 1.0 0.0 1.0}"`.
    - `"-cn"`: the control vector of the new patch. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-udx"`: the value of this option specifies the distance of automatically created control points in the x dimension between points in a row (U parametric dimension, along width), default is 0.25.
    - `"-udy"`: the value of this option specifies the distance of automatically created control points in the y dimension between points in a row (U parametric dimension, along width), default is 0.0.
    - `"-udz"`: the value of this option specifies the distance of automatically created control points in the z dimension between points in a row (U parametric dimension, along width), default is 0.0
    - `"-vdx"`: the value of this option specifies the distance of automatically created control points in the x dimension between points in a column (V parametric dimension, along height), default is 0.0.
    - `"-vdy"`: the value of this option specifies the distance of automatically created control points in the y dimension between points in a column (V parametric dimension, along height), default is 0.25.
    - `"-vdz"`: the value of this option specifies the distance of automatically created control points in the z dimension between points in a column (V parametric dimension, along height), default is 0.0
    - `"-center"`: If the value of the `"-center"` option is 1, the new patch will be centered. The default value is 0, no centering. This option is only in effect if no `"-cv"` option is specified.
    - `"-createmp"`: The `"-createmp"` option toggles creation of multiple points. The default value is 0.
    Examples:
    1. `"crtOb NPatch"`
       creates a flat patch with width 4, height 4, uorder 4, vorder 4, standard (clamped) NURBS knot vectors, control points arranged in a equidistant grid in the XY plane from 0 0 0 to 0.75 0.75 0 (all weights 1).
    2. `"crtOb NPatch -vdy 0 -vdz 0.25"`
       creates the same patch as above in the XZ plane (ground plane).
    3. `"crtOb NPatch -udy 0.25"`
       creates a sheared version of the standard NURBS patch in the XY plane.
    4. `"crtOb NPatch -udy 0.25 -vdz 0.25"`
       creates a 3D sheared version of the standard NURBS patch.
    5. `"crtOb NPatch -width 2 -height 2 -center 1 -udx 2 -vdy 2"`
       creates a centered patch with width 2, height 2, uorder 2, vorder 2, standard (clamped) NURBS knot vectors, control points at -1 0 0, 1 0 0, -1 1 0, 1 1 0 (all weights 1).
    6. `"crtOb NPatch -width 3 -height 2 -uorder 2 -cv {-1 0 1 1 1 0 1 1 -1 0 0 1 1 0 0 1 -1 1 0 1 1 1 0 1}"`
       creates a angular patch in the XZ and XY plane (remove `-uorder 2` to get a smooth shape).

    In versions of Ayam prior to 1.17, NURBS patches only accepted the `"-width"` and `"-height"` argument.

  - `"IPatch"`: Interpolating patches accept the following arguments:
    - `"-width"`: width of the new patch, the width defaults to 4.
    - `"-height"`: height of the new patch, the height defaults to 4.
    - `"-uorder"`: order of the new patch in U parametric dimension, the order defaults to 4. If a value greater than the width is specified, the order will be made identical to the width value. A value of 0 switches off interpolation along U.
    - `"-ukt"`: the U parameterisation type, must be one of 0 – Chordal (default), 1 – Centripetal, 2 – Uniform.
    - `"-vorder"`: order of the new patch in V parametric dimension, the order defaults to 4. If a value greater than the height is specified, the order will be made identical to the height value. A value of 0 switches off interpolation along V.
    - `"-vkt"`: the V parameterisation type, must be one of 0 – Chordal (default), 1 – Centripetal, 2 – Uniform.
    - `"-deriv_u"`: the end derivative mode for U, must be one of 0 – None (default), 1 – Automatic, or 2 – Manual. In manual mode full derivative vectors must be provided via `"-ederiv_u"` and `"-sderiv_u"`.
    - `"-edlen_u"`: the length of automatically calculated end derivatives at end of patch in U (default 0.125).
    - `"-sdlen_u"`: the length of automatically calculated end derivatives at start of patch in U (default 0.125).
    - `"-ederiv_u"`: end derivatives for U at end of patch. The value of this option is a list of 3 by height floating point numbers. There is no default value.
    - `"-sderiv_u"`: end derivatives for U at start of patch. The value of this option is a list of 3 by height floating point numbers. There is no default value.
    - `"-deriv_v"`: the end derivative mode for V, must be one of 0 – None (default), 1 – Automatic, or 2 – Manual. In manual mode full derivative vectors must be provided via `"-ederiv_v"` and `"-sderiv_v"`.
    - `"-edlen_u"`: the length of automatically calculated end derivatives at end of patch in U (default 0.125).
    - `"-sdlen_u"`: the length of automatically calculated end derivatives at start of patch in U (default 0.125).
    - `"-ederiv_u"`: end derivatives for U at end of patch. The value of this option is a list of 3 by height floating point numbers. There is no default value.
    - `"-sderiv_u"`: end derivatives for U at start of patch. The value of this option is a list of 3 by height floating point numbers. There is no default value.
    - `"-cv"`: the control vector of the new patch. The value of this option is a list of floating point numbers that describe the 3D non rational coordinates of the data points to be interpolated. This list may also only specify one point, which is then taken as starting point and UDX/UDY/UDZ and VDX/VDY/VDZ (see below) are used to create the missing control points automatically. To specify a complete control vector, this list should have width by height by 3 elements, e.g. for a patch of width 2 and height 2, specify 12 values: `"-cv {0.0 0.0 0.0 1.0 0.0 0.0 2.0 0.0 0.0 2.0 1.0 0.0}"`.
    - `"-cn"`: the control vector of the new patch. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-udx"`: the value of this option specifies the distance of automatically created control points in the x dimension between points in a row (U parametric dimension, along width), default is 0.25.
    - `"-udy"`: the value of this option specifies the distance of automatically created control points in the y dimension between points in a row (U parametric dimension, along width), default is 0.0.
    - `"-udz"`: the value of this option specifies the distance of automatically created control points in the z dimension between points in a row (U parametric dimension, along width), default is 0.0
    - `"-vdx"`: the value of this option specifies the distance of automatically created control points in the x dimension between points in a column (V parametric dimension, along height), default is 0.0.
    - `"-vdy"`: the value of this option specifies the distance of automatically created control points in the y dimension between points in a column (V parametric dimension, along height), default is 0.25.
    - `"-vdz"`: the value of this option specifies the distance of automatically created control points in the z dimension between points in a column (V parametric dimension, along height), default is 0.0
    - `"-center"`: If the value of the `"-center"` option is 1, the new patch will be centered. The default value is 0, no centering. This option is only in effect if no `"-cv"` option is specified.
    Examples:
    1. `"crtOb IPatch"`
       creates a flat patch with width 4, height 4, uorder 4, vorder 4, chordal parameterisation, data points arranged in a equidistant grid in the XY plane from 0 0 0 to 0.75 0.75 0.
    2. `"crtOb IPatch -vdy 0 -vdz 0.25"`
       creates the same patch as above in the XZ plane (ground plane).
    3. `"crtOb IPatch -udy 0.25"`
       creates a sheared version of the standard IPatch in the XY plane.
    4. `"crtOb IPatch -udy 0.25 -vdz 0.25"`
       creates a 3D sheared version of the standard IPatch.
    5. `"crtOb IPatch -width 3 -height 3 -center 1 -udx 2 -vdy 2"`
       creates a centered patch with width 3, height 3, uorder 3, and vorder 3.
  - `"PolyMesh"`: Polymeshes accept the following arguments:
    - `"-polys"`: the value of this option specifies the number of polygons/faces in the mesh. The number of polygons defaults to 0.
    - `"-loops"`: the value of this option specifies the number of loops per polygon. It is therefore a list of positive integer values of a length equal to the value of the `"-polys"` option. The default value of this option is a list of proper length with all elements set to 1 (only normal polygons, without holes, are specified).
    - `"-nverts"`: the value of this option specifies the number of vertices per loop. It is therefore a list of positive integer values of a length equal to the sum of all elements of the `"-loops"` option. The default value of this option is a list of proper length with all elements set to 3 (only triangles are in the mesh).
    - `"-iverts"`: the value of this option specifies all the (zero based) indices of the vertices of all loops. It is therefore a list of integer values of a length equal to the sum of all elements of the `"-nverts"` option. The default value of this option is a list of proper length with the elements set to a sequence of integers so that the control points are used in the same order as specified via the `"-cv"` option (0, 1, 2, 3, ...).
    - `"-cv"`: the control points of the new mesh. The value of this option is a list of floating point numbers that describe the 3D (non rational) coordinates of the control points. The indices specified via the `"-iverts"` option point to this list. If the `"-vnormals"` option is 1, also vertex normals are specified in this list (directly following the coordinate values of each control point) and stride is 6, otherwise stride is 3. This list must have a length of stride by the highest value in the list provided via the `"-iverts"` option. The default value of this option is an empty list, this implies that this option must be specified to create a non-empty PolyMesh object.
    - `"-cn"`: the control points of the new mesh. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-vnormals"`: determines whether vertex normals are present. The default value is 0 – no vertex normals are present.
    Examples:
    1. `"crtOb PolyMesh -p 1 -cv {0 0 0 1 0 0 0 1 0}"`
       creates a polymesh with a single triangular face.
    2. `"crtOb PolyMesh -p 2 -cv {0 0 0 1 0 0 1 1 0 0 1 0} -iv {0 1 2 0 2 3}"`
       creates a polymesh with two connected (vertex sharing) triangular faces.
    3. `"crtOb PolyMesh -p 3 -cv {0 0 0 1 0 0 1 1 0 0 1 0 1.5 0 0 1.5 1 0} -iv {0 1 2 0 2 3 1 4 5 2} -nv {3 3 4}"`
       creates a polymesh with two triangles and one quad all connected (vertex sharing).
    4. `"crtOb PolyMesh -p 1 -loops {2} -cv {0 0 0 1 0 0 0 1 0 .25 .25 0 .5 .25 0 .25 .5 0}"`
       creates a polymesh with one triangular face that has a triangular hole.
    Notes:
    Besides checking the lengths of arrays, maximum indices, and minimum number of vertices per loop, there is no error checking. Undetected errors include: degenerated or non-planar polygons, hole loops geometrically outside or touching the outline loop, disagreeing loop winding orders between faces, non-manifold meshes, unused control points. Those errors may be problematic for further processing steps – some may go unnoticed in Ayam and will only be detected later in other applications.
  - `"SDMesh"`: Subdivision meshes accept the following arguments:
    - `"-scheme"`: the value of this option specifies the subdivision scheme, it may be set to 0 – Catmull-Clark or 1 – Loop only. Default is 0.
    - `"-faces"`: the value of this option specifies the number of faces in the mesh. The number of faces defaults to 0.
    - `"-nverts"`: the value of this option specifies the number of vertices per face. It is therefore a list of positive integer values of a length equal to the number of faces. The default value of this option is a list of proper length with all elements set to 3 (only triangles are in the mesh).
    - `"-verts"`: the value of this option specifies all the (zero based) indices of the vertices of all faces. It is therefore a list of integer values of a length equal to the sum of all elements of the `"-nverts"` option. The default value of this option is a list of proper length with the elements set to a sequence of integers so that the control points are used in the same order as specified via the `"-cv"` option (0, 1, 2, 3, ...).
    - `"-cv"`: The value of this option is a list of floating point numbers that describe the 3D (non rational) coordinates of the control points. The indices specified via the `"-verts"` option point to this list. This list must have a length of 3 multiplied by the highest value in the list provided via the `"-verts"` option. The default value of this option is an empty list, this implies that this option must be specified to create a non-empty SDMesh object.
    - `"-cn"`: the control points of the new mesh. The value of this option is a variable name (with optional array and namespace specifier). The value of this variable must be compatible to the `"-cv"` option above.
    - `"-tags"`: the value of this option specifies a number of tags. It is therefore a list of positive integer values of arbitrary length. The only allowed values are 0 – hole, 1 – corner, 2 – crease, and 3 – interpolateboundary. The default value of this option is an empty list: no tags.
    - `"-args"`: the value of this option specifies the number of integer and floating point arguments per tag. It is therefore a list of positive integer values of length: double number of tags. The even entries specify the number of integer and the odd entries the number of floating point arguments per tag. The content of this list is partially dictated by the `"-tags"` option, e.g. a crease entry has atleast two integer arguments and one floating point argument. The default value of this option is list of proper length, with all elements set to zero (no tags have any arguments).
    - `"-intargs"`: the value of this option specifies the integer arguments of all tags. It is therefore a list of integer values of length sum of all even elements given by the `"-args"` option.
    - `"-doubleargs"`: the value of this option specifies the floating point arguments of all tags. It is therefore a list of double values of length sum of all odd elements given by the `"-args"` option.
    Examples:
    1. `"crtOb SDMesh -f 4 -v {0 1 3 1 2 3 0 3 2 0 2 1} -cv {0 0 0 1 0 0 0 0 -1 0.5 1 -0.5}"`
       creates a tetrahedral (four triangular faces) mesh.
    2. `"crtOb SDMesh -f 4 -v {0 1 3 1 2 3 0 3 2 0 2 1} -cv {0 0 0 1 0 0 0 0 -1 0.5 1 -0.5} -tags {1} -args {1 1} -intargs {0} -doubleargs {3.0}"`
       creates a tetrahedral mesh with a semi-sharp corner.
    3. `"crtOb SDMesh -f 4 -v {0 1 3 1 2 3 0 3 2 0 2 1} -cv {0 0 0 1 0 0 0 0 -1 0.5 1 -0.5} -tags {2} -args {2 1} -intargs {0 1} -doubleargs {10.0}"`
       creates a tetrahedral mesh with a crease.
    Notes:
    Besides checking the lengths of arrays, maximum indices, and minimum number of vertices per face, there is no error checking. Undetected errors include: degenerated or non-planar faces, faces with unsuitable vertex counts (for the selected subdivision scheme), non-manifold meshes, unused control points, wrong tag arguments. Those errors may be problematic for further processing steps – some may go unnoticed in Ayam and will only be detected later in other applications.
  - `"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), or `"4"` (primitive). Examples:
    1. `"crtOb Level 0"`
       creates a simple level object.
    2. `"crtOb Level 3"`
       creates a CSG difference level object.
  - `"Material"`: Materials must be given an additional argument giving the name of the new material. Example:
    1. `"crtOb Material Wood"`
       creates a material named Wood.
  - `"Instance"`: creates an instance of the selected object.
  - ...
- Example: Create a sphere and update the GUI: `"crtOb Sphere; uS; rV"`.

There are some helper commands, that create certain often used curves:

crtNCircle – create NURBS circle:

- Synopsis: `"crtNCircle [-r radius] [-a arc]"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command creates a circular NURBS curve with radius as defined via the `-r` option and arc as defined via the `-a` option. The curve always starts on the positive X axis. The radius defaults to 1.0 and the arc to 360.0. The arc option supports negative values.

crtClosedBS – create closed (circular) B-Spline:

- Synopsis: `"crtClosedBS sections [order [arc [radius]]]"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command creates a circular B-Spline curve with desired number of sections, order (defaults to 4), arc (defaults to 360.0, negative values are allowed), and radius (defaults to 1.0). The curve always starts on the positive X axis.

crtNRect – create a rectangular NURBS curve:

- Synopsis: `"crtNRect"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command creates a rectangular NURBS curve that fits the parameter space of the currently selected NURBS patch object (or the current parent object, if it is a NPatch). If no NURBS patch is selected or parent, this command will create a centered quadratic curve with width 2.0 and height 2.0 instead.

### 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):

- Synopsis: `"selOb [index]"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Use this command to set or clear the current selection, index may be an ordered list of indices, a single index or empty. If no index is given, the current selection will be cleared.
- Examples: `"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):

- Synopsis: `"withOb index [do] command"`
- Background: depends on command, Undo: depends on command, Safe: Yes
- Description: Use this command to execute command on a single object (designated by index) from a multiple selection without changing the selection state of any objects.
- Example: `"withOb 2 {movOb 0 1 0}"` moves the third object from multiple selected objects. All objects stay selected.

sL – select last object:

- Synopsis: `"sL"`
- Background: No, Undo: No, Safe: Yes
- Description: Select the last object in the current level and, if run in the Ayam interpreter, update the GUI. If run in the safe interpreter (e.g. from a Script objects script) this command will create a hidden selection. This command is often called in a sequence after creating a new object like this:

      # create object
      crtOb NCurve
      # update tree
      uCR
      # select new object
      sL

  In Script objects scripts the above example command sequence would leave out the `"uCR"` command, as access to the GUI is blocked anyway in this context:

      # create object
      crtOb NCurve
      # select new object
      sL

hSL – hidden select last object:

- Synopsis: `"hSL"`
- Background: Yes, Undo: No, Safe: No
- Description: Select the last object in the current level but do not update the GUI. Note: prior to Ayam 1.18 this command used to be available in the safe interpreter. This is no longer the case, use `"sL"` instead.

### Selecting Points

This command manipulates the point selection.

selPnts – select points:

- Synopsis: `"selPnts [-all | index1 index2 ...]"`
- Background: Yes, Undo: No, Safe: Yes
- Description:
  - If called without arguments, this command deselects all points.
  - If the argument is `"-all"`, this command selects all points.
  - If the argument contains an index, the corresponding point(s) will be added to the selection; already selected points will not be deselected. The index is zero-based and always one dimensional (even for surfaces). Multiple indices may be provided.
- Example: Given that a single NCurve object is selected, its points may be selected using the command `"selPnts -all"`; the first and third point of the same curve may be selected using `"selPnts 0 2"`.

### 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

- Synopsis: `"getProperty propname(elemname) varname"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command gets a single property element named elemname from the property named propname of the currently selected object and writes the result into the variable named varname.
- Notes: In contrast to many other helper commands, the variable varname does not have to be global. This command runs more slowly than calling the appropriate get-procedure and accessing the data array that is associated with a property directly, especially if multiple values are to be fetched. See below for more information regarding direct access of property values.
- Example: Given that a single Sphere object is selected, its radius may be retrieved in the variable `"r"` easily using the command

  > `

  >     getProperty SphereAttr(Radius) r

  > `

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

    getProp
    set r $::SphereAttrData(Radius)

See also section Global Property Management and Data Arrays.

setProperty – set single property value

- Synopsis: `"setProperty propname(elemname) value"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: This command sets a single property element named elemname of the property named propname for the currently selected object to the new value given in value.
- Notes: This command runs more slowly than accessing the data array that is associated with a property and calling the appropriate set-procedure directly, especially if multiple values are to be set. See below for more information regarding direct access of property values.
- Example: Given that a single Sphere object is selected, its radius may be set to the new value `"3.0"` easily using the command

  > `

  >     setProperty SphereAttr(Radius) 3.0

  > `

In contrast to using `"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:

- Synopsis: `"copOb"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Copy the selected object(s) to the object clipboard.

cutOb – cut object:

- Synopsis: `"cutOb"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Move the selected object(s) into the object clipboard.

pasOb – paste object:

- Synopsis: `"pasOb"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Copy the selected object(s) from the object clipboard to the current level.

delOb – delete object:

- Synopsis: `"delOb"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Delete the selected object(s) from the scene.

pasmovOb – paste (move) object:

- Synopsis: `"pasmovOb"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Move the objects from the object clipboard to the current level.

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

- Synopsis: `"pclip_copy mode"` or `"copyProp mode"`
- Background: Yes, Undo: No, Safe: No
- Description: Copy the currently selected property from the currently selected object to the property clipboard. If mode is 0, omit all marked entries, if mode is 1 copy just marked entries. Entries can also be marked programmatically by adding the respective entry names to the global array `"pclip_omit"`. Note that you may call this procedure also using the shortcut `"copyProp"`.

pclip_paste/pasteProp – paste a property

- Synopsis: `"pclip_paste"` or `"pasteProp"`
- Background: Yes, Undo: Yes, Safe: No
- Description: Copy the property from the property clipboard to the currently selected object. Note that you may call this procedure also using the shortcut `"pasteProp"`.

### Hierarchy Operations

These commands manipulate the current level of Ayam:

goDown:

- Synopsis: `"goDown index"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Enter the object determined by index. If index is 0 and the current level is inside some other object (not the root) the parent level will be entered instead. If index is -1, the last object of the current level will be entered.

goUp:

- Synopsis: `"goUp"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Go one level up in the object hierarchy.

goTop:

- Synopsis: `"goTop"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Go to the top level of the object hierarchy.

### Transformations

These commands transform objects or selected points of objects:

movOb – move objects:

- Synopsis: `"movOb dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Move the selected object(s) by dx in direction of the objects X axis, by dy in direction of the objects Y axis and by dz in direction of the objects Z axis.

rotOb – rotate objects:

- Synopsis: `"rotOb dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Rotate the selected object(s) by dx degrees around the objects X axis, then by dy degrees around objects Y axis and then by dz degrees around the objects Z axis. Note the order of the rotations.

scalOb – scale objects:

- Synopsis: `"scalOb dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Scale the selected object(s) by a factor of dx in direction of the objects X axis, by a factor of dy in direction of the objects Y axis and by a factor of dz in direction of the objects Z axis.
- Note: A scale factor of zero is generally a bad idea and thus will be changed to 1.0 silently.

movPnts – move selected points:

- Synopsis: `"movPnts dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Move the selected points by dx in direction of the objects X axis, by dy in direction of the objects Y axis and by dz in direction of the objects Z axis.

rotPnts – rotate selected points:

- Synopsis: `"rotPnts dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Rotate the selected points by dx degrees around the objects X axis then by dy degrees around objects Y axis and then by dz degrees around the objects Z axis. Note the order of the rotations.

scalPnts – scale selected points:

- Synopsis: `"scalPnts dx dy dz"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Scale the selected points by a factor of dx in direction of the objects X axis, by a factor of dy in direction of the objects Y axis and by a factor of dz in direction of the objects Z axis.
- Note: A scale factor of zero is generally a bad idea and thus will be changed to 1.0 silently.

delegTrafo – delegate transformations:

- Synopsis: `"delegTrafo"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: delegates the transformations associated with the selected objects to their child objects. Additionally, the transformations of the selected objects will be reset to the default values.

applyTrafo – apply transformations:

- Synopsis: `"applyTrafo sel | all"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: applies the transformations encoded in the transformation attributes of the selected objects to the points (either all points, or just the selected ones if there are any) of those objects. Additionally, the transformations of the selected objects will be reset to the default values.

### Manipulating Shaders

These commands operate the shader properties:

shaderSet:

- Synopsis: `"shaderSet shadertype [varname]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Set the shader of type shadertype for the selected object. Type may be one of `"surface"`, `"displacement"`, `"light"`, `"imager"`, `"atmosphere"`, `"exterior"` or `"interior"`. If varname is not given, the shader in question is deleted from the object instead.

shaderGet:

- Synopsis: `"shaderGet shadertype varname"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Get the shader of type shadertype for the selected object. Type may be one of `"surface"`, `"displacement"`, `"light"`, `"imager"`, `"atmosphere"`, `"exterior"` or `"interior"`. The shader will be written to an array pointed to by varname.

### Manipulating Tags

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

addTag:

- Synopsis: `"addTag type value"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Add a tag with type-string type and value-string value to the currently selected objects(s). It is legal to deliver `""` as value parameter. This is e.g. needed for the `"NoExport"` tag.
- Examples:
  1. `"addTag NoExport """`
     adds a `"NoExport"` tag to the selected objects.
  2. `"addTag RP Transformations"`
     adds a `"RP"` (remove property) tag to the selected objects that hides the Transformations property GUI.

delTags:

- Synopsis: `"delTags type"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Delete all tags of designated type from the currently selected objects(s). If type is `"all"`, all tags are deleted from the currently selected objects(s).
- Examples:
  1. `"delTags all"`
     removes all tags from the selected objects.
  2. `"delTags RP"`
     removes all `"RP"` tags from the selected objects.

getTags:

- Synopsis: `"getTags tvname vvname"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Get all tags from the currently selected objects and put them as lists into two variables named tvname for the tag types and vvname for the tag values.

setTags:

- Synopsis: `"setTags tags"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Clear all tags from the currently selected object and set new tags. The tag types are taken from the list elements with even index numbers and the tag value-strings from the list elements with odd index numbers.
- Examples:
  1. `"setTags {RP Transformations RP Attributes}"`
     replaces all tags from the selected objects with two `"RP"` tags.

### Manipulating NURBS Curves and Surfaces

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

clampNC – clamp NURBS curve:

- Synopsis: `"clampNC [side]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Clamp the knot vector of the selected NURBS curves without changing the shape of the curves. The knot type of the clamped curve will be changed to `"Custom"` and the knots will have o equal values at the desired side(s), where o is the order of the curve.

  If the side parameter is omitted or 0, both sides are clamped. If the side parameter is 1 only the start, and if it is 2 only the end is clamped.

  In Ayam versions prior to 1.18 it was an error if the curve was already clamped at either side, this is no longer the case. Furthermore, curves with multiple knots in the end region(s) could not be clamped, this works ok now. See also section Clamp Tool.

elevateNC – elevate NURBS curve:

- Synopsis: `"elevateNC n"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Elevate the order of the selected NURBS curves without changing the shape of the curves by n. The knot type of the elevated curves will be changed to `"Custom"`. See also section Elevate Tool.

insknNC – insert knot into NURBS curve:

- Synopsis: `"insknNC u r"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Insert a new knot at the position specified by u (u must be in the valid range of the knot vector of the selected curves) r times. The valid range is determined by the current knot vector U as follows: `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 Insert Knot Tool.

remknNC – remove knot from NURBS curve:

- Synopsis: `"remknNC (u | -i ind) r [tol]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Remove a knot at the position specified by u (u must be in the valid range of the knot vector of the selected curve) r times from the curve. Since Ayam 1.20 the knot to remove may also be specified using its (zero based) index in the knot vector (i.e. use `"remknNC -i 4 1"` instead of `"remknNC 0.5 1"`).

  Note that the shape of the curve may be changed by this tool unless the parameter tol is specified. If tol is specified the new curve does not deviate from the original curve more than tol in any point on the curve. If the knot can not be removed r times due to the tolerance, an error is reported and the original curve is left unchanged. See also section Remove Knot Tool.

refineNC – refine NURBS curve:

- Synopsis: `"refineNC [-cv | {u1 u2 un}]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Refine the knot vector of the selected NURBS curve without changing the shape of the curve with n new knots {u1 u2 un} or refine the control vector (if `"-cv"` option is given). If no list of new knots is given a new knot is inserted into each interval in the old knot vector. See also section Refine Tool.

coarsenNC – coarsen NURBS curve:

- Synopsis: `"coarsenNC"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Remove every second control point from the selected NURBS curves. See also section Coarsen Tool.

revertC – revert curves:

- Synopsis: `"revertC"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Revert the direction of the selected NURBS, interpolating, and approximating curves. See also section Revert Tool.

revertuS – revert surfaces:

- Synopsis: `"revertuS"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Revert the direction of the selected surfaces in the u parametric dimension. See also section Revert U Tool.

revertvS – revert surfaces:

- Synopsis: `"revertvS"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Revert the direction of the selected surfaces in the v parametric dimension. See also section Revert V Tool.

swapuvS – swap dimensions of surfaces:

- Synopsis: `"swapuvS"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Swap the dimensions of the selected surfaces, thus exchanging width and height (without altering the shape of the surfaces). See also section Swap UV Tool.

rescaleknNC – rescale knots of NURBS curves:

- Synopsis: `"rescaleknNC [-r rmin rmax | -d mindist]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Rescale the knot vector(s) of the selected NURBS curve(s) to the range `[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.

  Since Ayam 1.20 the knot type of the curve does not have to be `"Custom"` anymore. Furthermore, rescaling the knots does not change the knot type.

  This operation does not change the shape of the curve. See also section Rescale Knots to Range Tool.

splitNC – split NURBS curve

- Synopsis: `"splitNC u"`
- Background: Yes, Undo: No, Safe: Yes
- Description: splits the selected NURBS curve at designated parametric value into two curves, creating one new curve and modifying the original selected curve. See also section Split Tool.

shiftC – shift control points of a (closed) curve:

- Synopsis: `"shiftC i"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: shifts the control points of the selected NCurve, ACurve, and ICurve objects by an amount specified by the parameter i (which may be negative to revert the direction of the shifting). For a simple closed curve, shifting with i=1, the first control point will get the coordinates of the former last control point. This means, positive shifts occur in the direction of the curve. Note that for closed and periodic NURBS curves, the multiple points will be managed correctly. See also section Shift Closed Curve Tool.

toXYNC – move NURBS curve to XY plane

- Synopsis: `"toXYNC"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: moves the control points of the selected NURBS curve objects to its XY plane. See also section To XY Tool.

trimNC – trim NURBS curve

- Synopsis: `"trimNC umin umax"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: trims the selected NURBS curve to the designated parametric range (umin-umax), modifying the original selected curve. See also section Trim Tool.

estlenNC – estimate length of NURBS curve:

- Synopsis: `"estlenNC varname"`
- Background: Yes, Undo: No, Safe: Yes
- Description: estimate the length of the currently selected curve and put the result into the designated variable.

reparamNC – reparameterise a NURBS curve:

- Synopsis: `"reparamNC type"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: reparameterise all selected NURBS curves to have chordal knots (type: 0), or centripetal knots (type: 1). The knot type of the curve will be changed to `"Custom"`.

makeCompNC – make NURBS curves compatible

- Synopsis: `"makeCompNC"`
- Background: Yes, Undo: No, Safe: Yes
- Description: makes the selected NURBS curves compatible i.e. of the same order and defined on the same knot vector. See also section Make Compatible Tool.

clampuNP – clamp NURBS patch in U direction:

- Synopsis: `"clampuNP [side]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Clamp the U direction knot vector of the selected NURBS patches without changing the shape of the patches. The knot type will be changed to `"Custom"` and the knots will have o equal values at start and end (where o is the order of the patch in U direction).

  If the side parameter is omitted or 0, both sides are clamped. If the side parameter is 1 only the start, and if it is 2 only the end is clamped.

  In Ayam versions prior to 1.18 it was an error if the patch was already clamped at either side, this is no longer the case. Furthermore, patches with multiple knots in the end region(s) could not be clamped, this works ok now. See also section Patch Clamp Tool.

clampvNP – clamp NURBS patch in V direction:

- Synopsis: `"clampvNP [side]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Clamp the V direction knot vector of the selected NURBS patches without changing the shape of the patches. The knot type will be changed to `"Custom"` and the knots will have o equal values at start and end (where o is the order of the patch in V direction).

  If the side parameter is omitted or 0, both sides are clamped. If the side parameter is 1 only the start, and if it is 2 only the end is clamped.

  In Ayam versions prior to 1.18 it was an error if the patch was already clamped at either side, this is no longer the case. Furthermore, patches with multiple knots in the end region(s) could not be clamped, this works ok now. See also section Patch Clamp Tool.

rescaleknNP – rescale knots of NURBS patches:

- Synopsis: `"rescaleknNP [-r[u|v] rmin rmax | -d[u|v] mindist]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Rescale the knot vector(s) of the selected NURBS patch(es) to the range `[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. Since Ayam 1.20 the knot type of the curve does not have to be `"Custom"` anymore. Furthermore, rescaling the knots does not change the knot type. This operation does not change the shape of the patch. See also sections Patch Rescale Knots to Range Tool and Patch Rescale Knots to Mindist Tool.
- Example: `"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).

insknuNP – insert knot into NURBS patch:

- Synopsis: `"insknuNP u r"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Insert a new knot in U direction at the position specified by u, r times. u must be in the valid range of the corresponding knot vector of the selected patches. The valid range is determined by the current knot vector U as follows: `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 Patch Insert Knot Tool.

insknvNP – insert knot into NURBS patch:

- Synopsis: `"insknvNP v r"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Insert a new knot in V direction at the position specified by v, r times. v must be in the valid range of the corresponding knot vector of the selected patches. The valid range is determined by the current knot vector V as follows: `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 Patch Insert Knot Tool.

remknuNP – remove u knot from NURBS surface:

- Synopsis: `"remknuNP (u | -i ind) r [tol]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Remove a knot at the position specified by u (u must be in the valid range of the knot vector of the selected surface) r times from the surface. Since Ayam 1.20 the knot to remove may also be specified using its (zero based) index in the knot vector (i.e. use `"remknuNP -i 4 1"` instead of `"remknuNP 0.5 1"`). Note that the shape of the surface may be changed by this tool unless the parameter tol is specified. If tol is specified, the new surface does not deviate from the original surface more than tol in any point. If the knot can not be removed r times due to the tolerance, an error is reported and the original surface is left unchanged. See also section Patch Remove Knot Tool.

remknvNP – remove v knot from NURBS surface:

- Synopsis: `"remknvNP (v | -i ind) r [tol]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Remove a knot at the position specified by v (v must be in the valid range of the knot vector of the selected surface) r times from the surface. Since Ayam 1.20 the knot to remove may also be specified using its (zero based) index in the knot vector (i.e. use `"remknvNP -i 4 1"` instead of `"remknvNP 0.5 1"`). Note that the shape of the surface may be changed by this tool unless the parameter tol is specified. If tol is specified, the new surface does not deviate from the original surface more than tol in any point. If the knot can not be removed r times due to the tolerance, an error is reported and the original surface is left unchanged. See also section Patch Remove Knot Tool.

refineuNP – refine NURBS surface in u direction:

- Synopsis: `"refineuNP"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Refine the selected NURBS surfaces in u direction without changing their shape. The u knot type of the refined surfaces may be changed to `"Custom"`. See also section Refine Surface Tool.

refinevNP – refine NURBS surface in v direction:

- Synopsis: `"refinevNP"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Refine the selected NURBS surfaces in v direction without changing their shape. The v knot type of the refined surfaces may be changed to `"Custom"`. See also section Refine Surface Tool.

elevateuNP – elevate NURBS surface in u direction:

- Synopsis: `"elevateuNP n"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Elevate the u order of the selected NURBS surfaces without changing the shape of the surfaces by n. The u knot type of the elevated surfaces will be changed to `"Custom"`. See also section Elevate UV Tool.

elevatevNP – elevate NURBS surface in v direction:

- Synopsis: `"elevatevNP n"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Elevate the v order of the selected NURBS surfaces without changing the shape of the surfaces by n. The v knot type of the elevated surfaces will be changed to `"Custom"`. See also section Elevate UV Tool.

splituNP – split NURBS patch:

- Synopsis: `"splituNP u"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Splits the selected NPatch objects into two patches at parametric value u. The selected NPatch will be modified and a new NPatch object will be created and appended as new object to the current level of the scene. See also section Patch Split Tools.

splitvNP – split NURBS patch:

- Synopsis: `"splitvNP v"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Splits the selected NPatch objects into two patches at parametric value v. The selected NPatch will be modified and a new NPatch object will be created and appended as new object to the current level of the scene. See also section Patch Split Tools.

extrNP – extract NURBS patch:

- Synopsis: `"extrNP umin umax vmin vmax"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Extracts a sub-patch from the selected NPatch objects. The extracted patch will be appended as new object to the current level of the scene. The sub-patch to be extracted is specified by the parametric values umin, umax, vmin, and vmax which have to be in the respective valid knot range. See also section Extract Patch Tool.

interpuNP – interpolate NURBS surface in u direction:

- Synopsis: `"interpuNP [-order order | -ktype type | -closed (0|1) | -sdlen length | -edlen length]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Interpolate the selected NURBS surfaces in u direction with desired order and parameterisation type. Order defaults to 4 and must be higher than 2. The parameterisation type must be one of 0 – Chordal, 1 – Centripetal, or 2 – Uniform, default is Chordal. The interpolation can create a closed surface but this will also increase the width of the resulting NURBS surface (the default is to create an open surface). Using the options `"-sdlen"` and `"-edlen"` (which both default to 0.0) the length of automatically created start/end derivatives can be adjusted. If any of these is not 0.0, a different interpolation algorithm will be used, which increases the width of the resulting NURBS surface. The surface will interpolate all current control points after the interpolation and the position of certain control points will be changed in this process so that, after interpolation, the new control points will not be interpolated by the surface. The surface will interpolate the old control point positions. The u knot type of the interpolated surfaces will be changed to `"Custom"`.

interpvNP – interpolate NURBS surface in v direction:

- Synopsis: `"interpvNP [-order order | -ktype type | -closed (0|1) | -sdlen length | -edlen length]"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Interpolate the selected NURBS surfaces in v direction with desired order and parameterisation type. Order defaults to 4 and must be higher than 2. The parameterisation type must be one of 0 – Chordal, 1 – Centripetal, or 2 – Uniform, default is Chordal. The interpolation can create a closed surface but this will also increase the height of the resulting NURBS surface (the default is to create an open surface). Using the options `"-sdlen"` and `"-edlen"` (which both default to 0.0) the length of automatically created start/end derivatives can be adjusted. If any of these is not 0.0, a different interpolation algorithm will be used, which increases the height of the resulting NURBS surface. The surface will interpolate all current control points after the interpolation and the position of certain control points will be changed in this process so that, after interpolation, the new control points will not be interpolated by the surface. The surface will interpolate the old control point positions. The v knot type of the interpolated surfaces will be changed to `"Custom"`.

concatS – concatenate surfaces:

- Synopsis: `"concatS [-o order | -t type | -k knottype | -u uvselect]"`
- Background: Yes, Undo: No, Safe: No
- Description: Concatenate the selected surface objects into a single NURBS patch. The option `"-o"` determines the desired order of the surface in U-direction. The option `"-t"` allows to set a surface type (0 – open, 1 – closed, 3 – periodic; default 0), and `"-k"` allows to set a knot type (default 1 - NURB). Finally, the `"-u"` option allows to specify the uv-select-string. See also section ConcatNPAttr Property for more information on these options.

splitNP – split NURBS patch:

- Synopsis: `"splitNP (u | v)"`
- Background: Yes, Undo: No, Safe: No
- Description: Splits the selected NPatch objects into NURBS curves, along parametric dimension u or v. See also section Patch Split Tools.

buildNP – build NURBS patch:

- Synopsis: `"buildNPatch"`
- Background: Yes, Undo: No, Safe: No
- Description: Builds a NURBS patch from the selected NURBS curves. See also section Build from Curves Tool.

### 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. manipulating the points of a NURBS curve requires just one index parameter (indexu), whereas manipulating the points of a NURBS patch requires two index parameters (indexu and indexv) to be specified.

getPnt – get point(s):

- Synopsis: `"getPnt [-trafo | -world | -eval] (index | indexu indexv | u | u v (varx vary varz [varw] | -vn varname) | -all varname)"`
- Background: Yes, Undo: No, Safe: Yes
- Description: Get a control point of the currently selected object and write the coordinate values into the variables varx, vary, varz, and varw.

  If the optional argument `"-trafo"` is given, the coordinates will additionally be transformed by the values given in the objects Transformation property.

  If the optional argument `"-world"` is used, the coordinates will additionally be transformed to world space.

  If the optional argument `"-eval"` is specified, 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.

  If the alternative argument `"-vn"` is given, the coordinate values will be appended to the list variable specified by `"varname"`.

  If the alternative argument `"-all"` is used, all coordinate values of the selected objects will be appended to the list variable specified by `"varname"`.

- Notes: In Ayam versions prior to 1.20, only global variables were written, this is no longer the case.
- Examples:
  1. `"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"`.
  2. `"getPnt -eval 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 – set point(s):

- Synopsis: `"setPnt [-world] (indexu [indexv] (x y z [w] | -vn varname) | -all varname)"`
- Background: Yes, Undo: Yes, Safe: Yes
- Description: Set a control point of the currently selected object to the coordinates x, y, z, and w or to coordinates from a list, or set all control points from a list of coordinate values.

  If the optional parameter `"-world"` is given, the coordinate values are expressed in world space and will be transformed to appropriate object space coordinates before setting.

  If the optional parameter `"w"` is omitted, but the selected object has rational points, a default value of 1.0 will be used for the weight.

  If the alternative parameter `"-vn"` is used, the coordinate values will be read from the variable specified by `"varname"` which must be a list of double values.

  If the alternative parameter `"-all"` is provided, all control points of the selected objects will be set and the coordinate values will be read from the variable specified by `"varname"` which must be a list of double values.

  When reading data from list variables, no precision will be lost as there are no double-string-double conversions involved.

- Examples:
  1. `"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"`.
  2. `"setPnt -world 0 0 0 0"`
     sets the first point of the selected NURBS curve object to the world origin, regardless of the transformation attributes of the curve object (or any of its potential parent objects).
  3. `"setPnt 2 1 0.0 0.2 0.3"`
     sets the coordinate values of the second point in the third column of the control mesh of the selected NURBS patch object to `"0.0 0.2 0.3 1.0"`.

### Updating the GUI

These commands update various parts of the Ayam user interface:

rV – redraw all views:

- Synopsis: `"rV"`
- Background: No, Undo: No, Safe: No
- Description: Redraws all currently open views, except for iconified views and views where automatic redraw has been turned off.

uS – update select:

- Synopsis: `"uS [update_prop maintain_selection]"`
- Background: No, Undo: No, Safe: No
- Description: Update the object listbox or tree view after a change to the object hierarchy.

  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.

- Deficiencies: uS completely removes the object tree from the tree widget and rebuilds it, which can be a very time consuming operation (depending on the complexity of the scene). There are some options to speed this process up:
  - If there were just changes to the current level (and below) the global array entry `"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;

    .
  - If objects have been created and thus just need to be added to the current level of the object tree view, the command `"uCR"` may be used instead of `"uS"`.
  - If just names or types of objects of the current level changed, the command `"uCL cl"` may be used instead of `"uS"`.

uCL – update current level:

- Synopsis: `"uCL mode [args]"`
- Background: No, Undo: No, Safe: No
- Description: Update only the current level of the object listbox or tree view after changes. See also the discussion of `"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:

- Synopsis: `"uCR"`
- Background: No, Undo: No, Safe: No
- Description: Update only the current level of the object listbox or tree view after objects have been created and need to be added to the current level. See also the discussion of `"uS"` above.

plb_update – property listbox update:

- Synopsis: `"plb_update"`
- Background: No, Undo: No, Safe: No
- Description: Clear the current property GUI, ask the currently selected object for a list of properties and insert them in the property listbox, then rebuild the property GUI of the property with the same index in the property listbox as the property selected before plb_update was started (this is not necessarily a property of the same type).

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.

### Managing Preferences

These commands manage preferences data:

getPrefs – get preferences data:

- Synopsis: `"getPrefs"`
- Background: No, Undo: No, Safe: No
- Description: Copy preferences data from the C to the Tcl context.

setPrefs – set preferences data:

- Synopsis: `"setPrefs"`
- Background: No, Undo: No, Safe: No
- Description: Copy preferences data from the Tcl to the C context. This is necessary after a change to the global ayprefs Tcl array to let the changes take effect.

### Custom Objects

This command manages custom objects (plugins):

io_lc – load custom:

- Synopsis: `"io_lc filename"`
- Background: No, Undo: No, Safe: No
- Description: Load the custom object (plugin) from file filename. Note that it is currently not possible to unload a custom object from Ayam.

### 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:

- Synopsis: `"forAll recursive command"`
- Background: depends, Undo: depends, Safe: No
- Description: The forAll command executes command for all objects that have been selected currently, or for every object of the current level if nothing has been selected. If recursive is 1 then forAll will recurse into every object (if it has child objects) before the execution of command. Note that forAll will run slowly if a property GUI is displayed. You can make it run faster by de-selecting the property using e.g. the property context menu first.
- Deficiencies:
  - A recursive forAll will e.g. also descend into NURBS patches (if they have trim curves) and apply the command to the trim curves, which might not exactly be what you want. Use `"forAllT"` in this case.
  - The command will not have access to global arrays unless e.g. one of the following constructs is in use:

    `"forAll 0 { uplevel #0 { commands } }"`

    `"forAll 0 { global arrayname; commands }"`

  - It is not possible to use commands that change the object hierarchy (e.g. deleting or inserting objects). The commands may just modify existing objects. Since Ayam 1.9 `"forAll"` correctly maintains the current selection.

forAllT:

- Synopsis: `"forAllT type recursive command"`
- Background: depends, Undo: depends, Safe: No
- Description: forAllT works the same way as forAll, with an additional type check. The command will not be executed if the type of the current object does not match the argument type. Note that forAllT will run slowly if a property GUI is displayed. You can make it run faster by de-selecting the property using e.g. the property context menu first.

  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}"`

- Deficiencies:
  - The command will not have access to global arrays unless e.g. one of the following constructs is in use:

    `"forAllT ncurve 0 {uplevel #0 {commands} }"`

    `"forAllT ncurve 0 { global arrayname; commands }"`

  - It is not possible to use commands that change the object hierarchy (e.g. deleting or inserting objects). The commands may just modify existing objects. Since Ayam 1.9 `"forAllT"` correctly maintains the current selection.

### Scene IO

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

newScene:

- Synopsis: `"newScene"`
- Background: Yes, Undo: No, Safe: No
- Description: clears the current scene.

replaceScene:

- Synopsis: `"replaceScene filename"`
- Background: Yes, Undo: No, Safe: No
- Description: clears the current scene, then loads a new scene from filename.

insertScene:

- Synopsis: `"insertScene filename"`
- Background: Yes, Undo: No, Safe: No
- Description: inserts a scene from filename.

saveScene:

- Synopsis: `"saveScene filename"`
- Background: Yes, Undo: No, Safe: No
- Description: saves the current scene to filename.

### RIB Export

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

wrib – RIB export:

- Synopsis: `"wrib filename [-image imagename] [-smonly | -selonly | -objonly]"`
- Background: Yes, Undo: No, Safe: No
- Description: exports the current scene to a RIB file designated by `"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 used, 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. Likewise `"-objonly"` leads to a RIB file containing all objects in the scene but not suitable for rendering.

  The `"wrib"` command always needs a selected camera object (unless the `"-selonly"` or `"-objonly"` options are given); 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

  The Togl callback understands the same options as the `"wrib"` command.
- Notes: In Ayam versions prior to 1.15, the filename had to be prepended by a `"-filename "`, this is no longer the case.

### Reporting Errors

This command is for error reporting from scripts:

ayError:

- Synopsis: `"ayError code place detail"`
- Background: No, Undo: No, Safe: No
- Description: This command reports errors or warnings. You should always use ayError instead of puts because the error reporting mechanism of Ayam features consistently formatted output, compression of repeated messages, and logging. Code should be one of: 1: warning, 2: error, 3: flush messages, 4: unspecified output. There are more codes defined (see ayam.h, look for Return/Error Codes) but they are not needed in the Tcl script context. Place should describe the procedure where the error occured. Detail is the string to be output.
- Notes: The actual output in the Ayam console depends on the preference option `"ErrorLevel"` see section Miscellaneous Preferences.

### Miscellaneous

Miscellaneous commands:

getType:

- Synopsis: `"getType varname"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command writes the type of the selected object into the variable varname. The types are the well known strings that are displayed in the hierarchy list box if the objects are not named (NPatch, NCurve, Sphere, etc.).

tmpGet:

- Synopsis: `"tmpGet tmpdir varname"`
- Background: Yes, Undo: No, Safe: No
- Description: This command calculates a name for a temporary file in tmpdir and puts the complete name into varname.

hasChild:

- Synopsis: `"hasChild"`
- Background: Yes, Undo: No, Safe: Yes
- Description: This command returns 1 if the selected object has child objects, otherwise it returns 0.

undo:

- Synopsis: `"undo [redo | save opname [0|1] | clear | rewind]"`
- Background: Yes, Undo: Yes, Safe: No
- Description:
  - If called without arguments, this command performs the undo operation.
  - If the argument is `"redo"`, this command performs the redo operation.
  - If the argument is `"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 (e.g. `"[Undo:MoveObj/Redo:none].../bin>"`). Since Ayam 1.13, a third argument may be given, that controls whether all the children of the selected objects should also be saved. This may be needed if the modelling action that follows the undo save is about to change the selected objects and also their children. Note: undo save does not fail if no objects are selected.
  - If the argument is `"clear"`, all currently saved states will be cleared from the undo buffer.
  - The argument `"rewind"` is available since Ayam 1.14. With this command you can undo the last undo save operation. This may be necessary, if a modelling operation failed. Care should be taken, however, to not rewind the undo state, when a modelling operation only failed for some (not for all) of the selected objects.
- Example:

      undo save "MovOb"
      set ay_error ""
      movOb 0 1 0
      if { $ay_error > 1 } {
        undo rewind
      }

- Notes: See also section The Undo System.

convOb:

- Synopsis: `"convOb [-inplace]"`
- Background: Yes, Undo: depends (if -inplace: Yes), Safe: Yes
- Description: This command calls the registered converter for the selected object(s). If the option `"-inplace"` is used, the new object(s) will replace the old object(s).

notifyOb:

- Synopsis: `"notifyOb [-all | -modified | -parent]"`
- Background: Yes, Undo: No, Safe: No
- Description: This command calls the registered notification callback for the selected object(s) and their parents, or, if no object is selected, for all objects of the scene.

  If the `"-modified"` parameter is used, only modified objects will be notified.

  If the `"-all"` parameter is used, all objects will be notified regardless of the selection.

  If the `"-parent"` parameter is used, only the current parent object of the current level will be notified.

  Prior to Ayam 1.20 this command was named `"forceNot"`, the old name is still available for compatibility but its use is deprecated.

addToProc:

- Synopsis: `"addToProc procedure addition"`
- Background: Yes, Undo: No, Safe: No
- Description: This command adds the code from addition to the procedure procedure.
- Note: This command uses the introspection facilities of Tcl and works only correctly for procedures, that end with a single `"return;"` statement.

## 6.3 Expression Support in Dialog Entries

Various entries of dialogs for object creation and modelling tools support Tcl variables and expressions.

One can e.g. enter

    $::u

instead of a numeric knot value in the insert knot tool parameter dialog to infer the parametric value from the global variable u (that may have been set before using the find u modelling action) and insert a knot at the picked point.

It is also possible to enter complex mathematical expressions:

    [expr sin(45)]

or call into own procedures (that have to return appropriately typed values):

    [myproc]

.

Repeated calling of the tool without opening the dialog (using the keyboard shortcut `<Ctrl+T>`), will execute the provided expression again. This means, one can e.g. create a number of curves with increasing length by entering into the Ayam console

    set ::myvar 1

then entering for the length in the create NURBS curve dialog:

    [incr ::myvar]

then pressing `<Ctrl+T>` multiple times.

## 6.4 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, the procedure `"toolbox_add"` can be of considerable help. *

See also the script `"scripts/topoly.tcl"` for an example.

Here is another 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.5 Helper Scripts

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

The 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 (the latter except for repairAyam.tcl and bgconvert.tcl).

### Repair Ayam

The external Tcl script `"repairAyam.tcl"` 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`

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 one has to start `"repairAyam.tcl"` from the Ayam console using the command:

> `source scripts/repairAyam.tcl`

or via the consoles context menu: `"Console/Load File"`.

The script `"repairAyam.tcl"` should be considered a last resort to help saving the current state of 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.

Furthermore, the script 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"` the scene (or the most important objects currently worked on) should be immediately saved to a new scene file, not the file currently loaded, using `"File/Save As"` or `"Special/Save Selected"`) and Ayam should be restarted afterwards.

Simply saving the scene using `"File/Save"` or `<Ctrl+s>` should be avoided because views were possibly deleted.

### Convert Everything to Polygons

The script `"topoly.tcl"` 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 can not be undone, the conversion will not run if the scene contains unsaved changes.

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

### Convert Everything to NURBS patches

The script `"tonpatch.tcl"` recursively browses through the scene and converts everything to a NURBS patch representation effectively flattening the tool object hierarchy. *

After running the script, there is a new button in the toolbox named `"ToNPatch"`. 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 can not be undone, the conversion will not run if the scene contains unsaved changes.

### 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 of text. Different values may be chosen easily by adapting the script.

### Color the Focus Ring

The script `"colfocus.tcl"` (for colored focus) may be used to paint the focus ring in a more visible color.

After running the script, the focus ring will be painted in blue (instead of black): focussed sub-windows (views, console, object tree) will be more easily recognizable.

### Automatic About Center Actions

The script `"aac.tcl"` (for automatic about center) may be used to switch all modelling actions to their about variants with the mark set to the center of the current selection automatically.

After running the script, invoking e.g. the scale 2D action using the shortcut `<s>` will:

- if the modelling mode is object,
  1. set the mark to the center of all selected objects
  2. invoke the about variant of scale 2D
  (this is the equivalent of `<sac>`)
- if the modelling mode is point,
  1. set the mark to the center of all selected points
  2. invoke the about variant of scale 2D
  (this is the equivalent of `<saC>`)

The script modifies all rotate and scale actions (including their axis confined variants).

Note, that the mark is not reset to a new center, when the selection changes. After a selection change (e.g. by selecting points in a different view) simply restart the action to transform about the new center.

To temporarily disable the modified behaviour, the `<F11>` key can be used.

To rotate or scale about a different point than the center, the mark may still be set manually using `<a>`.

### Automatic Point Actions

The script `"apnt.tcl"` (for automatic point) may be used to switch the modelling mode of the current or all views to point modelling automatically after a point selection.

After running the script, selecting (tagging) a point using the select point action (shortcut `<t>`) will automatically switch the view to point modelling so that the next modelling actions (e.g. move, via shortcut `<m>`) will always transform the points and not modify the objects transformations. Note that currently the switch to point modelling will also occur, if no points are actually selected, it is just the mouse click that counts.

It is still possible to switch back to object modelling anytime via the keyboard shortcut `<o>`.

### Use Ayam as Command Line Converter

The external Tcl script `"bgconvert.tcl"` converts scene files from one 3D file format to another, with the help of Ayam which is running in the background. *

In the most simple form, bgconvert 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"`.

For a successfull conversion Ayam has to run and the plugins required for the import and export processes need to be available and properly configured (check the `"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.

### Create Polyhedrons from Conway Notations

Polyhedron generated from Conway notation: jtD

Since Ayam 1.18 there is a complete example script for the JavaScript scripting interface distributed as `"polyhedron.js"` which creates polyhedrons from Conway notations. The script is based on the online Polyhedron VRML generator by George W. Hart.

This script must be used in a Script object of type `"Create"`. For convenience, there is also a property GUI; one must add a `"NP"` tag of value `"PolyhedronAttr"` to the script object to see it.

The Conway notation defines a set of operations executed consecutively on a seed/basic shape. The script currently supports the following seeds and operations (information taken from George W. Harts fine web pages, see also section References).

Seeds:
The Platonic solids are denoted T, O, C, I, and D, according to their first letter. Other polyhedra which are implemented here include prisms: Pn, antiprisms: An, and pyramids: Yn, where n is a number (3 or greater) which must be specified to indicate the size of the base, e.g., Y3=T, P4=C, and A3=O.

Operations:
Currently, d, t, k, a, j, s, g, e, b, o, m, r, and p are defined. They are motivated by the operations needed to create the Archimedean solids and their duals from the Platonic solids. The following tables explain the operations in more detail:

Letter | Name | Description
`d` | dual | The dual of a polyhedron has a vertex for each face, and a face for each vertex, of the original polyhedron, e.g. dC=O.
`t`/`t` n | truncate all / just n-fold vertices | Truncating a polyhedron cuts off each vertex, producing a new n-sided face for each n-fold vertex.
`k`/`k` n | kis all / just n-sided faces | The kis operation divides each n-sided face into n triangles. A new vertex is added in the center of each face.
`a` | ambo | The ambo operation can be thought of as truncating to the edge midpoints. It produces a polyhedron, aX, with one vertex for each edge of X.
`j` | join | The join operator is dual to ambo, so jX=dadX=daX. jX is like kX without the original edges of X.
`e` | expand | Each face of X is separated from all its neighbors and reconnected with a new 4-sided face, corresponding to an edge of X. An n-gon is then added to connect the 4-sided faces at each n-fold vertex.
`s` | snub | The snub operation can be thought of as eC followed by the operation of slicing each of the new 4-fold faces along a diagonal into two triangles. With a consistent handedness to these cuts, all the vertices of sX are 5-fold.
`g` | gyro | The dual operation to s is g. g is like k but with the new edges connecting the face centers to the 1/3 points on the edges rather than the vertices.
`b` | bevel | The bevel operation can be defined by bX=taX.
`o` | ortho | Dual to e, oX=deX=jjX. oX has the effect of putting new vertices in the middle of each face of X and connecting them, with new edges, to the edge midpoints of X.
`m` | meta | Dual to b, m is like k and o combined; new edges connect new vertices at the face centers to the old vertices and new vertices at the edge midpoints.

Conway Notation Operations

Letter | Name | Description
`r` | reflect | Changes a left-handed solid to right handed, or vice versa, but has no effect on a reflexible solid. So rC=C, but compare sC and rsC.
`p` | propellor | Makes each n-gon face into a "propellor" of an n-gon surrounded by n quadrilaterals, e.g. pT is the tetrahedrally stellated icosahedron. Try pkD and pt6kT. p is a self-dual operation, i.e., dpdX=pX and dpX=pdX, and p also commutes with a and j, i.e. paX=apX.

Additional Operations

These abbreviated explanations were again taken from George W. Hart.

## 6.6 JavaScript Scripting Interface

This sections contains the documentation of the JavaScript scripting interface which is available after loading of the `"jsinterp"` plugin.

The JavaScript scripting interface exists since Ayam 1.18 and is based on the Mozilla SpiderMonkey JavaScript engine.

Upon loading, the `"jsinterp"` plugin creates one JavaScript context that lives (with all variables and objects defined therein) until Ayam exits.

### Accessing JavaScript from Tcl and Script Objects

To access the JavaScript functionality from the Tcl scripting interface, the `"jsEval"` command can be used to directly execute JavaScript code (Tcl code in bold):

> ``jsEval {var a = 0; a = a + 5.5; tclset("a", a);}``

or from a file:

> ``jsEval -f scriptfile.js``

Furthermore, Script object scripts may also be implemented in JavaScript, provided the first line of the script is a comment that instructs Ayam to use the JavaScript interpreter:

> ``/* Ayam, use: JavaScript */
> var a = 0;
> ...``

Note that the JavaScript scripting context inherits the limitations of the calling Tcl context. For example, when running in a Script object, the following code fails:

> ``tcleval("exit");``

it does not fail, when the calling context ist the main Tcl interpreter; one can e.g. type into the Ayam console:

> ``jsEval {tcleval("exit");}``

and Ayam quits (see also section: Safe Interpreter).

### JavaScript Functions

This subsection informs about the global functions additionally available in the Ayam JavaScript interpreter.

Those are converted Tcl commands, `"tcleval"`, `"tclvar"`, and `"tclset"`.

The functionality of Ayam is accessible from JavaScript via a larger set of global functions, named as the corresponding Tcl commands. One may e.g. create Ayam objects in JavaScript using a function call like this:

> ``crtOb("NCircle");``

or, with additional arguments:

> ``crtOb("NCircle", "-radius", 3.0);``

In general, all commands available in the safe Ayam Tcl interpreter are also available as converted function (refer to section Index of Procedures and Commands for a more or less complete list of those commands).

Note that many Tcl procedures are not available as global JavaScript function, but they can be called using `"tcleval"` as documented in the next paragraph.

`tcleval:`
Apart from Tcl commands converted to JavaScript functions, there is the global JavaScript function `"tcleval"`, that allows to evaluate arbitrary Tcl scripts:

> ``var a = 42;
> a = tcleval("puts " + a + "; return 5;");
> tcleval("puts " + a);
> /* expected output: 42 5 */``

The `"tcleval"` function provides access to all the functionality of Ayam that is just available as a Tcl procedure. Note that return values are properly transferred back to JavaScript according to the rules for data conversion as documented below.

`tclvar:`
Using the JavaScript function `"tclvar"` one may establish a link between a Tcl variable and a corresponding variable in the JavaScript context. The `"tclvar"` function establishes a write trace on the Tcl variable, so that changes on the Tcl side are always automatically reflected on the JavaScript side:

> ``tclvar("a");
> tcleval("set a 42");
> tcleval("puts " + a);
> /* expected output: 42 */``

Mind that the corresponding variable on the JavaScript side does not exist until the first write onto the Tcl variable. The Tcl variable, in turn, does not have to exist, when the `"tclvar"` function is called (i.e. all the work is done in the trace callback).

Even though it looks a perfect fit, `"tclvar"` can not be used to manage a property data array. Atleast not if the array contains components to be saved to Ayam scene files. This is, because upon reading a scene file with such saved array items, the items will be read (and put into the Tcl context) before the script can establish the write trace using `"tclvar"` and the data from the scene file never arrives in the JavaScript context. There is no easy way to get around this. A suggested way to manage a property data array is shown in the complete examples section below.

`tclset:`
The third global JavaScript function is `"tclset"` that allows to efficiently set Tcl variables from the JavaScript context avoiding conversion to string data and back. For example:

> ``var a = 3.3;
> var b = new Array(1, 3, 5);
> tclset("a", a);
> tclset("b", b);``

sets the Tcl variable `"a"` to the floating point value 3.3, and `"b"` to a list of integer values (`"{ 1 3 5 }"`). Note that the variable names may also point to Tcl array elements: `"tclset("SphereAttrData(Radius)", 1.2);"`.

### Data Conversion

When data is transferred from the Tcl to the JavaScript side (e.g. while converting return values of `"tcleval"` or variable values linked via `"tclvar"`), the following conversions are in effect: Scalar data types will be converted to their directly matching counterparts, except for Booleans, which will be converted to integer values. Lists will be converted to Array objects (nesting is allowed and will produce accordingly nested arrays). Associative arrays will be converted to objects with named properties. Unicode strings are currently not supported. See also the table below.

Tcl | JavaScript
Boolean (true, false) | Integer (1, 0)
Integer (2) | Integer (2)
Double (3.14) | Double (3.14)
String ("mystr") | String ("mystr")
List ({0 1 2}) | Array ((0, 1, 2))
Array (mya(mye) = 0.1) | Object (mya.mye = 0.1)

Tcl to JavaScript Data Conversions

When data is transferred from the JavaScript side to the Tcl side (e.g. as function argument), the following conversions are in effect: Scalar data types will be converted to their directly matching counterparts, Array objects will be converted to lists (nesting is allowed and will produce accordingly nested lists). Unicode strings and objects of a type other than Array (e.g. Boolean) are currently not supported. See also the following table.

JavaScript | Tcl
Integer (2) | Integer (2)
Double (3.14) | Double (3.14)
String ("mystr") | String ("mystr")
Array ((0, 1, 2)) | List ({0 1 2})

JavaScript to Tcl Data Conversions

The transport/conversion of object properties (to e.g. associative array elements) can be arranged manually like this:

> ``var a = new Object();
> a.b = 3.14;
> tclset("a(b)", a.b);``

### Complete Examples

This section contains two complete examples for Script objects written in JavaScript.

For the first example use Script object type `"Modify"` and put a Sphere as child object of the Script object.

    /* Ayam, use: JavaScript */
    tclvar("SphereAttrData");
    getProp();
    if(SphereAttrData)
    {
      tclset("SphereAttrData(ZMin)", -SphereAttrData.Radius);
      tclset("SphereAttrData(ZMax)", SphereAttrData.Radius);
      setProp();
    }

The above script will make sure, that the ZMin and ZMax parameters of the Sphere object always match its radius.

First, a link from the original Sphere object property data array `"SphereAttrData"` is established, so that when `"getProp()"` (a converted Tcl Ayam command) is called, also the JavaScript object `"SphereAttrData"` is filled with meaningful data. The next line (the if) is a safety measure that prevents the script from failing if the child object of the Script object is not a Sphere object. Now the radius value is transferred back to Tcl directly into the property data array to the ZMin and ZMax entries respectively with the help of `"tclset"`. Finally the modified property is transferred back to the Sphere object again with a converted Tcl Ayam command `"setProp()"`.

The next example shows, how to manage a property GUI in a JavaScript implemented Script object script. Use Script object type `"Create"` and add a tag `"NP MyProp"` to see the property GUI.

    /* Ayam, use: JavaScript, save array: MyPropData */
    var MyPropData = new Object();
    if(!tcleval("info exists MyPropData;"))
    {
      /* initial script run (but not when loaded from scene file!) */
      MyPropData.MyItem = tcleval("set MyPropData(MyItem) 1.0;");
      tcleval("set MyPropData(SP) {MyItem};");
    }
    else
    {
      /* all following script runs (and also when loaded from scene file!) */
      MyPropData.MyItem = tcleval("set MyPropData(MyItem);");
    }
    if(!tcleval("info exists MyPropGUI;"))
    {
      tcleval("set ::phw [addPropertyGUI MyProp \"\" \"\"];");
      tcleval("addParam $::phw MyPropData MyItem;");
    }
    crtOb("Sphere");
    sL();
    getProp();
    tclset("SphereAttrData(Radius)", MyPropData.MyItem);
    tclset("SphereAttrData(ZMin)", -MyPropData.MyItem);
    tclset("SphereAttrData(ZMax)", MyPropData.MyItem);
    setProp();

This example demonstrates how to manage property data using the JavaScript object variable `"MyPropData"`. The property data can be saved to and read from Ayam scene files with the help of a mirroring array variable on the Tcl side (also named `"MyPropData"`). To make this work properly, the initialisation of the JavaScript object must be constrained to the first script run: when the property data was read from a scene file, initialisation must not be run, instead the read data must be fetched from the Tcl context. This is what the first `"if"` statement, checking for existence of the mirroring Tcl array variable, in above example is all about.

Following this scheme of dual mirroring data structures on the Tcl and Javascript sides now follows the creation of the property GUI which is also constrained to just one script run by an `"if"` statement.

Following the GUI, a sphere object is created and parameterized according to the data in the property GUI, which is used as radius, zmin, and zmax value.

Next Previous Contents