Next Previous Contents

## 8. Miscellaneous

This section contains all information about Ayam not fitting elsewhere.

## 8.1 The Undo System

Using the undo system, you may correct mistakes you made while modelling. However, only modifications of objects can be undone. This includes changes made by modelling actions, changes made using property GUIs, but also changes to views (type changes or changes to the camera settings associated with a view).

It is currently not possible to undo any changes to the object hierarchy, including clipboard (e.g. cut, paste) and drag and drop operations. If you delete an object, it is gone! If you, accidentally, move an object using drag and drop, undo will not help!

The undo system works by storing copies of the different states of changed objects in an undo buffer. You may step backward through the saved states using `<Ctrl+z>` (undo) but also forward using `<Ctrl+y>` (redo).

The storage space occupied by the undo buffer may be adjusted using the preferences (`"Prefs/Modelling/UndoLevels"`). A value of -1 for `"UndoLevels"` completely disables the undo system. The values 0 and 1 are not allowed. The value 2 means that there is always one state of the scene that can be restored, plus, a potential undo operation can also always be undone using redo.

The changes that would be undone or redone are shown in abbreviated form in the prompt of the Ayam console and, since Ayam 1.14, in the main menu entries `"Edit/Undo"` and `"Edit/Redo"`.

Several actions will completely clear the undo buffer (no undo is possible after those actions): Delete Object, New Scene, Open (Replace) Scene, and Close View.

Note that undo/redo will also modify objects that currently reside in the object clipboard (if they have saved states in the undo buffer). This means that the following sequence of operations leads to a sphere placed at `"0,0,0"`:

    create Sphere (at 0,0,0)
    move Sphere (to 1,1,0)
    cut Sphere (to clipboard)
    undo
    paste Sphere (from clipboard)

## 8.2 The Modelling Concept Tool-Objects

This section introduces the modelling concept Tool-Objects, as used in Ayam.

In a standard modelling application, to create a surface of revolution, one would either first create a curve then call the revolve tool to get an appropriate surface (losing the curve as object, or even keeping it, but without relation to the surface), or call the revolve tool first, which would then require the user to draw a curve with similar results: the created surface will typically lose the relation to the surface of revolution tool and the curve (even if kept intact) will lose the relation to the surface. There is no easy way to change parameters for the surface creation or to change the geometry of the curve later on without doing it all over again.

The modelling concept Tool-Objects overcomes these drawbacks by transforming the revolve tool into a scene object.

The following example hierarchy shows two objects in a parent-child relation:

    +-Tool_Object(Revolve)
     |         ^
     |         :
     |   <Notification>
     |         :
     \ Parameter_Object(NCurve)

The parent object is called Tool-Object and the child object is called Parameter-Object. There is a flow of information from the parameter object to the tool object. This information flow is controlled by the so called Notification mechanism. The notification mechanism makes sure that whenever the parameter objects change, the tool object is informed so that it may adapt to the changes. For interactive modelling actions, the notification will be carried out while dragging the mouse or after release of the mouse button (i.e. after the modelling action finished), depending on the main preference setting `"LazyNotify"`.

In the example above, a NURBS curve is the parameter object and the tool object is creating a surface of revolution from the curve data. The NURBS curve and parameters of the Revolve object may change at any time. When saved to an Ayam scene file, no surface data will be written, leading to very small files that additionally contain a modelling history and capture design intent to a certain degree.

Tool objects may be parameter objects of other tool objects:

    +-Tool_Object(ExtrNP)
     +-Parameter_and_Tool_Object(Revolve)
      \ Parameter_Object(NCurve)

and there may be more than one parameter object per tool object:

    +-Tool_Object(Skin)
     | Parameter_Object_1(NCurve)
     | Parameter_Object_2(NCurve)
     | ...
     \ Parameter_Object_n(NCurve)

Tool objects create new geometric objects from the information delivered by the parameter object(s) or they modify the parameter object(s) and deliver them to their respective parent object.

The pure hierarchical dependency scheme may be broken up by instance objects:

    +-Tool_Object(Revolve)
     \ Parameter_Object(NCurve) --------------
    +-Tool_Object(Revolve)                    | !
     \ Parameter_Object(Instance_of_NCurve) <-

In the scene above, the second Revolve tool object depends on the shape of the first parameter object. The Instance object transports the data from one part of the hierarchy to another. The notification mechanism is aware of this and initiates updates in the scene hierarchy wherever needed and efficiently (not updating any objects twice) according to the `"CompleteNotify"` main preference setting. In the example above, due to complete notification, the second Revolve object will get updated automatically whenever the original NCurve object changes.

Two other mechanisms exist, that help tool objects to get the information they need and to increase flexibility in hierarchy building and modelling: Provision and Conversion. Both mechanisms are quite similar and convert objects temporarily/transparently (provision) or finally (conversion) from one type to another, e.g. they convert an ICurve (interpolating curve) to a plain NCurve (NURBS curve).

Due to the provision mechanism, an ICurve object could be used instead of an NCurve as parameter object in all examples above easily. And with the help of the conversion mechanism, the Revolve tool objects could be converted to plain NPatch objects (e.g. for modelling operations not available to Revolve objects).

Note that instance objects are subject to a second round of provision, i.e. the master does not need to be of the wanted type but rather provide the wanted type.

Even though, theoretically, every tool could be implemented as tool object, this has not been done in Ayam (mainly, because this would unnecessarily increase the code base). Only the most often used tools that convey and capture much design intent were implemented as tool objects (those are surface or curve creating tools). But also seldom used tools can be elevated to nearly full tool object capabilities through the employment of the concept of scripting objects (see section Script Object).

This can be done easily by e.g. creating script objects of type `"Modify"` that call those tools from their script (after possible conversion of the provided object(s) to a proper type, the tool may need to operate on). Even property GUIs to let the user adjust tool parameters as they know it from the other Ayam objects can be added and different tools can be combined in single objects with normal script code for unmatched flexibility. But let us see a simple example first:

    +-Skin
     +-Script
      \ ExtrNC

In the scene hierarchy above, the script object could be simply reverting the extracted curve with code like this:

    convOb -inplace; revertC

effectively elevating the tool `"revertC"` to an object.

A more useful example can be found in the Marsrakete sample scene (as available from the Ayam home page). Here, a curve extracted from a patch is trimmed to the right length using a script like this:

    convOb -inplace; trimNC 0.0 0.5

. See section Script Object Example for information on how this script might be expanded to support a GUI and more error checking.

## 8.3 Scene File Management

This section contains information on what exactly happens, when Ayam reads or writes a scene file.

### Opening Scene Files

When reading a scene using `"File/Open"` or the MRU list:

1. Ayam will first check the scene changed status of the currently loaded scene and warn the user, if the current scene contains unsaved changes,
2. then Ayam will clear the undo buffer and the current scene (the clipboard content is not touched, except for instance objects, whose masters are cleared with the scene: those instance objects will be deleted from the clipboard),
3. if the new file appears to be an Ayam scene file (judged solely by the file name extension) Ayam will change the working directory to the path of the scene file (otherwise, Ayam will try to import the file using an import plugin responsible for the file),
4. now, a backup copy of the file to read will be made (depending on the preference setting `"Main/BakOnReplace"`), note: even if the backup fails, scene reading continues,
5. the header of the scene file will be read to derive the scene file format version,
6. the file will be read with all objects,
7. all instances will be connected to their masters using the information stored in `"OI"` tags, if a master can not be found in the scene, the instance will be removed,
8. all objects will be connected to their materials using the information stored in `"MI"` tags, if no matching material can be found, the connection will not be established,
9. a complete notification will be run,
10. if the file contains a root object with `"SaveMainGeom"` and/or `"SavePaneLayout"` tags, the respective window/widget geometries from the tags will be re-established,
11. if no errors occurred during reading, the current scene name will be set to that of the file, otherwise the current scene name will be reset to "unnamed",
12. the file name will be put to the first most recently used files entry in the file menu,
13. the scene changed state will be reset to "unchanged",
14. if a root object was read, a save views flag will be set, otherwise it will be cleared and following save operations will not save the root and any views (i.e. scene files without root and views stay scene files without root and views).

When reading objects from a file:

1. if a view object is read, a new view window will be opened (except for the first three view objects in single window GUI mode, where only the configuration of the view objects read will be copied to the already existing view objects of the three internal views),
2. if one object is of a currently undefined type (i.e. defined by a plugin), Ayam will derive a potential plugin name from the object type name and load the plugin, then scene reading continues,
3. if loading of an object fails, Ayam continues to read from the file.

### Inserting Scene Files

In contrast to reading scenes via `"File/Open"` or the MRU list, reading scenes via `"File/Insert"` does some things differently:

1. the current scene will not be cleared,
2. the current level will not be reset before reading the file; if the scene file to be inserted contains no root and no views, the new objects will be created in the current level, otherwise the objects will be created in the topmost level of the scene, which will also be the new current level in any case (after reading),
3. if a material is missing from the file, and a matching (by name) material exists in the scene, the objects will be connected to this material,
4. view windows will be opened for every view object,
5. the current directory will only be changed during the file read operation,
6. if a material object is read, Ayam will immediately register it; if this registration fails (because there is already a material with that name registered), objects from the file will not be be linked to the material object from the file, but to the material object that was already registered before,
7. the current file name will not be changed,
8. the scene changed state will be set to "changed",
9. the save views flag will not be changed, this means that inserting a scene file without views into an empty scene (e.g. directly after application startup or after `"File/New"`) and then saving the scene, will enrich the scene file with root and views (in contrast to loading this scene via `"File/Open"`).

### Saving Scene Files

When saving a scene using `"File/Save"`:

1. Ayam will first check the current scene file name, if the name is "unnamed", a new file name will be requested,
2. if the file appears not to be an Ayam scene file (judged solely by the file name extension) Ayam will try to export the current scene using an export plugin responsible for the file type instead of saving to an Ayam scene file,
3. the geometry of the main window and internal widgets is saved to `"SaveMainGeom"` and/or `"SavePaneLayout"` tags (if present),
4. `"OI"` tags and `"MI"` tags will be created to allow instances to be connected to their respective masters and objects to their materials, when reading the scene file,
5. then, all objects from the scene will be saved to the file, if the save views flag is not set, root and views will be omitted,
6. if no errors occured during saving the file, the file name will be put to the first most recently used files entry in the file menu, and the scene changed state will be set to "unchanged",
7. if errors occured, the current scene changed state will be kept.

## 8.4 Ayamrc File

To customize Ayam the ayamrc file may be used. This file is either pointed to by the environment variable `AYAMRC` or is determined as following:

- On Unix it is `"~/.ayamrc"`, where `"~"` denotes the home directory of the current user.
- On the Win32 platform (Windows95 - XP) it is `"$(HOME)/ayamrc"` if the environment variable `HOME` exists, else `"$(TEMP)/ayamrc"`.
- On Mac OS X Aqua (not X11!) it is `"~/Library/Preferences/.ayamrc"`, where `"~"` denotes the home directory of the current user.
- On Mac OS X X11 (not Aqua!) it is `"~/.ayamrc"`, where `"~"` denotes the home directory of the current user.

The ayamrc file is read on each start of Ayam and saved again on exit (if the preference setting `"Main/AutoSavePrefs"` is enabled).

The ayamrc file contains:

1. preference settings (including some hidden settings that require just occasional tweaking and are not reachable using the GUI preference editor)
2. position and size of the main window and the toolbox window
3. keyboard shortcuts to menu entries and modelling actions
4. RiOption and RiAttribute databases

You may edit the file with any text editor (while Ayam is not running), but keep in mind, that the file will be parsed by Tcl. Should you, for some reason, destroy your ayamrc file so that Ayam does not start correctly anymore you can always start Ayam with the command line option `"-failsafe"`. When the application is left the next time, or the main menu entry `"File/Save Prefs"` is invoked, a correct ayamrc file will be created again. All preference settings will be reset to factory defaults and all your edits will be lost, however!

Another way to reset the ayamrc file is to simply delete the file manually or using the main menu entry `"Special/Reset Preferences"`.

To reset single elements to factory defaults, just remove the corresponding lines from the ayamrc file.

Finally, resetting single preference settings without a text editor is also possible with the help of the scripting interface by manipulating the global `"ayprefs"` array. The following example leads to a reset of the tolerance preference setting to the factory default for the next start of Ayam.

    unset ayprefs(Tolerance)

### Changing Keyboard Shortcuts

You may adapt the keyboard shortcuts used in the GUI to your special needs using the ayamrc file. Note that if you do that, the GUI (the menu entries and the `"Show Shortcuts"` window) will adapt to your changes but certainly neither this documentation, nor the reference card (unless recreated using refcard.tcl), nor the tutorials!

Ayam does not check for clashes in key bindings! This means, the last set binding for a key will be used.

On Unix, the output of the program `"xev"` and the manual page for the `"bind"` command of Tk provide helpful information about which strings may be used to describe key presses. You can also directly use the Ayam console to infer key names, just enter:

    toplevel .keytest
    bind .keytest <Key> {puts %K}

into the Ayam console. Now you can activate the new top level window and type on your keyboard while the Ayam console prints the names of the keys.

For your convenience, the special string `"Ctrl"` will be replaced by `"Control"` before a shortcut is handed to the `bind` command.

Example:

    set aymainshortcuts(Prefs) {Ctrl-p}

sets the keyboard shortcut for opening of the preferences editor to `<Ctrl+p>`. See the ayamrc file itself for a complete listing of available shortcuts.

### Hidden Preference Settings

The ayamrc file currently contains the following adjustable hidden preference settings:

- `"Balloon"`: time in ms until the tooltip window appears (default: 1500 - 1.5s)
- `"EFlush"`: time in ms between two flushes of the error message buffer (default: 2000 - 2s)
- `"toolBoxList"`: a list of sections or groups of buttons describing the appearance of the toolbox window (default, using all available sections: `{trafo trafo2 solids misco nurbs toolobjs points nctools1 nctools2 camera misc}`)
- `"Kill"`: name of a program that kills other processes and accepts a process id as argument (used by the Rendering GUI) (default: `"kill"`) (a setting of `"kill"` will be automatically replaced by `"kill.exe"` on Win32) On the Win32 platform you may also use an internal kill command `"w32kill"` that has been introduced in Ayam 1.4.
- `"Cat"`: name of a program that can read from and write to a pipe (used by the Rendering GUI) (default: `"cat"`) (a setting of `"cat"` will be automatically replaced by `"cat.exe"` on Win32)
- `"KeepNTmpFiles"`: how many incarnations of the scene in RIB form (which actually may be split in more than one file due to e.g. instances) created when directly rendering from a view window should be kept on disk (default: 5)
- `"WarnPropPasteToSel"`: should `"Special/Clipboard/Paste Property to Selected"` raise a warning requester? (default: 1 - yes)
- `"WarnUnknownTag"` controls the warning messages for unknown tag types. (default: 1 - yes)
- `"DailyTips"`: a list of strings that appear as tips on startup in the console (default: large)
- `"PickTolerance"`: the tolerance used to determine whether an object should be picked or not (default: 5); this setting determines the size of a rectangular area around the picked point in pixels, all objects that are inside or touch this area are considered picked
- `"MaxTagLen"`: the maximum number of characters to be displayed in the buttons in the Tag Property GUI (default: 30)
- `"Wait"`: set this to `"waitPid"` if you want to enable the work around for zombie processes created by the Rendering GUI. This is e.g. necessary for the Linux platform.
- `"Prompt"`: controls the prompt for the Ayam console. If set to an empty string, a default of

      \[Undo:$ay(undoo)/Redo:$ay(redoo)\].../[file tail [pwd]]>

  will be used, which displays the name of the operations that you can undo and redo and the last component of the current directory of Ayam like this `"[Undo:None/Redo:None].../scn>"`. You may e.g. change this to `"[pwd]>"` to see just the full path name of the current directory. If you want to display the value of a variable in the prompt (e.g. designating the current level in the scene hierarchy) you need to bind a write-trace to that variable. The write trace in turn must call the procedure `"ayam_updateprompt"` and may e.g. be established using a small script like this: `"trace variable <vname> ayam_updateprompt"`.
- `"BackupExt"`: is the file name extension to be used for backup files. Default values are `"~"` for Unix and `".bak"` for Win32.
- `"SelXOR_R"`, `"SelXOR_G"`, `"SelXOR_B"`: determine a color value that is used for drag selection rectangles. Note that the color is not used directly but combined with the color value of already drawn pixels by XOR. The default values are 255 for the red, 128 for the green, and 0 for the blue component.
- `"IconGamma"`: this setting may be used to adapt the contrast of all icons (in view menu and the toolbox) to your display gamma. If you are on a SGI it is recommended to set this to about "0.7". The default value `""` (empty string) leads to no changes of any icon images.
- `"AddViewParams"` allows to add custom parameters to the view OpenGL widget creation, like e.g. `"-stereo true"`. The default value is `""` (empty string).
- `"AskScriptDisable"` controls the warning dialog that appears if scenes with script objects or tags are loaded. The default value is 1 - yes, warn about script objects and tags.
- `"FixX11Menu"` enables a workaround for non-sticky menus on X11 (displaced menus do not stay open). This option is enabled by default and not used on the Win32 and Aqua platforms.
- `"FixDialogTitles"`, this option prepends the title of a message box that is normally displayed in the window frame of the message box to the message in the box. This may be necessary because on some systems the title string might be displayed in an unreadable font or not at all. On Mac OS X Aqua (not X11!) this option is enabled by default. On all other systems this option is disabled by default.
- `"FixImageButtons"`, enables a workaround for buttons (e.g. in the toolbox) that stay depressed when used. This option is disabled by default on all platforms.
- `"SafeAutoFocus"` disables AutoFocus (see section preference settings) when certain dialog windows are open, so that they do not get shuffled under other windows by accidental mouse movements on systems where the window manager does only auto raise in conjunction with auto focus. This option is enabled by default on Win32.
- `"UseInternalFD"` switches to an internal file dialog for loading of plugins. This option is only used on MacOSX/Aqua (not X11!), because there the normal file dialog will not enter application bundle directory structures. This option is enabled by default on MacOSX/Aqua and not used on any other platform.
- `"SwapMB"`, `"SwapMBSC"` allow to swap mouse buttons 2 and 3 on MacOSX/Aqua (not X11!) for specified mouse bindings (`"SwapMBSC"`), because on MacOSX/Aqua, traditionally, the naming of the middle and rightmost mouse button is reversed compared to X11/Win32. This option is enabled by default on MacOSX/Aqua and allows to use the same set of mouse bindings (the same ayamrc file) for X11 and Aqua without sacrificing user experience. The middle mouse button, by default, zooms the view, and the right one moves the view.
- `"CursorEnd"`, if switched on, the first click into the console will move the cursor to the input prompt, ready for command input, instead of moving the cursor to the point of the click. This option is enabled by default.
- `"LineWidth"`, line width used for drawing the lines of unselected objects (blue lines in standard color configuration). The default value is 1.0. Ayam is not checking, whether the specified value is supported by the OpenGL implementation used.
- `"SelLineWidth"`, line width used for drawing the lines of selected objects (white lines in standard color configuration). The default value is 1.0. Ayam is not checking, whether the specified value is supported by the OpenGL implementation used.
- `"ALFileTypes"`, `"ALPlugins"` two lists that describe file name extensions and corresponding plugins that import and export files of the type designated by the file name extensions.
- `"AUCommands"`, commands that will be run in the console when `<Shift+Return>` is used instead of `<Return>`. See also section Updating the GUI. The default value is `"uS;rV;"`, leading to a complete update of the object hierarchy, the property GUI and all view windows.
- `"PolyOffset0"`, `"PolyOffset1"` two float values, that control the offsetting of shaded surfaces in the shade and draw drawing mode (so that the curves always appear on top of the surfaces). Default values are 1.0, 1.0.
- `"WheelZoom"`, a float value that controls the zoom factor, for the mouse wheel; default value is 0.5.
- `"ShiftTab"`, allows to set a specific keyboard symbol for systems where pressing the Shift together with the Tab key does not produce "<Shift-Tab>" (the default) but some other symbol like e.g. "<ISO_Left_Tab>" (many, but not all, modern X11 systems often use this).
- `"ListTypes"` determines, whether the type of an object should be displayed in braces in the tree view or listbox. The default value is 1 - yes, list the types.
- `"MarkHidden"` determines, whether hidden objects should be marked (using a preceding exclamation mark) in the tree view or object listbox. The default value is 1 - yes, mark hidden objects.
- `"LoadEnv"`, if this is switched on, Ayam will load the scene file specified by `"EnvFile"` on startup. The default value is 1 - yes, load the environment file on startup.
- `"NewLoadsEnv"`, if this is switched on, Ayam will load the scene file specified by `"EnvFile"` also when the scene is cleared using the main menu entry `"File/New"`. The default value is 1 - yes, load the environment file on `"File/New"`.
- `"ToolBoxShrink"`, controls whether the toolbox window should shrink wrap around its contents after a resize operation. This option is not used in single window GUI mode. Default is 1 - yes.
- `"ToolBoxTrans"`, decides if the toolbox window should be made transient. It will then, depending on the window manager or its configuration, get a different or no decoration, no icon (or no entry in the task bar on Windows), and will always be iconified when the main window gets iconified. Not used in single window GUI mode. The default value is 1 - yes.
- `"PaneMargins"`, is a list of currently five floating point values, used as a safety margin for the panes: console vs. hierarchy, hierarchy vs. upper-views, lower-view vs. property, property vs. hierarchy, upper-view-2 vs. upper-view-1 (in this order!). These values control the minimum size of a pane expressed in an inverse (1/x) and relative way: the smaller the number, the bigger the margin. The safety margin of the uppermost horizontal pane (that divides the upper internal views from the hierarchy and the third view) is e.g. a bit larger so that the main menu may not be obscured easily (the corresponding value is 5.0). The default value for the console (20.0) leads to a small margin, so that the console may be shrunk to 2 or even 1 lines. The default values are

      {20.0 5.0 10.0 10.0 10.0}

- `"PVTexCoordName"`, default name for texture coordinate PV tags, the default value is "st".
- `"PVNormalName"`, default name for vertex normal PV tags, the default value is "N".
- `"PVColorName"`, default name for vertex color PV tags, the default value is "Cs".

### RiOption and RiAttributes Database

Using your ayamrc file, you may also adapt the database of RiOptions and RiAttributes to your rendering system.

You can then easily add those options and attributes to your scenes using tags and the main menu entries `"Special/Tags/Add RiOption"` and `"Special/Tags/Add RiAttribute"`, see also sections RiAttribute Tag and RiOption Tag.

The syntax for a new RiOption is quite simple as the following example shows:

    set riopt(runtime) { { verbosity s { "silent" "normal" "stats" "debug" } } }

This snippet sets the section `"runtime"` and adds a single option, `"verbosity"`, to it. The option is declared to be of type string using `"s"` and provided with a list of default values: `"{ "silent" "normal" "stats" "debug" }"`.

To add another option to this section, say the option `"op"` which shall be an integer value you have to change the aforementioned snippet to:

    set riopt(runtime) { { verbosity s { "silent" "normal" "stats" "debug"} }
     { op i }
    }

As you can see, it is not mandatory to provide default values. Be sure to correctly close all the curly braces, otherwise the next start of Ayam may fail!

Available types of parameters are:

- i: a scalar integer value
- j: a pair of integer values
- f: a scalar float value
- g: a pair of float values
- s: a string value
- p: a point in space (simply three float values), the default values (if provided) are three float values in curly braces, such as `{{0.0 0.0 0.0}{1.0 1.0 1.0}}`
- c: a color, the default values (if provided) are three float values in curly braces, such as `{{0.0 0.0 0.0}{1.0 1.0 1.0}}`

## 8.5 Environment Variables

This section documents the environment variables used by Ayam.

- `"AYAMRC"`: designates the full filename of the ayamrc file.
- `"HOME"`: path to the ayamrc file (used on Win32 if `"AYAMRC"` is not set).
- `"TEMP"`: path to the ayamrc file (used on Win32 if `"AYAMRC"` and `"HOME"` are not set); also initial value of the `"TmpDir"` preference setting (used on Win32 if no ayamrc file exists, that specifies `"TmpDir"`).
- `"AYNOSPLASH"`: if this variable is set to 1, the splash screen will not be shown
- `"BROWSER"`: filename of the preferred WWW browser (used to display the documentation URL)
- `"NETSCAPE"`: (if `"BROWSER"` does not exist) filename of the Netscape WWW browser (used to display the documentation URL)
- `"SHADERS"`: initial value of `"Shaders"` preference setting (used if no ayamrc file exists).

## 8.6 Plugins Overview

This section serves as a overview of the various plugins available in Ayam.

There are currently three major types of plugins for Ayam: shader parsing plugins, custom objects, and import/export plugins. See sections Shader Parsing Plugins, Custom Objects, and Import and Export for more information regarding the respective plugin types.

Furthermore, there are the following specific plugins:

- jsinterp – JavaScript scripting interface (see section JavaScript Scripting Interface),
- AyCSG – CSG rendering (see section CSG preview using the AyCSG plugin),
- IDR – Importance Driven Rendering (see section Importance Driven Rendering),
- aydnd – inter-application drag and drop.

## 8.7 Shader Parsing Plugins

Since Ayam 1.3, the following plugins are provided to allow parsing of shaders: `"ayslb"` for Air, `"ayslx"` for Aqsis, `"ayso"` for RDC, `"ayslo"` for PRMan, `"ayslo3d"` for 3Delight, (since Ayam 1.6) `"aysdr"` for Pixie, and (since Ayam 1.11) `"aygso"` for Gelato.

After loading of one of the aforementioned plugins, Ayam will be able to parse shaders compiled with the shader compiler of the respective renderer.

There can only be one active shader parsing plugin. You can not first load ayslb and then ayslx and expect Ayam to parse slb and slx shaders.

A shader parsing plugin may be loaded automatically on startup of Ayam using one of the provided Tcl scripts: `"loadayslb.tcl"`, `"loadayslo.tcl"`, `"loadayslo3d.tcl"`, `"loadayslx.tcl"`, `"loadayso.tcl"`, `"loadaysdr.tcl"`, and `"loadaygso.tcl"`. To automatically load a plugin simply add the appropriate script to the preference setting `"Main/Scripts"` using the `"Add"` button in the preferences editor.

Additionally, those scripts may be further adapted to set a different `"Shaders"` preference setting or to immediately scan for shaders after loading of the plugin. For that, just remove the leading hash-marks (#) from the corresponding lines in the script. Note that changing the scripts for immediate shader parsing is not necessary if you load the shader parsing plugin automatically on startup of Ayam, as the loading of the scripts will happen before the Ayam startup sequence executes the initial shader scanning pass. The shader search path used for the initial shader scanning pass is taken from the `"Shaders"` preference setting.

If you load a shader parsing plugin manually or via unchanged load script you need to adapt the shaders search path manually and also initiate a shader scan manually. Both actions may be carried out using the preferences editor. Scanning for shaders may also be started using the main menu: `"Special/Scan Shaders"`.

To better accommodate the fast changing world of RenderMan renderers, since Ayam 1.11 all shader parsing plugins are Ayam version independent (but still renderer version dependent and Tcl version dependent). This allows to distribute updated shader parsing plugins without updating Ayam too and thus in a higher frequency. Furthermore, compiling a shader parsing plugin is now much easier.

## 8.8 Automatic Instancing

Automatic Instancing is available via the main menu entry: `"Special/Instances/Automatic Instancing"`. Automatic Instancing creates instances from all instantiable objects, using a simple algorithm that recursively compares objects. The comparison of materials and tags may be turned off in the small dialog that pops up after selection of the menu entry `"Special/Instances/Automatic Instancing"`.

The algorithm is able to create instances of grouping objects too (objects with child objects, e.g. levels or tool-objects like revolve). However, in order for two grouping objects to be instantiated not only all child objects and the grouping objects have to be instantiable, but the child objects also have to be in the right order. It is not sufficient, that for every child of the potential master, a matching child of the potential instance exists. Instantiation of grouping objects may drastically decrease the total number of objects in a scene.

Note that before the automatic instantiation starts, all currently existing instances will be resolved! After instantiation some statistics will be displayed in the console.

Since Ayam 1.14, the instantiation obeys the object selection: instances are only created from the selected objects. If no objects are selected, instances are created from all objects in the current level and below.

More information about this subject can be found in:

Schultz, R., and Schumann, H.: "Automatic Instancing of Hierarchically Organized Objects", in: Kunii T.L. (ed.): Spring Conference on Computer Graphics (SCCG 2001) Conference Proceedings, Budmerice, Slovakia, 25-28 April 2001, ISBN 80-223-1606-7

## 8.9 Importance Driven Rendering (IDR)

The importance driven rendering plugin may be used to drastically reduce rendering times while developing a scene. It works in three main steps:

1. Importance values are assigned to elements of the scene.
2. Two rendering passes are started according to the assigned importance values. Elements of different importance values are mutually masked out using `"RiMatte"` statements.
3. The resulting partial images are composed to a single resulting image, which is then displayed.

The parameterisation of the two rendering passes ensures, that the total rendering time is lower than the rendering time of a single pass with high quality.

Many options exist to assign importance and parameterise the rendering passes:

Elements of the scenes may be geometric objects, regions in image space, or regions in object space. Importance values are currently just binary values. Assignment may take place manually (using IDR tags) or half-automatic by derivation of importance from currently selected or changed objects. To avoid inconsistency in the resulting images, importance values may be propagated between (geometrically or hierarchically) near objects, or between objects that are related (e.g. from a material to a geometric object).

Parameterisation of the two rendering passes currently includes selection of a different renderer and the possibility to reduce rendering resolution and shading rate. To further reduce rendering times for raytracing renderers, the size of the region to render may be automatically adapted to the elements of the current importance value (including an optimisation run that balances renderer startup times and times needed to render regions not originally occupied by two regions to merge).

Furthermore, caching of partial images is possible. However, the implementation of this feature is not very sophisticated at the moment, as it uses the Unix text tool `"diff"` to decide whether two RIB streams are identical and hence need no re-rendering.

To start using IDR:

1. load a scene (e.g. the cactus example scene),
2. load the IDR plugin (menu `"File/Load Plugin"`),
3. open the IDR control window using the main menu `"Custom/Open IDR"`,
4. set the assign mode to `"Selection"`,
5. select an object in the scene (e.g. the object named `"Pot"`),
6. then press the `"Render!"` button.

Compare the rendering time with a full render from the view window.

IDR requires that atleast the renderer of the second rendering pass honours RiMatte! Since rgl does not honour RiMatte, it is sometimes necessary to simply exclude objects of different importance value. No wrong images are to be expected from this, as rgl does not calculate other than local lighting effects.

More information about this subject can be found in:

Schultz, R., and Schumann, H.: "Importance Driven Rendering - Using Importance Information in the Rendering Process", in: Hamza M., Sarfraz M. (ed.): Computer Graphics and Imaging (CGIM 2001) Conference Proceedings, Honolulu, Hawaii, 13-16 August 2001, ISBN 0-88986-303-2

## 8.10 CSG preview using the AyCSG plugin

CSG preview example (left without, right with CSG)

The AyCSG plugin may be used to resolve and preview CSG operations. For this, the plugin uses image based CSG rendering algorithms provided by the OpenCSG library by Florian Kirsch. The OpenCSG library, currently, supports the Goldfeather and the SCS algorithm. The latter only works properly with convex primitives. Since both, Goldfeather and SCS, are image based rendering algorithms, there is no limit in geometric object types that may be used in CSG hierarchies. You may e.g. use Quadrics, NURBS, and Metaballs in every possible combination. You just have to make sure, that every CSG primitive describes a closed space.

In order for the CSG rendering algorithms to work properly, the depth complexity (convexity) of a primitive must be known. The depth complexity of a primitive determines the maximum number of forward oriented surfaces any ray through this primitive would pass. A regular sphere has a depth complexity of 1, a torus of 2, but do not confuse depth complexity with genus, they are different values! A 3D representation of the letter A e.g. has a genus of 1 but a depth complexity of 3. The depth complexity of a primitive can be stored in a `"DC"` tag. A torus would e.g. get a tag named `"DC"` with the value `"2"`. If no `"DC"` tag is present for a primitive, a default value for the depth complexity of `"1"` will be used. If you fail to correctly specify the depth complexity, rendering errors, like missing parts of surfaces, will occur.

Note that the correct operation of AyCSG not only depends on the depth complexity but also the winding order of the OpenGL primitives (triangles or quads) used for drawing of the CSG primitives. The winding order has to be consistent in a scene, so that the rendering algorithm can decide what is inside and what is outside by looking at a single OpenGL primitive. For all quadric primitives of Ayam the winding order is always consistent. However, for NURBS patches the winding order depends on the orientation of the patch dimensions. If NURBS patches are used in CSG operations you, consequently, may need to revert the patches (e.g. using the `"RevertU"` tool, see Revert U tool). If the winding order of some of the primitives in a CSG hierarchy is not right, the respective primitives will not be effective in the CSG operations to the extent that the rendered image becomes completely empty.

The AyCSG rendering obeys the `"Draw Selection only"` and `"Draw Level only"` view options as well as the hide attribute of objects. If the CSG rendering fails for complete complex scenes, you might still get a preview of the important CSG using objects by selecting them and enabling the `"Draw Selection only"` view option.

Also note that CSG rendering requires fast graphics hardware (the more fillrate, the better). Furthermore, your OpenGL subsystem has to support the PBuffers extension and, depending on the rendering options chosen, a stencil buffer. Speedups may be achieved using the `"GL_ARB_occlusion_query"` or `"GL_NV_occlusion_query"` extensions (if available to you).

Once the AyCSG plugin is loaded successfully you can render the CSG preview in any view window using the keyboard shortcut `<Ctrl+Shift+c>` or using the new button in the menu bar of every view window. If you hold down `<Shift>` while pressing the button the view will continually render CSG (the button stays pressed to signify this) until you click onto the button again.

The AyCSG plugin supports the following options, that are available through the main menu entry `"Custom/AyCSG Preferences"`:

- `"Algorithm"` allows to switch between the Goldfeather and SCS algorithm. Note again that the SCS algorithm only works correctly for convex primitives. The `"Automatic"` setting chooses one of the algorithms based on whether concave primitives (depth complexity > 1) are present or not.
- `"DCSampling"` determines a depth complexity sampling strategy. Quoting from the OpenCSG documentation, the following options are available:

  `"NoDCSampling"`: Does not employ the depth complexity. This essentially makes the algorithm O(n^2), but with low constant costs. This is the standard Goldfeather algorithm, DC tags must be present for primitives with a depth complexity greater than one, or rendering errors may occur.

  `"OcclusionQuery"`: Uses occlusion queries to profit implicitly from depth complexity without calculating it. This is especially useful for the SCS algorithm where this strategy is applied at shape level, resulting in a O(n*k') algorithm (where k' <= k), without significant constant overhead. This strategy requires hardware occlusion queries, i.e., the OpenGL extension `"GL_ARB_occlusion_query"` or `"GL_NV_occlusion_query"`. If this is enabled (and the `"Algorithm"` is set to Goldfeather), DC tags need not to be present.

  `"DCSampling"`: Calculates the depth complexity k using the stencil buffer. This makes the algorithm O(n*k), but with high constant costs. In case of the Goldfeather algorithm, the literature denotes this as layered Goldfeather algorithm. Note that this option requires a stencil buffer which must be enabled on the creation of a view window using additional view parameters (preferences option AddViewParams, see also the section on hidden preference settings). If stencil buffers are not enabled, Ayam will automatically add the relevant option to the preferences but this only has an effect on newly created view windows (i.e. you might also want to restart Ayam, if you switch to DCSampling). If `"DCSampling"` is enabled (and the `"Algorithm"` is set to Goldfeather), DC tags need not to be present as the depth complexity of primitives is calculated internally.

- `"OffscreenType"`: This option allows to switch between two offscreen rendering techniques, PBuffers and Frame Buffer Objects; depending on your graphics hardware and driver, one or the other might work better for you.
- `"Optimization"`: Currently unused.
- `"CalcBBS"` determines whether bounding boxes should be calculated and used for speed up (not working at the moment).

See also: Kirsch F. and Doellner J.: "Rendering Techniques for Hardware-Accelerated Image-Based CSG", in: Skala V. (ed.): Journal of WSCG'04, 221-228, ISSN 1213-6972

## 8.11 Increasing drawing speed

In case of sluggish response of the user interface of Ayam (not accounting for long tree update operations) several things to increase drawing speed can be done:

- Hide objects or complete object hierarchies using `"Hide"` in the `"Tools"` menu.
- Disable drawing of true NURBS curves/surfaces, if you can. Use the ControlHull display modes.
- If you need to see curves/surfaces, try to increase the (GLU) sampling tolerance of the objects (use a value of about 60.0).
- Switch the primary modelling view to draw just the selected object(s) or the current level.
- Iconify views you do not need, they will not be redrawn then.
- Switch off automatic redrawing of slow redrawing (e.g. shaded) views, and control their redraw by pressing `<Ctrl+d>` manually.
- Do not create unnecessary caps, they are trimmed NURBS patches that render very slowly.
- Disable `"UseMatColor"`.

## 8.12 Modelling Without Views

To work with very large/complex scenes, it may be necessary to turn off all views. In Ayam one can do this in the multi window GUI mode (see section GUI preference settings). If there are many objects, it is also advisable to switch the object selection widget from tree view mode to list box mode (menu: `"Special/Toggle TreeView"`.

Modelling without views does not work on Apple MacOSX (Aqua) if GLU functionality is involved (as every GLU functionality on MacOSX needs a GL context). GLU is needed for the PolyMesh and NURBS tesselation.

## 8.13 Restrictions and Implementation Deficiencies

Due to the way Ayam is implemented, several restrictions and deficiencies exist:

- Almost all strings in Ayam (scene file names, object names, material names) are restricted to be 7-bit ASCII. If the scene is not to be transported between platforms (e.g. between UNIX and Win32), using 8-bit ASCII should be fine, however.
- The maximum scene depth (i.e. the maximum number of nested levels) depends on the maximum stack size of the operating system Ayam is running on (due to the use of recursion almost everywhere when traversing the scene, e.g. for drawing purposes).
- Ayam internally operates on double precision math, however, no control over roundoff error in lengthy calculations exists. Saving of scene files only uses the precision dictated by the current standard C library. This may degrade the precision of the models. The usage of double precision numbers via the Tcl scripting interface or the GUI also can reduce model precision due to double-string-double-conversions (the precision of those conversion operations can be adjusted by the user via the `"TclPrecision"` preference setting, however).
- Ayam is currently not portable to 64-bit platforms.
- Materials may only be assigned to complete objects, not to certain parts of objects.
- Undo/Redo are not possible for scene structure changes.
- In the user interface, colors are always represented as three 8-bit RGB values, even though the RenderMan interface allows for different color sample numbers and floating point samples instead of integers to be used.
- There are no acceleration structures for e.g. drawing and object tree updates. This limits the number of objects that Ayam can handle simultaneously without big lags in redraws or after scene structure changes to about 1000. However, Ayam objects should be high-level objects, not single polygons, anyway, i.e. one usually gets away with about 100 objects for moderately complex scenes, the Marsrakete uses just 62 objects.

Ayam user interface deficiencies:

- The application state is often communicated via window title strings only. But certain window systems do not display those titles well, and they are not to be seen in the single window GUI mode at all.

## 8.14 How to join the fun

Helping to make Ayam even better will spice up your life too! Here is how to do it:

1. Write/translate tutorials.
2. Create and submit example objects, scenes, and images.
3. Implement custom objects like trees, landscape, sky, XSplines, T-Splines, or whatever you can think of. Note that the license of Ayam does not prevent you from implementing your custom object as shareware or even commercial software. However, free software is preferred for obvious reasons.
4. Donate source to improve several critical parts of the modeler, some ideas are: better (more exact) lighting simulation (is this possible to do with OpenGL at all?), transformation widgets, true support for subdivision surfaces, lift some deficiencies (see above), import/export plugins. The project page of Ayam on SourceForge lists some more tasks and you are always welcome to discuss such matters in the public forum or in the feature request tracker.
5. Donate money by registering ShellyLib. ShellyLibs source will be converted to a first high level custom object that creates objects of type seashell for Ayam. This object, however, will be Shareware!

Please do not implement custom objects like simple triangles or polygons. This would be something that really is not intended by the Ayam Team, and it would surely show the limits of the current design of all code operating on the scene structure.

Ayam objects should be high-level objects!

Reading the last paragraph you might think that we are a bit biased against polygonal models. We are not. Polygonal models are the only way to preview complex geometry using hardware accelerated graphics, for the moment. But even while RenderMan supports rendering of polygonal models, their use as a primitive is not recommended for good reasons. In other words, use polygonal models in the modeler as quick representation of your higher level objects, but please, if you are going to actually render something, do not use that polygonal representation. If you want to go a complete polygonal way instead, voila, there are good modelers out there.

## 8.15 References

Suggested reading:

- Advanced RenderMan: Creating CGI for Motion Pictures by Tony Apodaca and Larry Gritz (Morgan-Kaufmann, 1999)
- The RenderMan Companion: A Programmer's Guide to Realistic Computer Graphics by Steve Upstill (Addison-Wesley, 1989)
- Textures and Modelling: A Procedural Approach by Ebert, Musgrave, Peachey, Perlin, and Worley (Academic Press, 1994)

WWW resources:

- If you are reading this document from a local file system, maybe an updated version is available from the internet: `http://www.ayam3d.org/docs/ayam.html`
- Ayam Tutorial #1: `http://www.ayam3d.org/tut1/tutorial1.html`
- The Ayam FAQ: `http://www.ayam3d.org/faq.html`
- The RenderMan Repository: `http://www.renderman.org/`
- The RenderMan Academy: `http://www.rendermanacademy.com/`
- George W. Hart, Virtual Polyhedra
  `http://www.georgehart.com/virtual-polyhedra/conway_notation.html`

## 8.16 Acknowledgements

First of all, I would like to express a big "Thank you!" to Bernd (Pink) Sieker. He is the first real Mops user and beta tester, who urged me during the last years via E-Mail and on IRC to fix this particular bug, add some essential features, move the lights again etc. pp. in countless iterations. Bernd, without your help I surely would not be that far, thanks!

Furthermore, I would like to thank the following people:

- Hynek Schlawack: Ayam Makefile configuration GUI
- Florian Kirsch: OpenCSG
- Bertrand Coconnier: implementation of object picking
- Hermann Birkholz: initial implementation of the tree widget, shadow map support, AI, and IDR
- Frank (Copper) Pagels: MetaBalls custom object, TTF parser, providing a lot of good music
- Stephen Echavia: Icons
- Larry Gritz: BMRT
- Benjamin Bederson, Brian Paul et. al.: The Togl Widget
- Jeffrey Hobbs: tkMegaWidget set
- Jan Nijtmans: Tcl/Tk PlusPatches, tcl2c, Wrap
- Georgios Petasis: tkdnd
- Thomas E. Burge: The Affine Toolkit
- Apple, Duet Development Corp.: 3DMF parser
- Mark J. Kilgard: GLUT
- Les A. Piegl and Wayne Tiller: The NURBS Book
- W. T. Hewitt and D. Yip: The NURBS Procedure Library
- Philippe Lavoie: The NURBS++ Library
- Tom Cashman: snurbs (Subdivision NURBS) library
- George W. Hart: Conway notation polyhedron generator
- Everyone involved in the development of Tcl/Tk, OpenGL, The RenderMan Interface

OpenGL (R) is a registered trademark of Silicon Graphics, Inc.

The RenderMan (R) Interface Procedures and Protocol are: Copyright 1988, 1989, 2000 Pixar All Rights Reserved

RenderMan (R) is a registered trademark of Pixar

The Affine Libraries and Tools are Copyright (c) 1995, 1996, 1997, 1998 Thomas E. Burge All rights reserved.

Affine (R) is a registered trademark of Thomas E. Burge.

TIFF Software is Copyright (c) 1988-1997 Sam Leffler Copyright (c) 1991-1997 Silicon Graphics, Inc.

Dime is Copyright (c) 1998-1999 Systems In Motion, SA All rights reserved.

AutoCAD (R) is a registered trademark of Autodesk, Inc.

DXF (R) is a registered trademark of Autodesk, Inc.

Next Previous Contents