Next Previous Contents

## 4. Objects, Properties, and Tags

This section informs you about the different object types of Ayam and about the property GUIs that appear in the properties section of the main window if a single object and a property have been selected.

Documentation on the standard properties (Transformations, Attributes, Material, Shader, and Tags) can be found in section Standard Properties.

Furthermore, this section contains information about all tag types, see section Tags.

In the next sections general object capabilities will be briefly documented in tables like this:

Type | Parent of | Material | Converts to / Provides | Point Edit
Object Type | No/Object Type+/* | Yes/No | N/A / Children / Object Type+/* | Yes/No*

Object Capabilities Template

The capabilities are:

- Type: the type name as displayed in the object tree view and understood by the `"crtOb"` scripting interface command;
- Parent of: the object is a parent object (can have child objects of the designated type), + – multiple child objects may be present (one or many), * – multiple child objects must be present (many), note that the type of the child object(s) does not need to match directly, the child(s) must rather provide an object of the appropriate type (see also section The Modelling Concept Tool-Objects);
- Material: the object can be associated with a material;
- Converts to/Provides: type of converted/provided objects (Children means, the provided objects of the children are delivered upstream), + – multiple objects may be provided (one or many), * – multiple objects will be provided (many);
- Point Edit: the object has editable points, * – read only points are supported.

Example:

Type | Parent of | Material | Converts to / Provides | Point Edit
Revolve | NCurve | Yes | NPatch+ | No*

Object Capabilities Example

Explanation:

- Type: the Revolve object has the type name `"Revolve"`, i.e. it can be created from scripts using the command `"crtOb Revolve"`;
- Parent of: the Revolve object has one NCurve (or NCurve providing object) as child;
- Material: the Revolve object can be associated with a material;
- Converts to/Provides: the Revolve object converts to (and provides) one or multiple NPatch objects;
- Point Edit: the Revolve object has no editable points, it does not support single point modelling actions; however, read only points are supported (the control points of the underlying NPatch object can be read and selected).

## 4.1 Object Types Overview

This section provides an overview on the object types available in Ayam (since there are so many). The object types are grouped by application in the following sections.

### Scene Organization

These objects help to organize the scene apart from geometric objects:

Type | Parent of | Material | Converts to / Provides | Point Edit
Root | View+ | No | N/A | No
View | NPatch | No | N/A | Yes
Camera | No | No | N/A | Yes
Light | No | No | N/A | Yes
Material | No | N/A | N/A | No
Level | Any+ | Yes | N/A / Children+ | No
Clone | Any+ | No | Children+ | No*
Mirror | Any+ | No | Children+ | No*
Instance | No | No | Master | No*
Select | Any+ | No | N/A / Children+ | No
RiInc | No | No | N/A | No
RiProc | No | No | N/A | No

Scene Organization

### CSG/Solid Primitives

These objects serve as geometric primitives in CSG hierarchies:

Type | Parent of | Material | Converts to / Provides | Point Edit
Box | No | Yes | NPatch* | No*
Sphere | No | Yes | NPatch+ | No*
Disk | No | Yes | NPatch | No*
Cone | No | Yes | NPatch+ | No*
Cylinder | No | Yes | NPatch+ | No*
Torus | No | Yes | NPatch+ | No*
Paraboloid | No | Yes | NPatch+ | No*
Hyperboloid | No | Yes | NPatch+ | No*

CSG/Solid Primitives

### Freeform Curves

These objects are mainly used as child objects for the surface generating tool objects:

Type | Parent of | Material | Converts to / Provides | Point Edit
NCurve | No | No | N/A | Yes
ICurve | No | No | NCurve | Yes
ACurve | No | No | NCurve | Yes
NCircle | No | No | NCurve | No*

Freeform Curves

### Freeform Surfaces

These objects enable direct manipulation of freeform surfaces:

Type | Parent of | Material | Converts to / Provides | Point Edit
NPatch | NCurve+/Level+ | Yes | PolyMesh | Yes
IPatch | No | Yes | NPatch | Yes
BPatch | No | Yes | NPatch | Yes
PatchMesh | No | Yes | NPatch | Yes

Freeform Surfaces

### Curve Tool Objects

These objects modify existing curves or create new curves:

Type | Parent of | Material | Converts to / Provides | Point Edit
ConcatNC | NCurve+ | No | NCurve | No*
ExtrNC | NPatch | No | NCurve | No*
OffsetNC | NCurve | No | NCurve | No*

Curve Tool Objects

### Surface Tool Objects

These objects create freeform surfaces from curves or other surfaces:

Type | Parent of | Material | Converts to / Provides | Point Edit
Revolve | NCurve | Yes | NPatch+ | No*
Extrude | NCurve+ | Yes | NPatch+ | No*
Swing | NCurve* | Yes | NPatch+ | No*
Sweep | NCurve* | Yes | NPatch+ | No*
Birail1 | NCurve* | Yes | NPatch+ | No*
Birail2 | NCurve* | Yes | NPatch+ | No*
Skin | NCurve* | Yes | NPatch+ | No*
Gordon | NCurve*/Level | Yes | NPatch+ | No*
Bevel | NCurve+ | Yes | NPatch | No*
Cap | NCurve+ | Yes | NPatch | No*
Text | No | Yes | NPatch+ | No*
Trim | NPatch/NCurve+/Level+ | Yes | NPatch | No*
ConcatNP | NPatch*/NCurve* | Yes | NPatch | No*
ExtrNP | NPatch | Yes | NPatch | No*
OffsetNP | NPatch | Yes | NPatch | No*

Surface Tool Objects

### Polygonal and Subdivision Objects

These objects complement the Ayam feature set and allow objects modelled in the polygonal or subdivision modelling paradigms to be included in Ayam scenes:

Type | Parent of | Material | Converts to / Provides | Point Edit
PolyMesh | No | Yes | SDMesh | Yes
SDMesh | No | Yes | PolyMesh | Yes

Polygonal and Subdivision Objects

### Scripts and Plugins

These objects create/modify arbitrary other objects from scripts or define new object types via the custom object plugin mechanism.

Type | Parent of | Material | Converts to / Provides | Point Edit
Script | Any+ | No | Any | No*
MetaObj | MetaComp+ | Yes | PolyMesh | No
MetaComp | No | No | N/A | No
SDNPatch | No | Yes | PolyMesh | Yes

Scripts and Plugins

## 4.2 Root Object

There is always exactly one Root object in the scene. This object is something special in that it can not be deleted or copied. The Root object holds rendering options global to the scene like RiOptions, atmosphere and imager shaders. Furthermore, all currently open view windows are represented as child objects of the Root object.

If you hide the Root object, the little red/green/blue coordinate system will not be drawn in any view.

The Root object also aids in per-scene window geometry management using SaveMainGeom and SavePaneLayout tags (see also section Tags.

The global scene rendering options are documented in the following sections.

### RiOptions Property

The RiOptions property carries RenderMan Interface options. Both, standard and BMRT specific options may be set using this property. For the sake of brevity only a short description of the available options will be given here. Please refer to the documentation of the RenderMan Interface and the documentation of BMRT for more detailed information about the options.

The RiOptions property consists of the following elements:

- `"Width"`, `"Height"`, if greater than zero this value will be used for the image size instead of the corresponding dimension of the view window, but only for real RIB export operations, not for the QuickRender and not for the Render actions in view windows. QuickRender and Render actions will always use the dimensions of the view window instead.
- `"StdDisplay"`, if this is enabled, a standard display statement will be written to the RIB, which looks like this:

  > `

  >     Display "unnamed.tif" "file" "rgba"

  > `

  If you disable this option, be sure to add atleast one RiDisplay tag to the root object (see also section RiDisplay Tag), otherwise your RIB will not contain a RiDisplay statement. This option has no effect on RIBs created by the QuickRender and Render actions in view windows.
- `"Variance"`, maximum allowed variance of two pixel values. The default 0.0 causes no setting in the RIB. If the variance is > 0.0 no pixel samples setting will be written to the RIB. Various sources discourage the use of variance based sampling, because e.g. the number of samples actually taken (and therefore the rendering time) might not easily be predicted anymore.
- `"Samples_X"`, `"Samples_Y"` number of samples taken per pixel.
- `"FilterFunc"`, function used to filter final pixel values.
- `"FilterWidth"`, `"FilterHeight"` size of the pixel filter.
- `"ExpGain"`, Exposure
- `"ExpGamma"`, Exposure Gamma
- `"RGBA_ONE"`, `"RGBA_MIN"`, `"RGBA_MAX"`, `"RGBA_Dither"`, specify quantisation and dithering
- `"MinSamples"`, `"MaxSamples"`, minimum and maximum number of samples per pixel (for variance based sampling).
- `"MaxRayLevel"`, maximum number of recursive rays.
- `"ShadowBias"`, minimum distance that one object has to be in order to shadow another object.
- `"PRManSpec"`, toggles behaviour of BMRT's specular() function between PRMan compatible (default) and RI standard compatible.
- `"RadSteps"`, number of radiosity steps, the default 0 leads to no radiosity calculations to be performed.
- `"PatchSamples"`, minimum number of samples per patch to calculate the radiosity form factors for this patch.
- `"Textures"`, `"Shaders"`, `"Archives"` and `"Procedurals"` are search paths for the renderer.
- `"TextureMem"` and `"GeomMem"` determine how much memory rendrib (from BMRT) should use at maximum to cache textures and tesselated geometry.

### Imager, Atmosphere Property

The Imager and Atmosphere properties let you define shaders for the Root object, please refer to section Shader Properties for information on how to deal with shader property GUIs.

Imager shaders are executed once for every rendered pixel, they may e.g. be used to set a specific background color.

Atmosphere shaders are volume shaders that may be used to implement global atmospheric optical effects like fog.

### RIB Export

The Root object appears in RIB output in different places as collection of RenderMan Interface options and imager as well as atmosphere shaders.

The exact RIB statements used depend on the configuration of the object and the preference setting `"RIB-Export/RIStandard"`.

The Root object is the only object to support RiOptions, RiHider, and RiDisplay tags (see also section Tags.

## 4.3 View Object

Every view window (see also section Anatomy of a View) has a corresponding view object as a child object of the root object. You can change camera settings, the type of the view, and other things related to the view using the properties of the view object. Note that deleting the object that represents a view, will not close the view window. You will just lose a way to configure it. Please, do not mess with the objects in other ways (e.g. copy them), you are asking for trouble otherwise!

Each view is associated with a virtual camera. The type of the view determines the Up-vector of that camera. If the type is "Top" the Up-vector corresponds to the world Z-axis, else the world Y-axis. The type of the view, additionally, determines the so called input plane of the view. Interactive modelling actions in a view are limited to that input plane (unless the view is switched to local modelling; see also section Editing in Local Spaces). *

The standard input planes are as following: Front – XY-plane, Side – ZY-plane, Top – XZ-plane, Trim – XY-plane.

In perspective views no interactive modelling actions are possible, but you may position the camera, pick objects, and select points.

Views of type `"Trim"` are very special. They are used to edit trim curves of NPatch objects only. They display only those trim curves as normal NURBS curves when the current level is inside a NPatch. The extensions of the patch in parameter-space are drawn as a rectangle. The trim curves should completely lie inside this rectangle. Note that picking of objects currently does not work in views of type `"Trim"`.

View objects act in special ways, when certain objects are dropped onto them in the tree view:

When a camera object is dropped onto a view object using drag and drop in the tree view the camera settings of the camera object will be copied to the views camera.

When a light object of type `"Spot"` is dropped onto a view object using drag and drop in the tree view the views camera will be changed, so that the user looks along the light to see what objects of the scene are lit by the light object (this works best with perspective views that have equal width and height).

It is also possible, to directly drag objects from the tree view to a view window: for geometric objects, the view then performs a zoom to object operation, for cameras and light sources the views camera will be changed as if the object was dropped onto a view object in the tree view (see the above description). *

The following table briefly lists some capabilities of the View object.

Type | Parent of | Material | Converts to / Provides | Point Edit
View | NPatch | No | N/A | Yes

View Object Capabilities

The next sections detail the properties of the view object.

### Camera Property

This section describes all elements of the `"Camera"` property:

- `"From"` is the point where the camera (that is attached to the view) is situated.
- `"To"` is the point the camera is looking to.
- `"Up"` is the up vector of the camera.
- `"Near"` defines the near clipping plane. A value of 0.0 means a default value (that depends on the type of the view) should be used. Near should always be positive for perspective views, and smaller than far.
- `"Far"` defines the far clipping plane. A value of 0.0 means a default value (that depends on the type of the view) should be used. Far should always be bigger than near.
- `"Roll"` defines an angle by which the camera is rotated around the axis that is defined by the points from and to.
- `"Zoom"` is a zoom factor.

Note that the up vector is not checked for erroneous values (e.g. pointing in the direction of from-to) when applying the changes of the `"Camera"` property.

### ViewAttrib Property

This section describes the elements of the `"ViewAttrib"` property:

- `"Type"` specifies the type of the view. Front, Side, Top (all parallel), Perspective and Trim (again parallel) may be selected.
- `"Width"` and `"Height"` control the size of the view window. It is currently not possible to resize internal views with these elements.
- `"Redraw"` toggles automatic redrawing of the view. If this is disabled, no drawing takes place in the view until an explicit redraw is requested (using the view menu, or the shortcut `<Ctrl+d>`).
- `"DrawingMode"` allows to specify the drawing mode of the view: `"Draw"` draws a wireframe, `"Shade"` draws lighted surfaces. Note that the lighting is in no way an exact (or even similar) representation of the light information as specified with Light objects in the scene. Instead, a single light source, located at the camera origin (a headlight), will be used `"ShadeAndDraw"` combines surfaces and wireframes.
- `"DrawSel"` toggles drawing of selected objects. If this is enabled, only the current selected objects will be drawn.
- `"DrawLevel"` toggles drawing of the objects of the current level only. If this is enabled, only the objects of the current level will be drawn.
- `"Grid"` is the grid size, 0.0 means no grid.
- `"DrawGrid"` toggles drawing of the current grid.
- `"UseGrid"` toggles, whether the current grid should be used by the interactive modelling actions.
- `"ModellingMode"` enables editing in local object spaces. See also section Editing in Local Spaces.
- `"DrawBG"` controls whether the background image should be drawn.
- `"BGImage"` is the name of a TIFF file, that will be used as texture for the background image. Ayam will read this image once when you apply the changes to the `"ViewAttrib"` property but reread the image file if the notification callback of the view object is invoked (e.g. using the main menu entry `"Tools/Force Notification"`).
- `"Mark"` is the marked point (in world coordinates) for the rotate and scale about modelling actions.
- `"SetMark"` controls whether the data from the `"Mark"` entries above should be used as new mark coordinates.
- `"EnableUndo"` is switched on by default and allows to disable undo for view actions, e.g. panning or zooming a view, these actions then also do not change the scene changed state.

## 4.4 Camera Object

Camera objects are used to temporarily save camera settings of views. Therefore, they has just have two properties explained above, see sections Camera and Attributes Property.

When a view object is dropped onto a camera object using drag and drop in the tree view, the camera settings from the view will be copied to the camera object.

The following table briefly lists some capabilities of the Camera object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Camera | No | No | N/A | Yes

Camera Object Capabilities

### RIB Export

Camera objects never appear in RIB output.

## 4.5 Light Object

Light objects let you bring light into your scenes.

The behaviour of a light source object depends heavily on the type of the light source. There are currently four different light types available in Ayam: `"Custom"`, `"Point"`, `"Distant"` and `"Spot"`.

Custom Lights:

Light sources of type `"Custom"` use the attached light shader.

Note that Ayam is trying to guess from the names of the light shader arguments to draw the light. The names `"from"` and `"to"` denote location and destination of the light source. Those names should not be used for other things in the light shaders.

Point-, Distant-, and Spotlights:

These (standard) light sources have well defined parameters that will be displayed in the `"LightAttr"` property. Please refer to the RenderMan documentation for more information about the standard light sources (see section references).

In contrast to the light sources as defined in the RenderMan interface, Ayam light sources are always global by default. This means, regardless of the place of a light source in the scene hierarchy, it will always light all other objects (unless the `"IsLocal"` attribute is used).

Note that you can not preview the effect of a light source in shaded Ayam views, currently. However it is possible to estimate the effect of a spot light source by simply dropping it into a perspective view window, the view will then show you the objects lit by the spot.

The following table briefly lists some capabilities of the Light object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Light | Yes | No | N/A | Yes

Light Object Capabilities

### LightAttr Property

Depending on the type of the light source, the light attribute property contains different parameters. Parameters that are not displayed will not be used on RIB export, consequently.

Using `"Type"` you can change the type of the light source. When you change the type of a light source, the property GUI will be adapted to show only the options available for the new light source type, but only after you used the `"Apply"`-button.

`"IsOn"` allows you to switch the light off or on. The default value is on.

`"IsLocal"` controls whether the light source should light just local objects (objects, that are defined in the same level in the scene hierarchy as the light source object or below it) or all objects in the scene. The default is off, all objects in the scene are lit. The `"IsLocal"` attribute is ignored for lights that are defined in the root level of the scene. Mind also that shadow maps will always contain shadows from all objects in the scene, regardless of the `"IsLocal"` attribute of the light source.

Using the light attribute `"Shadows"` you may determine whether the light source should cast shadows. The default is off, no shadows. Note that this option will not magically enable shadows on renderers that create shadows by shadow maps. It will merely be interpreted by raytracing renderers like BMRT.

The attribute `"Samples"` determines the number of times to sample an area light source, independent of pixel samples, the default value is 1. This attribute is available for custom lights only.

`"UseSM"` determines, whether shadow maps should be created and used for this light source. The resolution of the shadow map may be determined by the attribute `"SMRes"`. If `"SMRes"` is 0, a default of 256 by 256 pixels will be used. These options are for renderers that do not support raytraced shadows like PRMan or Aqsis only.

For lights of type `"Distant"` the `"Scale"` attributes of the `"Transformations"` property of the light object may be used to scale the camera transformation used for the creation of the corresponding shadow map. Values of 1 for `"Scale_X"` and `"Scale_Y"` create a shadow map that is sized 1 by 1 units in world space.

All other parameters that may appear in the `"LightAttr"` property are the standard parameters for the standard RenderMan light sources: distant, point, and spot:

- `"From"` and `"To"` denote position and target of the light source as point in space. You may edit both points using standard point editing actions (see also section interactive actions).
- `"Color"` is the color of the light emitted by the light source.
- `"Intensity"` is the intensity of the light emitted by the light source. Note that the standard point and spot lights have a quadratic falloff (with distance), that requires the intensity to be set to quite high values in order to achieve some illumination effect (e.g. around 30 for the standard distance of `"From"` and `"To"` of a spot light).
- `"ConeAngle"` is the angle of the beam of a spot light.
- `"ConeDAngle"` (cone delta angle) is the angle that determines a falloff area at the edge of the beam of a spot light.
- `"BeamDistrib"` (beam distribution) determines, how the light falls off in the beam of the spot light. Larger values result in narrower lit areas.

In order to ease the parameterisation of spot lights, you may drop the light source object onto a view object or into a view window (preferably one with a perspective viewing transformation and with equal width and height) to see what objects of the scene are actually lit by the light object.

### Using ShadowMaps

Using shadow maps requires the global preference setting `"RIB-Export/ShadowMaps"` to be switched on. Furthermore, for each light source for which a shadow map should be created, the attributes `"IsOn"` and `"UseSM"` have to be switched on.

Automatic Creation of ShadowMaps

If the preference setting `"RIB-Export/ShadowMaps"` is set to `"Automatic"`, Ayam will create a special version of the RIB on export, that creates all shadow maps automatically upon rendering. This is done by rendering depth images from the position of every light source that casts shadows. Special light source shaders later pick up these depth images and calculate shadows. This approach implies, that the scene is rendered multiple times. To reduce the size of the RIB, the objects to be rendered are written to a second RIB file named `"<scene>.obj.rib"`. This file is read from the main RIB several times via `"ReadArchive"`. The RIB contains multiple frames which may also be rendered separately if the frame number is known. To help you picking the right frame number for the image (e.g. to re-render just the final image, when only a material setting was changed, and no shadow casting lights were moved and no shadow casting geometry was changed), a comment with the frame number of the last frame (the image) will be written as last statement to the RIB.

Because multiple files (RIBs and shadow maps) are used, it is suggested to change the preference setting `"RIB-Export/RIBFile"` to `"Scenefile"`. This will strip the leading absolute path component from the filenames so that you may move the exported scene from one system to another more easily.

Do not render directly from a view window to the display when the `"ShadowMaps"` `"RIB-Export"` preference option is set to `"Automatic"`. Your renderer may not write image files when the command line option to render directly to the display (-d for rendrib, or -fb for Aqsis) is in use. Consequently, this may also inhibit writing of the shadow maps, so that the resulting image will look wrong, or the renderer will render the shadow map to the display and simply stop.

Manual Creation of ShadowMaps

If the preference setting `"RIB-Export/ShadowMaps"` is set to `"Manual"`, the exported scene will not render the shadow maps but rather expects them to be present already. You can create them manually (hence the name `"Manual"`) using the view menu entries `"View/Create ShadowMap"`, `"View/Create All ShadowMaps"` or the main menu entries `"Special/RIB-Export/Create ShadowMap"`, `"Special/RIB-Export/Create All ShadowMaps"`. The manual approach has the advantage, that the shadow maps will not be re-created each time you render the scene.

ShadowMap Types

Ayam supports three different methods for the creation of shadow maps for certain types of light sources: point, distant, and spot:

The point method is used with lights of type `"Point"` and custom lights that have a light shader argument named "from". Six shadow maps pointing in all possible axis aligned directions and named `"<rib>.point<num>_<dir>.shd"` (where `"<rib>"` is the name of the RIB, `"<num>"` is the number of the light source that makes use of shadow maps and `"<dir>"` is one of `"x+"`, `"x-"`, `"y+"`, `"y-"`, `"z+"`, or `"z-"`) will be created.

The distant method is used with lights of type `"Distant"` and custom lights that have a light shader argument named "from" and a light shader argument named "to". One shadow map is created and named `"<rib>.dist<num>.shd"`. By default, the size of the shadow map is 1 by 1 units in world space, but this may be adapted using the scale transformation attributes of the light object.

The spot method is used with lights of type `"Spot"` and custom lights that have a light shader argument named "from", a light shader argument named "to", and a light shader argument named "coneangle". One shadow map is created and named `"<rib>.spot<num>.shd"`. The spot method uses the cone angle (and additionally the delta cone angle, if present) argument to determine the size of the shadow map in world space.

If a light object of type `"Spot"`, `"Distant"` or `"Point"` is used, Ayam automatically changes the name of the exported light shader to `"shadowspot"`, `"shadowdistant"`, and `"shadowpoint"` respectively. Additionally, the shader will be parameterised to use the created shadow maps. If the light source is of type `"Custom"`, no automatic renaming and adjusting of the shader takes place. This means, you have to make sure that the shader really uses the shadow maps, by selecting the right shader and parameterising it accordingly. See the discussion above for the names of the shadow map files. Those file names, most probably, will have to be entered as parameter to the light shader.

For example, you will not get any shadows if you use a light source of type `"Custom"` with the normal `"distantlight"` shader attached, even though Ayam is able to create the necessary shadow maps. The normal `"distantlight"` shader just makes no use of the shadow maps. You have to manually switch to a shader that makes use of the shadow maps (`"shadowdistant"` in this case) to get shadows.

ShadowMap Mini Tutorial

Here is a short example for a scene using a shadow map:

1. Go to the preferences (section `"RIB-Export"`) and set `"ShadowMaps"` to `"Automatic"`.
2. Create two boxes.
3. Open the `"Transformations"` property of the second box.
4. Translate it by X: 0.0, Y: -1.0, Z: 0.0.
5. Scale it by X: 4.0, Y:1.0, Z:4.0.
6. Create a light source.
7. Open the `"LightAttr"` property.
8. Change the type to `"Spot"`. Press `"Apply"`.
9. Now change the parameters of the spot light to `"IsOn"`: Yes, `"Intensity"`: 18.0, `"UseSM"`: Yes, `"ConeAngle"`: 45.0, `"BeamDistrib"`: 3.0, `"From"`: -2, 2, 2, `"To"`: 1, 0, -1; leave all other parameters at their default values.
10. Create a new view and make it perspective (Menu: `"Type/Perspective"`).
11. Export a RIB from that perspective view (Menu: `"View/Export RIB"`).
12. Render the RIB with a RenderMan compliant renderer, that uses shadow maps, e.g. Photorealistic RenderMan (prman) or Aqsis.

This scene is distributed with Ayam as an example scene named `"shadowmaps.ay"`.

Note that for Aqsis you should add a RiHider hidden,depthfilter,s,midpoint tag to your root object if shadow maps are in use. Other renderers might require additional tweaking using shadow bias RiOption tags. Please consult the documentation of your renderer on how to achieve the best results using shadow maps.

### Using AreaLights

The common idealized standard light sources `"Point"`, `"Distant"` and `"Spot"` have no own geometric extension in space. This means, shadows resulting from such light sources will have sharp borders which does not look too natural. Good looking soft shadows may be generated using area lights.

Area lights may be created by simply placing a single object as child object of a `"Custom"` light object that has the `"arealight"` shader attached:

> `

>     +-AreaLight(Light)
>      \ AreaLightGeometry(Sphere)

> `

This child object determines the geometry, place, and extension of the light source. According to L. Gritz, Spheres and Cylinders work best as area light geometry for BMRT, because of special sampling code.

An example:

- Create a custom light object.
- Assign the arealight light shader to it.
- Create a sphere.
- Drag and drop the sphere onto the Light object so that it becomes a child of the light object.
- Transform the sphere object to your hearts content; the position and size of the object determines the position and size of the light source.

There is an example scene named `"arealight.ay"` distributed with Ayam.

## 4.6 Material Object

Material objects are used to attach RiAttributes and shaders to geometric objects.

When geometric objects are dropped onto a material object using drag and drop in the tree view they will be connected to this material object.

While geometric objects are connected to a material object this material object may not be deleted.

The following table briefly lists some capabilities of the Material object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Material | No | N/A | N/A | No

Material Object Capabilities

### RiAttributes Property

Using this property standard and BMRT specific attributes may be set. Please refer to the documentation of the RenderMan interface and the documentation of BMRT for more detailed information about the RenderMan specific attributes.

- `"Color"`, the color of the object. If you set one of the entries to a negative value (e.g. -1), the color will not be set at all for this object.
- `"Opacity"`, the opacity of the object, the default 255 255 255 means the object is totally opaque. If you set one of the entries to a negative value (e.g. -1), the opacity will not be set at all for this object.
- `"ShadingRate"`, determines how often shaders are evaluated for a sample.
- `"Interpolation"`, determines how return values computed by the shaders are interpolated across a geometric primitive.
- `"Sides"`, determines how many sides of the surface of a geometric primitive should be shaded.
- `"BoundCoord"`, sets the coordinate system in which the displacement bound is expressed.
- `"BoundVal"`, displacement bound value.
- `"TrueDisp"`, toggles true displacements on or off. Default off.
- `"CastShadows"`, determines how the object casts shadows: the default `"Os"` means the object casts shadows according to it's opacity; `"None"` object does not cast any shadows; `"Opaque"` the object is completely opaque and casts shadows; `"Shade"` the object has a complex opacity pattern determined by it's surface shader, that is used in shadow calculations.
- `"Camera"`, `"Reflection"`, and `"Shadow"` toggle visibility attributes.

### Surface, Displacement, Interior, Exterior Property

These properties let you define shaders for the material object, please refer to section Shader Properties for information on how to deal with shader property GUIs.

Surface shaders may be used to procedurally encode lighting models and textures. Displacement shaders may procedurally deform the object while rendering. Interior and Exterior shaders are so called volume shaders that may be used to capture special optical effects, encoding how light is affected while passing through an object.

### MaterialAttr Property

The MaterialAttr property contains attributes related to the management of material objects:

- `"Materialname"` denotes the name of the material. Note that material names have to be unique in a scene. If two materials with the same name exist, only the first material created with this name is "registered" and thus may be connected to geometric objects.
- `"Refcount"` shows how many geometric objects are connected to (are of) this material. Note that connected or referring geometric objects not necessarily have to live in the scene, they may as well temporarily reside in the object clipboard.
- `"Registered"` displays whether this material may be connected to geometric objects, see the discussion about material names above.

### RIB Export

Material objects only appear in RIB output if connected to a geometric object (e.g. a Box).

The exact RIB statements used depend on the configuration of the material and the preference setting `"RIB-Export/RIStandard"`.

If all elements of the MaterialAttr property are left on their default values, only color and opacity will be written to the RIB:

> ``RiColor(...);
> RiOpacity(...);``

After the elements of the MaterialAttr property, the surface, displacement, interior, and exterior shaders (if attached to the material) will be exported, all shader parameters will be properly declared:

> ``RiDeclare("Ka", "float");
> ...
> RiSurface("Ka", 0.9, ...);
> ...``

After the material description custom RiAttributes and texture coordinates from tags will be exported.

No attempt is being made to re-order or sort objects in a level according to their attached materials, they will rather be exported in the order of their appearance in the level and thus each object with a material will also be prepended by a full material specification as described above.

## 4.7 Level Object

Level objects may be used to build object hierarchies and perform CSG operations.

Ayam does not offer a layer concept, but by grouping objects using levels and the hide/show tools, layer functionality may be emulated to a certain extent.

Organizing the scene and working in levels also increases the speed of object tree updates, as only the current level and its sub-levels are subject to a tree update if something in the object hierarchy changes.

Note that child objects of a level inherit the levels transformations, material, attributes, and shaders. Inheritance of e.g. transformations means:
If you have a NURBS patch in a level that is translated to (10,0,0), the origin of the local coordinate system of the NURBS patch will be situated at (10,0,0). If you decide to move the patch by a value of 5 in X direction by setting a corresponding value in the Transformations property of the patch object, the local coordinate system of the patch will be placed at (15,0,0) in world coordinates, i.e. the control point (1,0,0) will be at (16,0,0).

Note also that since Ayam 1.12, Level objects provide their child objects to their parent objects as a list. This means the following hierarchy is now valid:

> `

>     +-Skin
>      +-Level
>       | NCurve
>       | NCurve
>       | ICurve
>       \ NCurve

> `

All NURBS curves and objects that may be converted to NURBS curves (in this example: the ICurve) will be provided to the Skin by the Level object. Transformation attributes of the Level will be added to the provided objects. Objects that do not provide the wanted type will be silently ignored.

The following table briefly lists some capabilities of the Level object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Level | Any+ | Yes | N/A / Children+ | No

Level Object Capabilities

### LevelAttr Property

Levels do not have many object type specific properties, you may just modify the type of the level using the attribute `"Type"`.

Levels of type `"Level"` just group objects and inherit attributes.

Levels of type `"Union"`, `"Intersection"`, and `"Difference"` are used to build CSG hierarchies. Additionally, they inherit attributes. Note that Ayam is currently not able to correctly display the results of CSG operations, all objects are always drawn completely, even though a CSG operation would cut parts away.

However, since Ayam 1.8 there is a plugin available that is able to preview the results of CSG operations, see also section CSG preview using the AyCSG plugin.

The object hierarchy to cut away a part of a box using a sphere looks like this:

> `

>     +-Level_of_Type_Difference(Level)
>      | Box
>      \ Sphere

> `

More than two objects may be arguments of a CSG operation:

> `

>     +-Level_of_Type_Difference(Level)
>      | Box
>      | Sphere
>      \ Sphere

> `

In this example, the two spheres would cut away parts of the box.

New solid primitives may be created with levels of type `"Primitive"`.

> `

>     +-Level_of_Type_Difference(Level)
>      +-Level_of_Type_Primitive(Level)
>      | | Sphere_blue
>      | \ Disk_red
>      \ Box_grey

> `

In this example an open sphere with `"ThetaMax"` 180.0 (a hemisphere) is manually capped by a disk object. The two objects need to be placed into a level of type `"Primitive"` because each object alone is an open surface and therefore not a valid CSG primitive. Both objects that form the new primitive use a different material. In addition, a grey box cuts away a part from the multi colored hemisphere. The above CSG hierarchy is available as example scene file `"multicolcsg.ay"`.

See also this image:

Multicolor CSG Example

Note that Ayam is not able to check, whether your new primitive obeys the rule of total closeness. For instance, if the disk in the above example would not totally cap the sphere (this happens if the disk `"ThetaMax"` is not 360.0 or if it is not placed exactly at the sphere) Ayam would not complain upon RIB export. The rendered image would expose serious errors, however.

Furthermore, it is not necessary to enclose normal child objects (e.g. quadrics with the `"Closed"` attribute set to on) of CSG levels in primitive levels for RIB export. This is done by Ayam automatically where needed.

### RIB Export

The exact representation of a Level in RIB output depends on its type.

Normal Level objects appear in RIB output as Transformation hierarchies:

> ``RiTransformBegin();
> RiTranslate(...);
> RiRotate(...);
> RiScale(...);
> «Children RIB output»
> RiTransformEnd();``

Level objects of type Union, Difference, or Intersection will additionally contain a call to SolidBegin, and each child will be properly declared as primitive, e.g.:

> ``RiTransformBegin();
> «Level Transformations»
> RiSolidBegin(RI_DIFFERENCE);
> RiSolidBegin(RI_PRIMITIVE);
> «Child #1 RIB output»
> RiSolidEnd();
> RiSolidBegin(RI_PRIMITIVE);
> «Child #2 RIB output»
> RiSolidEnd();
> RiSolidEnd();
> RiTransformEnd();``

## 4.8 Clone Object

Clone Object (blue) with Trajectory Curve (white)

The Clone object allows to easily create and control an arbitrary number of instances of a single object, hereafter called the cloned object. The instances can be transformed (each by a certain amount expressed as difference between two instances) or placed on a trajectory curve (see also the image above).

If a second object is present as child of the Clone object it is treated as trajectory (or path) curve automatically. The process of placing the clones on the trajectory is very similar to the sweeping operation (see also section Sweep Object).

Thus, the default object hierarchy of a Clone object looks like this:

> `

>     +-Clone
>      | Cloned-Object
>      \ [Trajectory(NCurve)]

> `

If you use a trajectory curve to place the clones, you may want to hide the cloned object and also add a `"NoExport"` tag to it. Otherwise the original object will appear twice, on the trajectory and on its normal, untransformed, position. Note that the transformation attributes of the cloned object will be completely overwritten when placing the clones on the trajectory curve. If the cloned object has distinct scale or rotation attributes it should be put inside a level object like this:

> `

>     +-Clone
>      +-Level
>      |\ Cloned-Object with non-standard Scale/Rotation
>      \ Trajectory(NCurve)

> `

It is not possible to create clones from objects that may not be master objects of instance objects, e.g. it is not possible to clone light objects or material objects. However, (since Ayam 1.7) it is possible to use instances as parameter objects.

If an instance object is used as cloned object on a trajectory it can be placed in a level and the `"NoExport"` tag can be added to the level object (as adding tags to Instance objects is more involved), see the following hierarchy for an example:

> `

>     +-Clone
>      +-Level with NoExport tag
>      |\ Instance
>      \ Trajectory(NCurve)

> `

Since Ayam 1.20 the mirror facility of the Clone object is realized through the new Mirror object (see also section Mirror Object). The mirror facility was integrated into the Clone object before.

The following table briefly lists some capabilities of the Clone object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Clone | Any+ | No | Children+ | No*

Clone Object Capabilities

The following attributes further control the cloning process:

### CloneAttr Property

- `"NumClones"` is the number of clones to create.
- `"Rotate"` is only used, if a trajectory curve is present. If it is enabled all clones will be aligned according to the normal of the trajectory curve. Otherwise the rotation attributes will not be touched when placing the clone on the trajectory.
- `"Translate_X"`, `"Translate_Y"`, `"Translate_Z"`, `"Rotate_X"`, `"Rotate_Y"`, `"Rotate_Z"`, `"Scale_X"`, `"Scale_Y"`, `"Scale_Z"`, those attributes control the transformation of the instances created by the Clone object. These attributes specify difference values between two instances: the clone `"n+1"` is offset by `"Translate_X"`, `"Translate_Y"`, and `"Translate_Z"` from the previous clone `"n"`. It is also rotated by `"Rotate_X"`, `"Rotate_Y"`, and `"Rotate_Z"` and scaled by `"Scale_X"`, `"Scale_Y"`, `"Scale_Z"` in relation to the previous clone.

  Note however, that the transformation attributes do not affect the first clone.

  The transformation attributes are also in effect if a trajectory curve is present, they will be applied after moving of the instance to the trajectory and rotating it. *

The following table summarizes which transformation attributes are used in the respective clone modes.

Mode | Use Child Transform | Use CloneAttrib Transform | Use Clone Transform
Clone | No | Yes | Yes
Trajectory | Yes | Yes | Yes
Mirror | Yes | N/A | Yes

Clone Parameterisation Examples

### Conversion Support

The Clone object may be converted to ordinary objects using the main menu entry `"Tools/Convert"`.

Upon conversion a Level object will be created, that contains the original object and the clones.

### RIB Export

Clone objects appear in RIB output as a number of real objects, each with different transformation attributes.

As the original objects will also appear in the RIB output, it is suggested to add a `"NoExport"` tag to the original if the Clone is in trajectory mode.

## 4.9 Mirror Object

Mirrored Object (blue) From Curve (white)

The Mirror object allows to easily create and control an arbitrary number of mirrored instances of a number of objects. *

The original object(s) and their mirrored counterparts will be provided by the Mirror object to the respective parent object (normally, tool objects do not provide their unmodified children). Additionally, the order of the mirrored objects will be reversed so that it is possible to use a single Mirror object (with one or multiple NURBS curves as children) as parameter object of e.g. a Skin object:

> `

>     +-Skin
>      +-Mirror
>       \ NCurve
>     +-Skin
>      +-Mirror
>       | NCurve_1(NCurve)
>       | NCurve_2(NCurve)
>       \ NCurve_3(NCurve)

> `

The first Skin object in the above example can only work, because also the unmodified NCurve is provided by the Mirror object. The second Skin object can only work properly, because the order of the provided objects is reversed, so that it gets to see the curves in the following sequence: `"NCurve_1"`, `"NCurve_2"`, `"NCurve_3"`, `"Mirrored_NCurve_3"`, `"Mirrored_NCurve_2"`, `"Mirrored_NCurve_1"`.

The following table briefly lists some capabilities of the Mirror object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Mirror | Any+ | No | Children+ | No*

Mirror Object Capabilities

The following attributes further control the mirror process:

### MirrorAttr Property

- `"Plane"` allows to select the plane about which the mirroring should occur (YZ-, XZ-, or XY-plane).

### Conversion Support

The Mirror object may be converted to ordinary objects using the main menu entry `"Tools/Convert"`.

Upon conversion a Level object will be created, that contains the original objects and the mirrored counterparts (the latter in reverse order).

### RIB Export

Mirror objects appear in RIB output as a number of real objects, each with different transformation attributes.

## 4.10 Instance Object

Instance objects help to save memory consumption in scenes with many similar or repeating objects or transport geometric data across the scene hierarchy.

The term instance is unfortunately misleading (and can be very confusing if you are accustomed to the terminology of object oriented programming), but it is the term that seems to be used and understood by most computer graphic artists. A better term would be link, as an instance object has the same basic properties as a link in a Unix file system. A link is just a pointer to an original file, the same goes for an instance object: it is just a pointer to an original object (here also called master object). A link can be placed anywhere on the file system, an instance object can be placed anywhere in the scene hierarchy, and additionally, it can be transformed.

Normally, the sole purpose of instance objects is to save space, in memory and on the disk. But in the tool object context, instances also serve as a means to transport geometric data across the scene hierarchy to make tool objects depend on each other (see also section The Modelling Concept Tool-Objects). Note that in the tool object context, instance objects are the only objects, that are subject to a second round of provision.

The amount of saved space can be very high, depending heavily on the actual scene and at what levels in the hierarchy instances are used. If there are no similar objects in the scene, however, one can hardly utilise instancing. Similar means "the same except for the transformation property" in this context.

Some simple rules for instancing:

- No instances may be created of objects of the following types: Root, View, Instance, Material, Light. Do not try to fool Ayam and create instances of levels that contain aforementioned types of objects, things will go awry!
- It is allowed, however, to put some instances into a level object and create instances of this level (this is sometimes called hierarchical instancing).
- But one may not put instances of a level into the very same level or one of its children (this would be recursive instancing, which is not supported by Ayam).
- The original/master object may not be deleted from the scene as long as there are instances of that object in the scene or in the object clipboard.

If deleting of an object fails, and the error message complains about the reference counter not being zero, then the last rule was about to be violated. Clean the clipboard using the menu `"Special/Clipboard/Paste (Move)"` and delete or resolve all references first.

Ayam can also create instances for complete scenes automatically (see section Automatic Instancing).

To easily find the master object of an instance, just select the instance, then use the main menu entry: `"Edit/Master"`.

The following table briefly lists some capabilities of the Instance object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Instance | No | No | Master | No*

Instance Object Capabilities

### Instances without Transformations (References)

Instance objects support the `"RP"` tag type in a special way: if the `"Transformations"` property is removed using a `"RP"` tag, the instance does not provide objects with an own set of transformation attributes (to ease hierarchy building with e.g. `"ExtrNC"`/`"ExtrNP"` objects, where only pointers to already existing objects are required and where it is expected, that the instance reflects the master exactly, including its transformation attributes). *

The extract curve/surface tools automatically add such a tag to the instances they create.

To create such a tag manually, select the Instance object and enter into the Ayam console:

    addTag RP Transformations

.

This special case of an instance is sometimes also called reference.

### Instances and the Object Clipboard

It is not possible to copy a master object and some instances of it, so that the new instances point to the newly created master. All copies of instance objects always point to the same original master object.

For example, when the following two objects are copied and pasted back to the scene

> `

>     --NCurve   <-----
>                      |
>     --Instance  -----

> `

the following scene hierarchy results:

> `

>     --NCurve   <-------
>                      | |
>     --Instance  -----  |
>                        | !
>     --NCurve           |
>                        |
>     --Instance  -------

> `

The new instance still points to the original master and not to the copy of the master.

It is possible to move masters and instances through the scene hierarchy using drag and drop in the tree view or using the clipboard with `"Edit/Cut"` and then `"Special/Clipboard/Paste (Move)"`.

### Conversion Support

An Instance object may be converted to an ordinary object using the main menu entry `"Tools/Convert"`. This process is also called resolving the instance.

To resolve all instance objects in a scene to normal objects, one can also use the main menu entry: `"Special/Instances/Resolve all Instances"`.

### RIB Export

The RIB export of instances does not use the RiInstance facility of the RenderMan interface, but rather the more flexible ReadArchive mechanism.

This means, every master object in the scene will be written in a separate archive (RIB file) on disk, and every instance will cause that archive file to be read when rendering the RIB file. You can change this behaviour using the RIB export preference setting `"ResInstances"`: If `"ResInstances"` is enabled, all instances will be resolved temporarily to normal objects before being exported to RIB. The resulting RIB file will then be self contained.

## 4.11 Select Object

The Select object may be used in hierarchies of tool objects to select one object from a list of provided objects. * Also multiple objects and ranges (even decreasing ranges that lead to reversed orders) may be selected. *

In the following example hierarchy, a single patch from multiple provided patches of the Sweep object (the swept surface, a bevel, or a cap) could be selected by the Select object and delivered upstream to the ExtrNC object.

> `

>     +-Sweep
>     +-Revolve
>      +-ExtrNC
>       +-Select
>        \ Instance_of_Sweep(Instance)

> `

Note that this example just serves illustrative purpose; the hierarchy presented is not exactly useful, as the ExtrNC object has a selector facility built in. Consequently, the Select object should be used in scenarios, where a selector facility does not exist or is hard to implement, as e.g. in Script object scripts.

The following table briefly lists some capabilities of the Select object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Select | Any+ | No | N/A / Children+ | No

Select Object Capabilities

### SelectAttrib Property

- `"Indices"` designates the object(s) to select. The index values are zero based. Multiple indices must be separated by `","`, ranges can be specified like this `"1-4"`, reversed ranges are allowed (`"4-1"`) and will create an object list of reversed order. The special index `"end"` (or abbreviated `"e"`) designates the last of all the provided objects. An index may appear multiple times, leading to multiple copies of the selected object to be delivered upstream. The index space spans over all provided objects of the desired type from all child objects. This means one can mix provided objects from multiple child objects of the Select object. Syntactically incorrect ranges and indices are silently ignored.

  Examples:

  - `"0,2"` – delivers the first and third provided objects upstream;
  - `"end-0"` – delivers all provided objects in reversed order upstream;
  - `"0,0,0"` – delivers three copies of the first provided object upstream;
  - `"0,4-end,1"` – delivers the first, the fifth (if there are so many) up to the last, and the second object upstream.

### RIB Export

Select objects never appear in RIB output.

## 4.12 RiInc Object

RiInc objects may be used to include objects or whole scene parts into your scenes that, for some reason, are just available as a piece of RIB.

The following table briefly lists some capabilities of the RiInc object.

Type | Parent of | Material | Converts to / Provides | Point Edit
RiInc | No | No | N/A | No

RiInc Object Capabilities

The following attributes control the inclusion process:

### RiIncAttr Property

- Using `"File"` you specify the filename of the RIB to be included.
- `"Width"`, `"Height"`, and `"Length"` specify the size of a box, that will be drawn as a geometric representation of the RIB.

## 4.13 RiProc Object

RiProc objects may be used to include procedural objects or external archives into your scenes.

The following table briefly lists some capabilities of the RiProc object.

Type | Parent of | Material | Converts to / Provides | Point Edit
RiProc | No | No | N/A | No

RiProc Object Capabilities

The following attributes control the RiProc object:

### RiProcAttr Property

- `"Type"` defines the type of the procedural object which is one of `"DelayedReadArchive"`, `"RunProgram"`, or `"DynamicLoad"`.
- Using `"File"` you specify the filename of the RIB archive, program, or dynamic shared object (depending on the type of the procedural object).
- Using `"Data"` additional arguments may be supplied to procedural objects of type `"RunProgram"` and `"DynamicLoad"`.
- `"MinX"`, `"MaxX"`, `"MinY"`, `"MaxY"`, `"MinZ"`, and `"MaxZ"` specify the size of the bounding box of the objects that the procedural will create or the archive contains.

## 4.14 Box Object

A solid box, centered at the origin of the object coordinate system.

The following table briefly lists some capabilities of the Box object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Box | No | Yes | NPatch* | No*

Box Object Capabilities

The following parameters further control the shape of a box:

### BoxAttrib Property

- `"Width"` is the width of the box (size of the box in direction of the X axis of the objects coordinate system).
- `"Length"` is the length of the box (size of the box in direction of the Z axis of the objects coordinate system).
- `"Height"` is the height of the box (size of the box in direction of the Y axis of the objects coordinate system).

### Conversion Support

A box object may be converted to three NURBS patches using the main menu entry `"Tools/Convert"`. *

### RIB Export

The box object will always be exported as six bilinear patches.

## 4.15 Sphere Object

A sphere, centered at the origin of the object coordinate system.

The following table briefly lists some capabilities of the Sphere object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Sphere | No | Yes | NPatch+ | No*

Sphere Object Capabilities

The following parameters further control the shape of a sphere:

### SphereAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the sphere may be used in CSG operations safely.
- `"Radius"` is the radius of the sphere, default is 1.
- `"ZMin"` is the lower limit of the sphere on the Z axis, default is -1.
- `"ZMax"` is the upper limit of the sphere on the Z axis, default is 1.
- `"ThetaMax"` is the sweeping angle of the sphere in degrees, default is 360.

### Conversion Support

A sphere object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the sphere. *

If the sphere is closed, an enclosing Level object will be created and the caps follow the sphere in the following order: disk-shaped cap at zmin, disk-shaped cap at zmax, cap at theta 0, cap at thetamax.

### RIB Export

The sphere object appears in RIB output as simple

> ``RiSphere(...);``

or, if `"Closed"` is enabled and `"ZMin"`, `"ZMax"`, or `"ThetaMax"` have other than the default values, as complex CSG hierarchy of at most two spheres, two cylinders, and eight disks.

## 4.16 Disk Object

A disk in the XY plane, centered at the origin of the object coordinate system.

The following table briefly lists some capabilities of the Disk object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Disk | No | Yes | NPatch | No*

Disk Object Capabilities

The following parameters further control the shape of a disk:

### DiskAttr Property

- `"Radius"` is the radius of the disk, default is 1.
- `"ZMin"` displaces the disk along the Z axis, default is 0.
- `"ThetaMax"` is the sweeping angle of the disk in degrees, default is 360.

### Conversion Support

A disk object may be converted to a NURBS patch using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the disk. *

### RIB Export

The disk object will always be exported as simple disk:

> ``RiDisk(...);``

## 4.17 Cone Object

A cone, centered at the origin of the object coordinate system, with the base in the XY plane.

The following table briefly lists some capabilities of the Cone object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Cone | No | Yes | NPatch+ | No*

Cone Object Capabilities

The following parameters further control the shape of a cone:

### ConeAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the cone may be used in CSG operations safely.
- `"Radius"` is the radius of the cone at the base, default is 1.
- `"Height"` is the height of the cone, default is 1.
- `"ThetaMax"` is the sweeping angle of the cone in degrees, default is 360.

### Conversion Support

A cone object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the cone. *

If the cone is closed, an enclosing Level object will be created and the caps follow the cone in the following order: disk-shaped cap at the base, cap at theta 0, cap at thetamax.

### RIB Export

The cone object appears in RIB output as simple

> ``RiCone(...);``

or, if `"Closed"` is enabled and `"ThetaMax"` has a different than the default value, as complex CSG hierarchy of at most one cone, one disk, and two polygons.

## 4.18 Cylinder Object

A cylinder, centered at the origin of the object coordinate system.

The following table briefly lists some capabilities of the Cylinder object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Cylinder | No | Yes | NPatch+ | No*

Cylinder Object Capabilities

The following parameters further control the shape of a cylinder:

### CylinderAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the cylinder may be used in CSG operations safely.
- `"Radius"` is the radius of the cylinder, default is 1.
- `"ZMin"` determines the Z location of the base, default is -1.
- `"ZMax"` determines the Z location of the top, default is 1.
- `"ThetaMax"` is the sweeping angle of the cylinder in degrees, default is 360.

### Conversion Support

A cylinder object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the cylinder. *

If the cylinder is closed, an enclosing Level object will be created and the caps follow the cylinder in the following order: disk-shaped cap at zmin, disk-shaped cap at zmax, cap at theta 0, cap at thetamax.

### RIB Export

The cylinder object appears in RIB output as simple

> ``RiCylinder(...);``

or, if `"Closed"` is enabled and `"ThetaMax"` has a different than the default value, as complex CSG hierarchy of at most one cylinder, two disks, and two polygons.

## 4.19 Torus Object

A torus, centered at the origin of the object coordinate system. A torus is a donut like shape, that results from sweeping a small circle (that has been displaced along X sufficiently) around the Z axis.

The following table briefly lists some capabilities of the Torus object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Torus | No | Yes | NPatch+ | No*

Torus Object Capabilities

The following parameters further control the shape of a torus:

### TorusAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the torus may be used in CSG operations safely.
- `"MajorRad"` is the radius of the torus, measured from the Z axis to the center of the swept smaller circle, default is 0.75.
- `"MinorRad"` is the radius of the swept circle, default is 0.25.
- `"PhiMin"` determines an angle to limit the swept circle, default is 0.
- `"PhiMax"` determines an angle to limit the swept circle, default is 360.
- `"ThetaMax"` is the sweeping angle of the torus in degrees, default is 360.

### Conversion Support

A torus object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the torus. *

If the torus is closed, an enclosing Level object will be created and the caps follow the torus in the following order: disk-shaped cap at theta 0, disk-shaped cap at thetamax, ring-shaped cap at phimin 0, ring-shaped cap at phimax.

### RIB Export

The torus object appears in RIB output as simple

> ``RiTorus(...);``

or, if `"Closed"` is enabled and `"PhiMin"`, `"PhiMax"`, or `"ThetaMax"` have different than the default values, as complex CSG hierarchy of at most one one torus, two disks, and two hyperboloids.

## 4.20 Paraboloid Object

A paraboloid, centered at the origin of the object coordinate system.

The following table briefly lists some capabilities of the Paraboloid object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Paraboloid | No | Yes | NPatch+ | No*

Paraboloid Object Capabilities

The following parameters further control the shape of a paraboloid:

### ParaboloidAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the paraboloid may be used in CSG operations safely.
- `"RMax"` is the radius of the paraboloid at a Z of `"ZMax"`, the base of the paraboloid surface, default is 1.
- `"ZMin"` limits the paraboloid surface on the Z axis, must be positive, default is 0.
- `"ZMax"` limits the paraboloid surface on the Z axis and determines the Z location of the base, must be positive, default is 1.
- `"ThetaMax"` is the sweeping angle of the paraboloid in degrees, default is 360.

### Conversion Support

A paraboloid object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the paraboloid. *

If the paraboloid is closed, an enclosing Level object will be created and the caps follow the paraboloid in the following order: disk-shaped cap at zmin, disk-shaped cap at zmax, cap at theta 0, cap at thetamax.

### RIB Export

The paraboloid object appears in RIB output as simple

> ``RiParaboloid(...);``

or, if `"Closed"` is enabled and `"ZMin"`, `"ZMax"` or `"ThetaMax"` have different than the default values, as complex CSG hierarchy of at most one paraboloid, two disks, and two bicubic patches.

## 4.21 Hyperboloid Object

A hyperboloid, centered at the origin of the object coordinate system. The shape of the hyperboloid will be created by sweeping a line specified by two points in space around the Z axis. Thus, disk, cylinder, and cone are special cases of the hyperboloid.

The following table briefly lists some capabilities of the Hyperboloid object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Hyperboloid | No | Yes | NPatch+ | No*

Hyperboloid Object Capabilities

The following parameters further control the shape of a hyperboloid:

### HyperboloidAttr Property

- `"Closed"` toggles whether the object should be automatically sealed (closed by matching cap surfaces).
  Only when this option is enabled, the hyperboloid may be used in CSG operations safely.
- `"P1_X"`, `"P1_Y"` and `"P1_Z"`, define point one, default is (0, 1, -0.5).
- `"P2_X"`, `"P2_Y"` and `"P2_Z"`, define point two, default is (1, 0, 0.5).
- `"ThetaMax"` is the sweeping angle of the hyperboloid in degrees, default is 360.

### Conversion Support

A hyperboloid object may be converted to NURBS patches using the main menu entry `"Tools/Convert"`. This conversion obeys all parameters of the hyperboloid. *

If the hyperboloid is closed, an enclosing Level object will be created and the caps follow the hyperboloid in the following order: disk-shaped cap at P1, disk-shaped cap at P2, non-planar cap at theta 0, non-planar cap at thetamax.

### RIB Export

The hyperboloid object appears in RIB output as simple

> ``RiHyperboloid(...);``

or, if `"Closed"` is enabled and `"ThetaMax"` has a different than the default value, as complex CSG hierarchy of at most one hyperboloid, two disks, and two bilinear patches.

Note that due to a bug in BMRT that is still present in V2.3.6 the `"Closed"` option does not work properly when `"ThetaMax"` has a different than the default value and the hyperboloid has no displacement shader. In fact, using a displacement shader with a km (amount of displacement) of 0.0 is a work-around for this bug (found by T. E. Burge).

## 4.22 NCurve (NURBS Curve) Object

A simple NURBS Curve

The NCurve object is the most used basic object for NURBS modelling in Ayam because NURBS curves are used to build more complex smoothly shaped surfaces using operations like extrude, revolve, sweep or skin. NURBS curves can be open or closed and used to emulate Bezier and B-Spline curves easily. In addition, for easier modelling, they support multiple points, as explained in section Multiple Points.

The following table briefly lists some capabilities of the NCurve object.

Type | Parent of | Material | Converts to / Provides | Point Edit
NCurve | No | No | N/A | Yes

NCurve Object Capabilities

The next section details the NCurve object property.

### NCurveAttr Property

The first section of the NCurveAttr property contains curve specific settings:

- `"Type"`: This attribute replaces the `"Closed"` attribute since Ayam 1.9.

  The type `"Open"` is for the standard open NURBS curve.

  If the type is `"Closed"`, the first and last control point of the curve will be made identical. This will close the curve but without any guaranteed continuity. Such a closed curve will e.g. be created by the NURBS circle tool. It is important to know, that identical start/end control points alone can not guarantee that the curve is closed if the knot vector is not clamped. If in doubt, use the clamp tool or a knot vector of type `"NURB"`, `"Chordal"`, or `"Centripetal"`.

  If the type is `"Periodic"`, the last p control points of the curve will be made identical to the first p where p is the degree of the curve (read order-1). This will close the curve with guaranteed continuity. Note that for a cubic spline (order 4) you will need atleast 6 control points to make it periodic. It is important to know, that the multiple control points alone can not guarantee that the curve is closed if the knot vector has no periodic extensions. If in doubt, switch the curve to knot type `"B-Spline"`, `"Chordal"`, or `"Centripetal"`.

  You may also want to enable the creation of multiple points using the `"CreateMP"` attribute (see below) for closed and periodic curves so that single point editing actions modify all multiple control points.

- `"Length"` is the number of control points of the curve.
- `"Order"` is the order of the curve.
- `"Knot-Type"`: Using `"Knot-Type"` you may select from `"NURB"`, `"Bezier"`, `"B-Spline"`, `"Custom"`, `"Chordal"`, and `"Centripetal"` knot types.

  The knot type `"NURB"` will generate uniformly distributed knot values ranging from 0.0 to 1.0, where the multiplicity of the knots at the ends will be of order of the curve (the knot vector will be clamped). This guarantees that the curve will touch the control points at the ends of the curve. An example `"NURB"` knot vector for a curve of length 5 and order 4 would be:

  `{ 0.0 0.0 0.0 0.0 0.5 1.0 1.0 1.0 1.0 }`.

  The knot type `"Bezier"` will generate just 0.0 and 1.0 values. Note that the order of the curve has to be equal to the length of the curve if `"Bezier"` knots are generated. Otherwise, the generated knot sequence is illegal. The resulting curve looks and behaves exactly like a real Bezier curve, interpolating the control points at the ends and so on. An example `"Bezier"` knot vector for a curve of length 5 and order 5 would be:

  `{ 0.0 0.0 0.0 0.0 0.0 1.0 1.0 1.0 1.0 1.0 }`.

  The knot type `"B-Spline"` will generate uniformly distributed knot values (without any multiple knots). The resulting curve looks and behaves like a B-Spline curve. It is not interpolating the control end points. An example `"B-Spline"` knot vector for a curve of length 5 and order 4 would be:

  `{ 0.0 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1.0 }`.

  The knot types `"Chordal"` and `"Centripetal"` will generate knot values whose distribution reflect the distances of the control points. This only works, if there are free knots in the knot vector, i.e. knots that are not subject to clamping or periodic extensions (the default NURBS curve with 4 control points and order 4 has none). For open curves, the generated knot vector will be clamped, for periodic curves, proper periodic extensions will be created. Those knot types are mainly useful for curves with unevenly distributed control points that will be sampled uniformly (in parametric space) later on and where it is expected, that the uniform sampling in parameter space results in evenly distributed sample points in coordinate space, e.g. if the curves are used as Sweep, Birail, or Clone trajectory, or surfaces are created from them that use implicit texture coordinates or a uniform tesselation strategy. The `"Chordal"` and `"Centripetal"` knots will ensure a more uniform distribution of the sample points on the curve in such cases (see also the example image below). An example `"Chordal"` knot vector for an open curve of length 5 and order 4 would be:

  `{ 0.0 0.0 0.0 0.0 0.388889 1.0 1.0 1.0 1.0 }`.

  The image below illustrates the use of two curves with uniform (NURB) vs. chordal knot vectors as Sweep trajectories. The upper Sweep with the uniform knot vector has much more unevenly distributed/sized sections and exhibits more severe self intersection problems. Please note that the shapes of the curves differ slightly.

  Sweeps Created From Curves With Uniform (upper) And Chordal (lower) Knot Vectors

- `"Knots"` allows to enter own custom knot sequences. Note that `"Knots"` are not in use if `"Knot-Type"` (above) is of type `"NURB"`, `"B-Spline"`, `"Bezier"`, `"Chordal"`, or `"Centripetal"`. Note also, that the content of this parameter will be overwritten, if the knot type is switched to any of the aforementioned types.
- `"CreateMP"` toggles, whether multiple points should be created for this curve. See also the discussion in section Multiple Points.
- `"IsRat"` informs you, whether the curve is rational (uses weight values different from 1.0). *

The GLU-parameters control the appearance of the curve when curve/surface display is enabled.

- `"Tolerance"` is in fact GLU sampling tolerance, used to control the quality of the sampling when rendering a curve. Smaller tolerance settings lead to higher quality but also slower display. A setting of 0.0 means, that the global preference setting `"Drawing/Tolerance"` should be used.
- `"DisplayMode"` determines how the curve should be drawn. The control hull (control polygon) or the curve or a combination of both may be displayed. The setting `"Global"` means, that the global preference setting `"Drawing/NCDisplayMode"` should be used.

When changing more than one of the above values the changes will be applied in the order of the values in the property. The sum of the changed values should describe a valid NURBS curve. It is perfectly legal to change the length of the curve, it's order, and switch to a custom knot vector (be sure to actually enter a valid new knot vector) at once. Ayam will check your changes and fall back to certain default values if e.g. your knot sequence is wrong. Check the console for any messages after pressing the `"Apply"` button!

When the curve type is changed using the NCurveAttr property Ayam may also have to change the position of some control points as follows:

- When the type is changed from open to closed, the last control point is moved to be identical to the first one. In addition, if the current knot type of the curve is `"B-Spline"`, it will be reset to knot type `"NURB"`.
- When the type is changed from open or closed to periodic, the last p control points will be moved to be identical to the first p, where p is the degree of the curve (order-1). For a cubic curve (order 4), consequently, the last three control points will be moved. In addition, if the current knot type of the curve is `"NURB"` or `"Bezier"` it will be changed to `"B-Spline"` automatically.

When changing the order of a periodic curve (and not touching the length) Ayam will automatically add or remove control points to/from the curve so that the shape of the curve remains largely intact and the periodic extensions plausible. *

### Multiple Points

A NURBS Curve with Multiple Points (big handles)

The NURBS curves of Ayam support so called multiple points. A multiple point is made of a number of different control points that have the same coordinates. Modelling actions will always modify all the control points that make up a multiple point. Multiple points will be drawn with a bigger handle than normal points (see image above). They may e.g. be used to create closed curves. Note that the control points that make up a multiple point do not have to be consecutive (in the control point vector of the NURBS curve). Multiple points may be created using the collapse tool, and split up again using the explode tool (see sections Collapse Tool and Explode Tool for more information regarding those tools). Note that even though you might have exploded some multiple points Ayam will re-create them automatically on several occasions like reading of a scene, inserting/deleting points, and applying the NCurveAttr property if they still have identical coordinate values. In other words, you should immediately edit the control points (move them apart) after exploding to avoid that they automatically collapse to a multiple point again! You may also totally inhibit creation of multiple points for a NURBS curve using the attribute `"CreateMP"`.

### RIB Export

NCurve objects never directly appear in RIB output (only indirectly as trim curve).

## 4.23 ICurve (Interpolating Curve) Object

The ICurve object creates a global interpolating NURBS curve from n 3D non-rational ordered data points. The curve may be closed, the order of the curve may be configured, the parameterisation may be adapted, and end derivatives may be specified. The open versions create n+2 NURBS control points, and the closed ones n+3.

Different ICurves resulting from identical data point configurations (Upper Left: Open, Order 3; Upper Right: Open, Order 4; Lower Left: Closed, Order 3; Lower Right: Closed, Order 4)

The image above shows some interpolating curves, the left ones are of order 3 (quadratic curves), the right ones are of order 4 (cubic curves), the upper open, and the lower closed ones. The interpolation fidelity for the closed curves was tuned by adjusting the `"SDLen"` and `"EDLen"` parameters (all set to 0.2), see also the discussion of the parameters below.

In all parameterisation modes, knot averaging will be used to determine the knot vector of the interpolating curve.

Note that the axis of symmetry for closed interpolating curves crosses the first data point (in contrast to open interpolating or closed approximating curves, where it crosses between the last and first data point). For example, the closed interpolating curves in the above example image are indeed both symmetric, but the axis of symmetry is crossing the first and third data point and is, thus, rotated by 45 degrees.

This object makes use of the provide mechanism. It marks itself as providing a NCurve object (it creates and uses NURBS curves internally anyway) and all other objects that work with the provide mechanism (e.g. revolve, sweep, extrude, and skin) are able to work with an ICurve object instead of an object of type NCurve.

The following table briefly lists some capabilities of the ICurve object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ICurve | No | No | NCurve | Yes

ICurve Object Capabilities

The following parameters control the interpolation process:

### ICurveAttr Property

- The `"Type"` parameter controls whether the interpolated curve should be open or closed.
- `"Length"` is the number of data points to interpolate.
- The next parameter `"Order"` determines the desired order of the interpolating curve. If the specified order is bigger than the number of control points used by the interpolating NURBS curve, then the order is silently changed to match the number of control points.
- The parameter `"ParamType"` switches the parameterisation between `"Chordal"` (default), `"Centripetal"`, and `"Uniform"`. The centripetal method generates a better parameterisation than the default (chordal) if the input data contains sharp turns. The uniform method is available since Ayam 1.20 and generates worse parameterisations (that lead to wiggles and overshooting) in the general case but it might help in some edge cases.
- `"Derivatives"` allows to choose between automatic and manual derivatives. If automatic derivatives are switched on, the direction of the derivatives will be determined from the first, second, second to last, and last data points for open curves and from the second and second to last data points for closed curves. In addition, the respective derivative vector will be scaled by `"SDLen"` and `"EDLen"`. If manual dervivatives are is switched on, two more editable points appear in the single point editing modes. Those additional points directly control the derivatives in the endpoints of the interpolating curve. The parameters `"SDLen"` and `"EDLen"` do not influence those derivatives.
- The parameters `"SDLen"` and `"EDLen"` are used to control the length of the first and last derivative (if automatically generated from the data points, i.e. when `"Derivatives"` above is switched to automatic).
- See section NCurveAttr for a description of the parameters: `"Tolerance"` and `"DisplayMode"`.

- Finally, a `"NCInfo"` field informs about the actual configuration of the created NURBS curve.

The parameters `"Mode"`, `"Closed"`, and `"IParam"` are gone since Ayam 1.16. `"Closed"` was replaced by `"Type"`, `"IParam"` by `"SDLen"` and `"EDLen"`, and the `"Mode"` is now determined automatically from the desired order.

### Conversion Support

The interpolating curve may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

ICurve objects never directly appear in RIB output (only indirectly as trim curve).

## 4.24 ACurve (Approximating Curve) Object

Different ACurves (Upper Left: ALength 3, Order 3; Upper Right: ALength 4, Order 4; Lower Left: ALength 4, Order 4; Lower Right: ALength 6, Order 3)

The ACurve object creates an approximating NURBS curve with m control points from n 3D non-rational ordered data points (see image above). *

The number of data points must be higher than or equal to the number of control points used. The approximation algorithm used is of the least squares variety. If the number of control points approaches the number of data points, undesired wiggles in the output curve may occur.

This object makes use of the provide mechanism. It marks itself as providing a NCurve object (it creates and uses NURBS curves internally anyway) and all other objects that work with the provide mechanism (e.g. revolve, sweep, extrude, and skin) are able to work with an ACurve object instead of an object of type NCurve.

The following table briefly lists some capabilities of the ACurve object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ACurve | No | No | NCurve | Yes

ACurve Object Capabilities

The following parameters control the approximation process:

### ACurveAttr Property

- Using `"Length"` you determine the number of data points to approximate.
- Using `"ALength"` you determine the number of (distinct) control points to use for the approximating NURBS curve. The total number of distinct control points must be smaller than or equal to the number of data points.
- The curve can be closed with the parameter `"Closed"`. For closed approximations, the total number of control points will be `"ALength + Order - 1"`. The following table illustrates this relationship.

  Length | ALength | Order | Closed | Output Length
  10 | 5 | 3 | No | 5
  10 | 5 | 3 | Yes | 8
  10 | 4 | 4 | Yes | 8
  5 | 4 | 3 | No | 4
  5 | 4 | 3 | Yes | 7

  ACurve Parameterisation Examples

- For symmetric data point configurations, the approximating curve is not necessarily symmetric. With the parameter `"Symmetric"` a symmetric result can be enforced (see image below), albeit at the cost of about double runtime and a slightly worse parameterisation.

  Left: asymmetric ACurve, Right: symmetric ACurve

- The parameter `"Order"` specifies the desired order of the approximating NURBS curve. Currently, only orders higher than 2 are supported.
- See section NCurveAttr for a description of the parameters: `"Tolerance"` and `"DisplayMode"`.

- Finally, a `"NCInfo"` field informs about the actual configuration of the created NURBS curve.

### Conversion Support

The approximating curve may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

ACurve objects never directly appear in RIB output (only indirectly as trim curve).

## 4.25 NCircle (NURBS Circle) Object

Different NCircle Objects (l: default, m: TMax 180, r: Radius 0.5, TMax 200)

The NCircle object creates a circular NURBS curve or a circular arc in the XY plane centered at the origin with designated radius and start/end angles (see image above). *

In order to revert the created NURBS curve the start/end angles may be used, e.g. `"TMin"` 0.0, `"TMax"` -360.0 for a reverse full circle. *

The following table briefly lists some capabilities of the NCircle object.

Type | Parent of | Material | Converts to / Provides | Point Edit
NCircle | No | No | NCurve | No*

NCircle Object Capabilities

The following section describes the parameters of the circle or arc.

### NCircleAttr Property

- `"Radius"` is the radius of the circle.
- `"TMin"` (ThetaMin) controls the starting angle of the circle or arc to be created. Negative values are allowed.
- `"TMax"` (ThetaMax) controls the end angle of the circle or arc to be created. Negative values are allowed.
- See section NCurveAttr for a description of the parameters: `"Tolerance"` and `"DisplayMode"`.

- Finally, a `"NCInfo"` field informs about the actual configuration of the created NURBS curve.

### Conversion Support

The circular curve/arc may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

NCircle objects never directly appear in RIB output (only indirectly as trim curve).

## 4.26 ConcatNC (Concatenate NURBS Curves) Object

ConcatNC Object (blue) from a Linear Curve and 3 Instances (white)

The ConcatNC object concatenates all child objects (which should be NURBS curves or provide NURBS curves) to a single NURBS curve. Since the ConcatNC object also provides a NURBS curve, it is possible to use it as child object for another ConcatNC object (with possibly different parameters) or as a parameter object for a tool object that works with NURBS curves such as Revolve or Extrude.

The concatenation process works as follows:

1. The orders of all parameter curves will be elevated to the maximum order of all the parameter curves (see also section elevate tool for more information on elevation) and all curves will be clamped (see also section clamp tool for more information on clamping).
2. If the parameter `"FillGaps"` is enabled, fillet curves will be created for every gap between the parameter curves of the ConcatNC object. If `"Closed"` and `"FillGaps"` are enabled, an additional fillet is created to close the curve.
3. Now the control points of all parameter curves and fillets are simply copied into a new big control point vector, without checking for double points. This means that for parameter curves that touch at their respective ends, atleast double control points in the new concatenated curve will result.
4. If `"Closed"` is enabled, the curve will be closed.

The knot sequence of the new concatenated curve will be of type `"NURBS"` or a custom knot vector will be computed (depending on the setting of `"Knot-Type"`). If `"Knot-Type"` is `"NURBS"`, the shape of the concatenated curve will differ from the parameter curves if any of the parameter curves has a custom knot vector with non equidistant knots. If `"Knot-Type"` is `"Custom"`, the shape of the parameter curves will be preserved.

Attributes like display mode and tolerance for the new concatenated curve are simply taken from the first parameter curve.

The following table briefly lists some capabilities of the ConcatNC object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ConcatNC | NCurve+ | No | NCurve | No*

ConcatNC Object Capabilities

The following parameters further control the concatenation process:

### ConcatNCAttr Property

- Using `"Closed"` a closed concatenated curve may be created, even if the parameter curves do not touch. If also `"FillGaps"` (see below) is enabled, an additional fillet will be created for the last and the first child curve to close the concatenated curve. If `"FillGaps"` is not enabled, the concatenated curve will be closed with the same algorithm that is also used by the close curve tool (possibly changing its shape).
- If `"Revert"` is enabled, the orientation of the concatenated curve will be reversed.
- `"FillGaps"` creates fillet curves for all gaps between the parameter curves of the ConcatNC object. No fillet will be created if the end points of two parameter curves match.

  The fillet curves will initially be created from four control points. The outer fillet control points are the parameter curve end points and the inner fillet control points will be positioned on the tangent of the respective parameter curve end point (see also the discussion of `"FTLength"` below). Thus, the transitions between parameter curve and fillet should be atleast G1 continuous. Degree elevation will be used to raise the degree of the fillet to that of the concatenated curve; this may introduce additional control points in the fillet but its shape does not change and the transition continuity is also not affected.

  If the order of the resulting concatenated curve is 2, only simple fillets, connecting the parameter curves by straight lines, will be generated.

- `"FTLength"` determines the distance of the inner fillet control points from their respective end points. This value can be adapted for smaller / larger gaps between parameter curves.
- `"Knot-Type"` sets the knot type of the concatenated curve:
  - If `"Knot-Type"` is `"NURB"` a simple knot vector with equidistant knots is generated, which leads to a concatenated curve that does not exactly preserve the shapes of the original curves. Furthermore, all transitions between parameter curves are always smoothed out.
  - If `"Knot-Type"` is `"Custom"`, the knot vector is composed from the knot vectors of the original curves, and thus, their shapes may be preserved completely. This also applies to potential discontinuities in transitions.

    However, this comes at the price of internal knots with high multiplicity. Note that such a curve is not differentiable in all places anymore.

- Finally, a `"NCInfo"` field informs about the actual configuration of the created NURBS curve.

### Conversion Support

The concatenated curve may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

ConcatNC objects never directly appear in RIB output (only indirectly as trim curve).

## 4.27 ExtrNC (Extract NURBS Curve) Object

Extracted Curves (white) from Arbitrarily Shaped Surface (blue)

The ExtrNC object extracts a NURBS curve from a NURBS patch object, for use as parameter object for other tool objects, like e.g. Revolve (see image above). It also works with NURBS patch providing objects, so that the following example hierarchy is valid:

> `

>     --NPatch
>     +-Skin
>      +-ExtrNC
>      |\ Instance_of_NPatch(Instance)
>      \ NCurve

> `

Depending on the parameters of the ExtrNC object, the Skin object above will have one boundary in common with a boundary or an iso-curve of the NPatch object. Note that using an instance object of some other surface object (as shown in the above example) is in fact the recommended way of using the ExtrNC object. Therefore, the main menu entry `"Tools/Create/ExtrNC"` will automatically create an instance of the currently selected object and move it to the newly created ExtrNC object.

As the geometry of the extracted curve is completely defined by the master surface, ExtrNC objects do not support own transformation attributes. *

Note that the extraction of any curves currently completely ignores potentially present trimming information of the NPatch object.

The following table briefly lists some capabilities of the ExtrNC object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ExtrNC | NPatch | No | NCurve | No*

ExtrNC Object Capabilities

The extraction process is controlled by the following attributes:

### ExtrNCAttr Property

- `"Side"` controls which curve should be extracted from the surface. Available values are:
  - `"U0"`, `"Un"`: extract upper or lower boundary curve (along width);
  - `"V0"`, `"Vn"`: extract left or right boundary curve (along height);
  - `"U"`, `"V"` extract curve along width and height respectively at specified parametric value (see below). *
  - `"Boundary"`: extract the complete boundary curve of the patch. *
  - `"Middle_U"`, `"Middle_V"`: create a curve from the patch data that is the "middle axis" (simply the medium of all control points of a patch in the designated dimension). *
    This option is useful to re-engineer swept surfaces, delivered as simple patches.
  Note that if `"Side"` is `"U0"`, `"Un"`, `"V0"`, or `"Vn"` the extraction process just copies the respective boundary control points, which only works for clamped knot vectors. To extract a boundary from a surface with e.g. a B-Spline knot vector, one should not use `"U0"` but `"U"` with `"Parameter"` set to 0.0 and `"Relative"` enabled as `"U"` uses a different, more expensive, extraction process (which involves knot insertion).
- `"Parameter"` controls the parametric value in U or V direction in the parameter space of the NURBS patch object where the curve should be extracted. This parameter is only used when `"Side"` is `"U"` or `"V"`. The valid range of parameter values depends on the knot vectors of the NURBS patch.
- `"Relative"` controls whether the parametric value should be interpreted in a relative way. If enabled, a parametric value of 0.5 always extracts from the middle of the knot vector, regardless of the actual knot values, and the valid range for `"Parameter"` is then consequently 0.0-1.0. *
- `"Revert"` immediately reverts the extracted curve.
- `"CreatePVN"` controls creation of a PV tag that contains the normals (derived from the surface control points) on the surface. This PV tag can then be used to control a 3D offset curve.
- `"PatchNum"` allows to select a patch from a list of patches delivered e.g. by a beveled Extrude object as child of the ExtrNC object. This way it is possible to extract a curve from a bevel or cap surface of e.g. said Extrude object.

- Finally, a `"NCInfo"` field informs about the actual configuration of the extracted NURBS curve.

See section NCurveAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

### Conversion Support

The extracted curve may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

ExtrNC objects never directly appear in RIB output (only indirectly as trim curve).

## 4.28 OffsetNC (Offset NURBS Curves) Object

Offset Curves (white) from NURBS Curves (blue) with Offset 0.2, -0.2, and 0.3

The OffsetNC object creates offset curves from planar NURBS curves using four different algorithms. *
The offset curve will always match the original curve in type, length, order, and knots. See also the image above.

The available offset algorithms are:

`Point`
offsets each control point along the normal derived from the surrounding control points; the offset curve created by this algorithm may come too near the original curve at sharp convex features whose exact forms are not preserved well either,

`Section`
this algorithm offsets all control polygon sections in the direction of their normal and places new control points at intersection points of the lines defined by the offset sections; this algorithm is better in avoiding self intersections of the offset curve but the offset curve may be too far away from the original curve at sharp convex or concave features (regions of high curvature),

`Hybrid`
this algorithm offsets the curve two times using the Point and Section algorithms and then mixes the results so that the bad features of the two algorithms cancel out each other, *

`3DPVN`
Since Ayam 1.18 there is a fourth offsetting algorithm available, that creates true three dimensional offsets from non planar curves using a primitive variable tag that contains normal information for the curve (vertex normals). Such tags can be created manually or automatically e.g. when extracting curves from surfaces using the `"ExtrNC"` object.

As the geometry of the offset curve is completely defined by the master curve, OffsetNC objects do not support own transformation attributes. *

The `"Bevel3D"` offset algorithm has been removed since Ayam 1.19.

The following table briefly lists some capabilities of the OffsetNC object.

Type | Parent of | Material | Converts to / Provides | Point Edit
OffsetNC | NCurve | No | NCurve | No*

OffsetNC Object Capabilities

The following parameters further control the offsetting process:

### OffsetNCAttr Property

- The first parameter `"Mode"` determines, which algorithm to use for the offsetting process.
- Using `"Revert"` you may revert the direction of the offset curve.
- `"Offset"` determines the distance between original curve and offset curve. Negative values are allowed.
- See section NCurveAttr for a description of the parameters: `"Tolerance"` and `"DisplayMode"`.

- Finally, a `"NCInfo"` field informs about the actual configuration of the created NURBS curve.

### Conversion Support

The offset curve may be converted to an ordinary NURBS curve using the main menu entry `"Tools/Convert"`.

### RIB Export

OffsetNC objects never directly appear in RIB output (only indirectly as trim curve).

## 4.29 NPatch (NURBS Patch) Object

NURBS patch: surface (blue) from control polygon (white)

The NPatch object allows to model NURBS surfaces in a direct way, e.g. by modifying control points (see also the image above). Note that using NPatch objects should be seen as last resort, only to be used when the flexibility of all the NURBS surface creating tool objects is not high enough to achieve a certain shape.

Like NCurve objects, NPatch objects mark their last control point with a small arrow. Note that the arrow points in the V direction (height).

NPatch objects also support the concept of multiple points, see section Multiple Points for more information regarding this. *

The following table briefly lists some capabilities of the NPatch object.

Type | Parent of | Material | Converts to / Provides | Point Edit
NPatch | NCurve+/Level+ | Yes | PolyMesh | Yes

NPatch Object Capabilities

### NPatchAttr Property

The first section of the NPatchAttr property contains patch specific settings:

- `"Width"` and `"Height"` control the dimensions of the patch. Similar to the `"Length"` parameter of the NCurve object, changes to `"Width"` or `"Height"` add or remove internal control points (i.e. to double the resolution of a 4 by 4 NURBS patch in U direction, change the `"Width"` from 4 to 7; this will lead to an additional control point inserted into every section of the original patch).
- `"Order_U"` and `"Order_V"` set the orders of the patch.
- `"Knot-Type_U"`/`"Knot-Type_V"` and `"Knots_U"`/`"Knots_V"`: For a discussion of the `"Knot-Type"` and `"Knots"` parameters, please see section NCurveAttr.
- `"CreateMP"` toggles, whether multiple points should be created for this surface. See also the discussion in section Multiple Points. *
- `"IsRat"` informs you, whether the patch is rational (uses weight values different from 1.0). *

The next parameters control the appearance of the patch for display in Ayam:

- `"Tolerance"` is in fact the GLU sampling tolerance used to control the quality of the sampling when rendering the patch. Smaller tolerance settings lead to higher quality but also slower display. A setting of 0.0 means, that the global preference setting `"Drawing/Tolerance"` should be used.
- `"DisplayMode"` sets the display mode, either the control hull is drawn (`"ControlHull"`), or just the outlines of the polygons created by the tesselation (`"OutlinePolygon"`), or just the outlines of the patch (`"OutlinePatch"`). The default setting (`"Global"`) means, that the value of the global preference setting `"Drawing/NPDisplayMode"` should be used instead.

### Trim Curves

Trim curves may be used to cut out certain parts of a NURBS patch. They are simple 2D NURBS curves defined in the parametric space of the associated NURBS patch. Trim curves have to be defined as child objects of the NURBS patch object they belong to. In contrast to other child objects, however, they do not inherit the transformation attributes of the parent object. Trim curve editing should take place in views of type `Trim`, that draw the boundaries of the parametric space of the corresponding NURBS patch as rectangle, but otherwise act as normal `Front` views.

Note that the direction of the trim curve determines which part of the NURBS patch should be cut out. You can use the `Revert` tool (`Tools/NURBCurve` menu) to easily change the direction of a trim curve.

Some special restrictions apply to trim curves:

- All trim curves should entirely lie in the (u,v) parameter space of the NURBS patch (remember the rectangle in the `Trim` view). Note that this restriction does not apply to the control points, but the curves! It is ok to have control points outside the rectangle if the defined curve is inside the rectangle.
- The last point of a trim curve must be identical to the first point.
- Trim loops (multiple trim curves that form loops) are possible too; the last point of each curve in the loop must be identical to the first point of the next curve in the loop and the first point of the first curve of a loop must be identical to the last point of the last curve of that loop.
- To mark a set of curves to be a loop, they must be placed in a level object. The order of the curves in this level is the order of the loop. The transformation attributes of this level object are fully ignored for trimming.
- Drawing trimmed NURBS patches with certain implementations of OpenGL may require a special trim curve (a rectangular piecewise linear curve that encloses the whole NURBS patch) to be present. Such a curve may be generated with the `TrimRect` tool. You can find this tool in the `"Tools/Create"` menu. This curve is needed if you want to cut out a hole with a single trim curve. This curve is generally not needed if you want to render the patch with BMRT but it should not hurt if it is present.
- If there are nested trim curves, their direction must alternate.
- Trim curves may not intersect each other or themself.

Note that Ayam is not checking whether your trim curves follow these rules.

Warning: Certain OpenGL implementations may be easily crashed drawing trimmed NURBS patches with trims that do not follow the aforementioned rules. When in doubt or while heavy modelling, switch to wireframe drawing and switch off shading temporarily and you will be on the safe side.

NURBS curve providing objects are also supported as trim curves. *

### Conversion Support

A NPatch object may be converted to a PolyMesh object using the main menu entry `"Tools/Convert"`.

This process is also called tesselation and thus, the tesselation parameters from TP tags will be used in the conversion process (if present) (see also section TP Tag).

### RIB Export

NPatch objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported and also trim curves may appear.

## 4.30 IPatch (Interpolating Patch) Object

Interpolating surface (blue) from data points (white)

A IPatch forms a surface defined by interpolating a regular grid of three dimensional and non rational data points (see also the image above).

The following table briefly lists some capabilities of the IPatch object.

Type | Parent of | Material | Converts to / Provides | Point Edit
IPatch | No | Yes | NPatch | Yes

IPatch Object Capabilities

### IPatchAttr Property

The IPatchAttr property contains the following elements:

- `"Width"` and `"Height"` control the dimensions of the patch. Similar to the `"Length"` parameter of the NCurve object, changes to `"Width"` or `"Height"` add or remove internal control points (i.e. to double the resolution of a 4 by 4 interpolating patch in U direction, change the `"Width"` from 4 to 7; this will lead to an additional control point inserted into every section of the original patch).
- `"Order_U"` and `"Order_V"` set the desired interpolation orders of the patch. If any of these values is set to 2, no explicit interpolation will take place in this dimension (the surface will implicitly interpolate the data points due to the low order).
- `"Close_U"` and `"Close_V"` allow to create closed surfaces in the respective dimension.
- `"Knot-Type_U"` and `"Knot-Type_V"` switches the parameterisation between `"Chordal"` (default), `"Centripetal"`, and `"Uniform"`. The centripetal method generates a better parameterisation than the default (chordal) if the input data contains sharp turns. The uniform method generates worse parameterisations (that lead to wiggles and overshooting) in the general case but it might help in some edge cases.
- `"Deriv_U"` and `"Deriv_V"` toggle whether
  - `"None"`: no end derivatives,
  - `"Automatic"`: automatically created (from data points) derivatives, scaled by the additional parameters `"SDLen_U"`, `"EDLen_U"`, `"SDLen_V"`, and`"EDLen_V"`,
  - `"Manual"`: completely manually controlled end derivatives (appearing as additional control points in point editing, if enabled)
  should be used in the interpolation.

The next parameters control the appearance of the patch for display in Ayam:

- `"Tolerance"` is in fact the GLU sampling tolerance used to control the quality of the sampling when rendering the patch. Smaller tolerance settings lead to higher quality but also slower display. A setting of 0.0 means, that the global preference setting `"Drawing/Tolerance"` should be used.
- `"DisplayMode"` sets the display mode, either the control hull is drawn (`"ControlHull"`), or just the outlines of the polygons created by the tesselation (`"OutlinePolygon"`), or just the outlines of the patch (`"OutlinePatch"`). The default setting (`"Global"`) means, that the value of the global preference setting `"Drawing/NPDisplayMode"` should be used instead.

- Finally, a `"NPInfo"` field informs about the actual configuration of the created NURBS patch.

### Conversion Support

The interpolated surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

IPatch objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are currently not supported.

## 4.31 BPatch (Bilinear Patch) Object

Bilinear Patch

A BPatch is a simple bilinear patch defined by four control points. BPatch objects are e.g. used internally to build box objects, see also Box Object.

The following table briefly lists some capabilities of the BPatch object.

Type | Parent of | Material | Converts to / Provides | Point Edit
BPatch | No | Yes | NPatch | Yes

BPatch Object Capabilities

### BPatchAttr Property

The BPatchAttr property allows to directly control the four points defining the geometry of the patch:

- `"P1_X"`, `"P1_Y"`, `"P1_Z"`, first point.
- `"P2_X"`, `"P2_Y"`, `"P2_Z"`, second point.
- `"P3_X"`, `"P3_Y"`, `"P3_Z"`, third point.
- `"P4_X"`, `"P4_Y"`, `"P4_Z"`, fourth point.

### Conversion Support

The bilinear patch may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

BPatch objects will be exported as bilinear patch primitives:

> ``RiPatch(RI_BILINEAR, ...);``

PV tags are supported.

## 4.32 PatchMesh Object

Bicubic (left) and Bilinear (right) PatchMesh Surfaces (blue) from their Respective Control Polygons (white)

The PatchMesh object may be used to model with bilinear and bicubic patch meshes.

Like NCurve objects, PatchMesh objects mark their last control point with a small arrow. Note that the arrow points in the V direction (height).

The following table briefly lists some capabilities of the PatchMesh object.

Type | Parent of | Material | Converts to / Provides | Point Edit
PatchMesh | No | Yes | NPatch | Yes

PatchMesh Object Capabilities

### PatchMeshAttr Property

The first section of the PatchMeshAttr property contains patch specific settings:

- `"Type"` may be set to `"Bilinear"` or `"Bicubic"`.
- `"Width"` and `"Height"` control the dimensions of the patch.
- `"Close_U"` and `"Close_V"` determine, whether the patch mesh should be closed in U and V direction respectively.
- `"BType_U"` and `"BType_V"` control the basis type for bicubic patches. You may choose between the basis types: `"Bezier"`, `"B-Spline"`, `"Catmull-Rom"`, `"Hermite"`, and `"Custom"`. In the latter case (`"Custom"`), additional parameters may be set. Those are `"Step_U"`/`"Step_V"` (the stepsize of the basis) and `"Basis_U"`/`"Basis_V"` the basis itself (please see the RenderMan Companion for a discussion of basis types).

The parameters `"BType_U"` and `"BType_V"` and consequently `"Step_U"`/`"Step_V"` and `"Basis_U"`/`"Basis_V"` are only available to bicubic patch meshes.

The next parameters control the appearance of the patch for display in Ayam:

- `"Tolerance"` is in fact GLU sampling tolerance, used to control the quality of the sampling when rendering the patch. A setting of 0.0 means, that the global preference setting `"Drawing/Tolerance"` should be used.
- `"DisplayMode"` sets the display mode, either the control hull is drawn, or just the outlines of the polygons created by the tesselation (OutlinePolygon), or just the outlines of the patch (OutlinePatch). The default setting (Global) means, that the global preference setting `"Drawing/DisplayMode"` should be used.

### Conversion Support

The patch mesh may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`. However, this does not work for all possible types of patch meshes (e.g. patch meshes with the basis types Catmull-Rom, Hermite, or Custom can not be converted, currently). An internal NURBS patch representation is also in use when drawing the patch mesh (if the `"DisplayMode"` is not `"ControlHull"`) and when shading the patch mesh. Consequently, there is currently no shaded representation of patch meshes of basis type Catmull-Rom, Hermite or Custom.

### RIB Export

PatchMesh objects will be exported as patch mesh primitives:

> ``RiPatchMesh(...);``

PV tags are supported.

## 4.33 PolyMesh Object

The PolyMesh object may be used to include objects that have been modeled using the polygonal modelling paradigm in Ayam scenes.

There are no special modelling actions for this type of object, but you may select and modify single points as you can do it with other object types, e.g. curves.

The PolyMesh object is equivalent to the general points polygons primitive of the RenderMan interface. This means, each PolyMesh object may contain multiple general (convex or concave) polygons, which in turn may consist of an outer loop and an arbitrary number of inner loops that describe holes in the polygon. The loops use a point indexing scheme to efficiently reuse coordinate values. This general approach requires a so called tesselation to be carried out, in order for the PolyMesh object to be shaded. For the tesselation, Ayam uses routines of the GLU library.

Ayam is able to automatically create face normals for PolyMeshes. They will be calculated while tesselating the PolyMesh and be perpendicular to the plane determined by the first three vertices of the outer loop of a polygon. Furthermore, Ayam supports vertex normals (normals stored for every control point).

Note that storing a bunch of triangles each in its own PolyMesh object will lead to a real waste of memory. You may use the merge tool (main menu `"Tools/PolyMesh/Merge"`) to merge many PolyMesh objects into a single PolyMesh object.

The following table briefly lists some capabilities of the PolyMesh object.

Type | Parent of | Material | Converts to / Provides | Point Edit
PolyMesh | No | Yes | SDMesh | Yes

PolyMesh Object Capabilities

### PolyMeshAttr Property

The PolyMeshAttr GUI just displays some information about the PolyMesh object:

- `"NPolys"` the number of polygons.
- `"NControls"` the total number of control points defined.
- `"HasNormals"` is 1 if the object uses vertex normals, else it is 0.

### Conversion Support

PolyMesh objects may be converted to SDMesh objects using the main menu entry `"Tools/Convert"`. *

Note that no verification of the usability of the mesh as base mesh for a subdivision surface is carried out. Usually, such meshes have to be manifold and may not contain T-junctions.

### RIB Export

PolyMesh objects will be exported as RiPointsGeneralPolygons primitives (regardless of whether the actual configuration would fit into a simpler polygonal primitive of the RenderMan interface, e.g. a RiGeneralPolygon).

PV tags are supported.

## 4.34 SDMesh Object

SDMesh object with original polygonal mesh (blue)

The SDMesh object may be used to include objects that have been modeled using the subdivision modelling paradigm in Ayam scenes (see also the image above).

There are no special modelling actions for this type of object, but you may select and modify single points as you can do it with other object types, e.g. curves.

The SDMesh object is equivalent to the Subdivision Mesh primitive of the RenderMan interface. This means, each SDMesh object may contain multiple faces with arbitrary number of vertices that form a polygonal mesh. This polygonal mesh is then successively refined using a subdivision scheme and, depending on the number of refinement (or subdivision) steps, results in a more or less smooth surface. There are several different subdivision schemes, but the scheme currently supported by most RenderMan compliant renderers is named "Catmull-Clark".

Tags may be specified for faces, edges, or vertices to control the subdivision process (e.g. to create sharp corners or edges in the resulting surface). All tags known from the RenderMan interface (hole, crease, corner, and interpolateboundary) are supported by Ayam, but they may currently not be changed by the user.

Unless the `"subdiv"` plugin (available since Ayam 1.19) is loaded, Ayam is not able to do the subdivision and show the resulting smooth surface. All that is shown in wireframe and shaded views is the original polygonal mesh.

The following table briefly lists some capabilities of the SDMesh object.

Type | Parent of | Material | Converts to / Provides | Point Edit
SDMesh | No | Yes | PolyMesh | Yes

SDMesh Object Capabilities

### SDMeshAttr Property

The SDMeshAttr GUI just displays some information about the SDMesh object:

- `"Scheme"`, is the subdivision scheme, currently available schemes are Catmull-Clark and Loop. *
- `"Level"` is the number of subdivision steps that should be carried out when subdividing the mesh for preview. This subdivision needs the `"subdiv"` plugin.
- `"DrawSub"` allows to switch between the control polygon and the subdivided polygon outlines when drawing the mesh.
- `"NFaces"`, the number of faces.
- `"NControls"`, the total number of control points defined.

### Conversion Support

SDMesh objects may be converted to PolyMesh objects. *

Note however that only the original, unrefined, control polygon (i.e. the base mesh) will be converted unless the `"Level"` attribute is not zero and the `"subdiv"` plugin is loaded.

### RIB Export

SDMesh objects will be exported as subdivision mesh primitives:

> ``RiSubdivisionMesh(...);``

PV tags are supported.

## 4.35 Revolve Object

Revolve Object (left: Curve, right: Surface of Revolution)

The Revolve object forms a surface of revolution from a NURBS curve.

The Revolve object has the generating NURBS curve as child object and watches its changes and adapts to it automagically.

The axis of revolution is always the Y axis. The parameter curve should be defined in the XY plane. If not, it will be squashed down to this plane before revolving it.

The following table briefly lists some capabilities of the Revolve object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Revolve | NCurve | Yes | NPatch+ | No*

Revolve Object Capabilities

### RevolveAttr Property

The parameter `"ThetaMax"` specifies the sweeping angle of the revolution just like for an ordinary RenderMan quadric primitive.

The Revolve object also supports a B-Spline mode that may be enabled by setting the parameter `"Sections"` to a value higher than 0. * In this mode, a circular B-Spline is used as basis for the surface of revolution instead of the standard NURBS circle. Depending on the number of sections chosen, the surface of revolution does not exactly interpolate the parameter curve, but the surface may be edited more easily after a possible conversion to an ordinary NURBS patch object, because the control points will not be rational if the revolved curve is also not rational.
Note that also the B-Spline mode can realize arbitrary `"ThetaMax"` values. *

In addition to the number of sections, in B-Spline mode it is possible to control the order of the surface of revolution using the parameter `"Order"`. If `"Order"` is 0, a standard value of 3 will be used.

The revolve object can automatically generate caps, which are trimmed NURBS patches. Using the parameters `"UpperCap"`, `"LowerCap"`, `"StartCap"`, and `"EndCap"`, you determine whether such caps should be generated, default is off (no caps).

If the side caps of a surface of revolution of an open curve are not created correctly, GLU complains about "intersecting or misoriented trim curves", try to revert the revolved curve.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

### Conversion Support

The surface of revolution and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If caps are present, an enclosing Level object will be created and the caps follow the surface of revolution in the following order: upper, lower, start, end.

The Revolve object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Revolve objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps are present, those follow as trimmed NURBS patch primitives in the following order: upper, lower, start, end.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.36 Extrude Object

Extrude Object (left: Curve, middle: normal Extrusion, right: Extrusion with Caps)

The extrude object forms an extrusion from a number of planar NURBS curves.

The first curve determines the outline and the other curves determine holes in the extrusion object. Holes may be used by objects that form e.g. letters.

The object has the generating NURBS curves as child objects, watches them and adapts to them automagically.

Consequently, the object hierarchy of an Extrude object may look like this:

> `

>     +-Extrude
>      | Outline(NCurve)
>      | [Hole_1(NCurve)
>      | ...
>      \ Hole_n(NCurve)]

> `

The extrude object can generate caps, if the generating curves are closed. Cap generation may fail, if the outer curve has weights and the curve itself leaves the convex hull of the control polygon. Be careful when using curves with weights!

The sharp corners between caps and extrusion may be beveled.

The axis of the extrusion is always the Z axis. The parameter curves should be defined in the XY plane. If not, they will be squashed down to this plane. See section To XY Tool for information on how to easily achieve curves in the XY plane.

The dimensions and orders of the extruded surface(s) will be taken from the respective parameter curves as follows: width and order in U direction will be 2, height and order in V direction are taken from the parameter curve.

The following table briefly lists some capabilities of the Extrude object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Extrude | NCurve+ | Yes | NPatch+ | No*

Extrude Object Capabilities

### ExtrudeAttr Property

The parameter `"Height"` determines how big in Z direction the extrusion should be. Note that the height of the bevels will not be taken into account here, if the extrusion height is 1.0 and beveling (upper and lower) is switched on with radius 0.1 the resulting object extends 1.2 units in Z direction.

The extrude object can automatically generate caps, that are trimmed NURBS patches. Using `"StartCap"` and `"EndCap"` you determine whether such caps should be generated, default is off (no caps). Note that this feature does only work properly, if the generating NURBS curves are closed and not self intersecting, this is because the generating curves themselves are used as trim curves for the caps. Warning, Ayam will not check whether the parameter curves conform to these criteria. Ayam, however, automatically detects the correct orientation of the curves (and reverts them if necessary).

Since Ayam 1.10 the bevel parameters of the extrude object are saved in bevel parameter tags and the property GUI changed to conform to all other bevel supporting tool objects. The old options `"LowerBevel"`, `"UpperBevel"`, `"BevelType"`, and `"BevelRadius"` are no longer available. They were replaced with new dynamic tag creating bevel property GUI sections that are accessible through the new command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a corresponding bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

### Using Holes and Bevels

All curves forming holes in the extruded object must be defined inside (geometrically) the first curve (the outline curve). Additionally, they may not intersect each other or themself and one can not have hole curves inside hole curves. If there are bevels and caps, allow extra spacing between the curves (for the bevels). Ayam will not check whether the parameter curves conform to these criteria.

With the direction of the curve one decides the direction of the bevel as well (should it round outwards or inwards?). If the bevels of the holes look wrong try to revert the generating curves of the holes. Note that beveling does not work well with open curves. One should always use closed curves for beveling. Beveling may lead to self intersecting trim curves in sharp corners of an extrusion. Decrease the bevel radius or round the corners of the extruded curve (using insertion of additional control points) if cap generation fails due to self intersecting bevels.

Another special issue shall be noted: If there are holes, the corresponding bevels will be scaled with the hole curve object transformation values. Thus, to achieve equally sized bevels for outline and holes, possible scale transformations should be carried out on the hole curve control points, rather than on the hole curve object transformation attributes.

### Conversion Support

The extruded surface, the bevels, and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the bevels and caps follow the extruded surface in the following order: end bevel, end cap, start bevel, start cap.

The Extrude object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Extrude objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: end bevel, end cap, start bevel, start cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.37 Swing Object

Swing Object (left: Curves, right: Resulting Swung Surface)

The Swing object forms a surface that results from rotating a NURBS curve (cross section or profile) around an axis while scaling it according to a second NURBS curve (trajectory or path). *
This process is sometimes also called rotational sweep.

The swing object has the generating NURBS curves as child objects and watches their movements and adapts to them automagically. The first curve is the cross section, the second is the trajectory.

The object hierarchy of a Swing object, thus, looks like this:

> `

>     +-Swing
>      | Cross_Section(NCurve)
>      \ Trajectory(NCurve)

> `

The swing operation will occur around the Y-axis.

The base plane for the swing operation is the YZ-plane. The cross section curve should be defined in this plane and the trajectory should start here.

The dimensions and orders of the swung surface will be taken from the respective parameter curves as follows: width and order in U direction from the trajectory, height and order in V direction from the cross section.

The following table briefly lists some capabilities of the Swing object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Swing | NCurve* | Yes | NPatch+ | No*

Swing Object Capabilities

### SwingAttr Property

The attributes `"UpperCap"`, `"LowerCap"`, `"StartCap"`, and `"EndCap"` may be used to automatically create cap surfaces, that close the Swing on the respective ends. Note that this works properly only if the corresponding parameter curve is closed and planar.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the Swing, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

### Conversion Support

The swung surface and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If caps are present, an enclosing Level object will be created and the caps follow the swung surface in the following order: upper, lower, start, end.

The Swing object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Swing objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps are present, those follow as trimmed NURBS patch primitives in the following order: upper, lower, start, end.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.38 Sweep Object

Sweep Object (left: Curves, right: Resulting Swept Surface)

The Sweep object forms a surface that results from moving a NURBS curve (cross section or profile) along a second NURBS curve (trajectory or path). The cross section may be scaled while sweeping using a third curve, the scaling function. Swept surfaces may be closed in the direction of the trajectory and, since Ayam 1.10, they may even be periodic.

The Sweep object has the generating NURBS curves as child objects and watches their movements and adapts to them automagically. The first curve is the cross section, the second is the trajectory, and the third curve represents the scaling function.

The object hierarchy of a Sweep object, thus, looks like this:

> `

>     +-Sweep
>      | Cross_Section(NCurve)
>      | Trajectory(NCurve)
>      \ [Scaling_Function(NCurve)]

> `

Note that the `"Translate"` attributes of the cross section curve will be fully ignored. All other transformation attributes (of cross section and trajectory) will be used to determine place, orientation, and size of the Sweep object.

The cross section curve has to be defined in the YZ-plane of the Sweep objects coordinate system but it also has to be defined in the XY-plane of its own coordinate system. This means that a simple circular curve as e.g. created with the toolbox has to be rotated by 90 degrees around the Y-axis using its transformation attributes to follow these rules. Later editing of this curve has to be done in a Side view (or in an aligned local Front view, if the Sweep object itself is transformed somehow).

The scaling function is sampled for each section and the Y-component of the coordinates of the current curve point will be used as scale factor that is applied to the cross section in Y-direction.

If any sample point of the scaling function has a Z-component different from zero, the Z-component will be used to independently scale the cross section in X-direction, otherwise the Y-component will be used to also scale the cross section in X-direction. *

This implies, that e.g. a scaling function that does nothing should be a linear curve from (0,1,1) to (1,1,1). Scale components that are less than or equal to zero will be silently ignored.

Sweep Object (blue) with Scaling Function (white)

Here is a short example for the creation of a sweep:

1. Create a circular B-Spline curve using the toolbox. (This will be our cross section.)
2. Rotate the curve by 90 degrees around the Y-axis. (Use the `"Transformations"` property for that.)
3. Create a simple NURBS curve using the toolbox. (This will be our trajectory.)
4. Select both curves. (Select the first curve, hold down the `"Shift"` key and select the other curve.)
5. Create the Sweep object using the toolbox.
6. Now you may enter the Sweep object and modify e.g. the second curve, the trajectory. (Press `<e>`, then drag some control points around.)
7. To modify the cross section you would need to switch to a view of type `"Side"`. (Use the views `"Type"` menu or the `<PgDwn>` keyboard shortcut while the view has the input focus.)

Section Easy Sweep has an example script that automates creation and parameterisation of a suitable cross section curve.

The following table briefly lists some capabilities of the Sweep object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Sweep | NCurve* | Yes | NPatch+ | No*

Sweep Object Capabilities

### SweepAttr Property

The `"Type"` attribute controls whether the swept surface should be open, closed, or periodic in the direction of the trajectory curve. *

If `"Interpolation"` is enabled, an additional interpolation will be run on the swept surface in U direction so that all section curves will be interpolated by the swept surface. Instead of a NURBS knot vector, the swept surface will then get a Chordal knot vector (calculated by knot averaging) and the swept surface will follow the trajectory more closely. See the image below for an example.

Sweep Along a Quarter Circle without (left) and with (right) Interpolation Enabled

The third parameter, `"Sections"`, determines how many sections (in U direction) should be used, when generating the sweep NURBS patch. The sweep NURBS patch has sections+1 control points in U direction for open and closed sweep types whereas sections+order control points will be created for periodic sweep types.
Also zero is a valid setting for the `"Sections"` parameter and used as default value. * If `"Sections"` is zero the number of sections is directly derived from the length of the trajectory curve plus one (except for trajectory curves of length 2, where it is 1). See the table below for examples.
Consequently, if `"Sections"` is zero, for a standard NURBS curve of length 4, the number of sections used is 5 and the width of the created NURBS patch is 6, for a curve with just 2 control points, the number of sections used is 1 and the width of the resulting patch is 2.
Moreover, if `"Sections"` is zero, the order of the sweep in U direction is taken from the trajectory curve. Otherwise, the order of the created patch depends on the number of sections as follows: for 1 and 2 sections the order will be 2 and 3 respectively, in all other cases it will be 4.

If `"Rotate"` is enabled, the cross sections will be rotated so that they are always perpendicular to the trajectory, this enabled by default.

The attributes `"StartCap"` and `"EndCap"` may be used to automatically create cap surfaces, that close the Sweep on both ends. Note that this works properly only if the cross section curve is closed and planar (defined in the XY plane).

Also bevels are available for sweeps. * They are accessible through the command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a corresponding bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the sweep, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

The following table shows some example parameter configurations for the Sweep object.

Sections | Trajectory Length | Trajectory Order | Sweep Length | Sweep Order
0 | 2 | 2 | 2 | 2
0 | 5 | 4 | 6 | 4
0 | 6 | 5 | 7 | 5
4 | 6 | 5 | 5 | 4
10 | 6 | 5 | 11 | 4

Sweep Parameterisation Examples

### Conversion Support

The swept surface, the bevels and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the bevels and caps follow the swept surface in the following order: start bevel, start cap, end bevel, end cap.

The Sweep object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Sweep objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: start bevel, start cap, end bevel, end cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.39 Birail1 Object

Birail1 Object (left: Curves, right: Resulting Swept Surface)

The Birail1 object forms a surface by sweeping a cross section (or profile) curve along two so called rail curves. The object hierarchy of a Birail1 object, thus, looks like this:

> `

>     +-Birail1
>      | Cross_Section(NCurve)
>      | Rail1(NCurve)
>      \ Rail2(NCurve)

> `

When the cross section touches the rail curves in their respective starting points, the resulting surface will interpolate the rail curves. The direction of the cross section curve will be parallel to the V parametric dimension (height) and the direction of the rail curves will be parallel to the U parametric dimension (width) of the resulting surface. Height and width of the surface will be derived from the length of the cross section curve and the number of sections, respectively.

Valid Configuration of Parameter Curves (white) for Birail1 (blue)

The image above shows a valid configuration of parameter curves for the Birail1 object. Mind the direction of the rail curves (R1 and R2) with regard to the cross section curve (CS) and the fact that the cross section curve touches the starting points of the rail curves.

Note that the cross section curve does not have to be two dimensional, and, in contrast to the normal Sweep object, it also does not have to be defined in a special plane. Also note that the precision with which the resulting surface will interpolate the rail curves depends on the number of sections chosen.

The Birail1 object watches the child objects and adapts to them automatically via the notification mechanism.

The following table briefly lists some capabilities of the Birail1 object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Birail1 | NCurve* | Yes | NPatch+ | No*

Birail1 Object Capabilities

The following parameters further control the birailing process:

### Birail1Attr Property

Similar to the `"Sweep"`, the `"Type"` attribute controls whether the swept surface should be open, closed, or periodic in the direction of the birail curves.

The parameter `"Sections"` determines how many sections (in U direction) should be used, when generating the birailed NURBS patch. The birailed NURBS patch always has sections+1 control points in U direction.
Also zero is a valid setting for the `"Sections"` parameter and used as default value. *
If `"Sections"` is zero the number of sections is directly derived from the length of the first rail curve plus one (except for curves of length 2, where it is 1). See the table below for examples.
Moreover, if `"Sections"` is zero, the order of the birail in U direction is taken from the first rail curve. Otherwise, the order of the created patch depends on the number of sections as follows: for 1 and 2 sections the order will be 2 and 3 respectively, in all other cases it will be 4.

The attributes `"StartCap"` and `"EndCap"` may be used to automatically create cap surfaces, that close the birailed surface on the respective end. Note that this only works properly if the cross section curve is closed and planar (e.g. defined in the XY plane).

Since Ayam 1.10 bevels are available for birails. They are accessible through the new command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a corresponding bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the birail, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

The following table shows some example parameter configurations for the birail object.

Sections | Rail1 Length | Rail1 Order | Birail1 Length | Birail1 Order
0 | 2 | 2 | 2 | 2
0 | 5 | 4 | 6 | 4
0 | 6 | 5 | 7 | 5
4 | 6 | 5 | 5 | 4
10 | 6 | 5 | 11 | 4

Birail1 Parameterisation Examples

### Conversion Support

The birailed surface, the bevels, and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the bevels and caps follow the birailed surface in the following order: end bevel, end cap, start bevel, start cap.

The Birail1 object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Birail1 objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: end bevel, end cap, start bevel, start cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.40 Birail2 Object

Birail2 Object (left: Curves, right: Resulting Swept Surface)

The Birail2 object forms a surface by sweeping a cross section (or profile) curve along two so called rail curves, while morphing it into a second cross section (or profile) curve. The morphing process may be controlled by a fifth parameter curve. The object hierarchy of a Birail2 object, thus, looks like this:

> `

>     +-Birail2
>      | Cross_Section1(NCurve)
>      | Rail1(NCurve)
>      | Rail2(NCurve)
>      | Cross_Section2(NCurve)
>      \ [Interpolation_Control(NCurve)]

> `

When the cross sections touch the rail curves in their respective starting points, the resulting surface will interpolate the rail curves. The direction of the cross section curves will be parallel to the V parametric dimension (height) and the direction of the rail curves will be parallel to the U parametric dimension (width) of the resulting surface. Height and width of the surface will be derived from the length of the cross section curves and the number of sections, respectively.

Valid Configuration of Parameter Curves (white) for Birail2 (blue)

The image above shows a valid configuration of parameter curves for the Birail2 object. Mind the direction of the rail curves (R1 and R2) with regard to the two cross section curves (CS1 and CS2) and the fact, that all curves touch at their respective end points.

Note that the cross section curves do not have to be two dimensional, and, in contrast to the normal Sweep object, they also do not have to be defined in a special plane. Furthermore, they do not have to be compatible in terms of length, order, and knots. Incompatible curves will be made compatible before birailing automatically; the height of the resulting surface, however, is not easily predictable anymore in this case. Also note that the precision with which the resulting surface will interpolate the rail curves depends on the number of sections chosen.

If a fifth curve is present as parameter object, this curve will control the morphing (interpolation) process. The y coordinate of this curve at a specific point, which should have a value between 0 and 1, determines the ratio of control of the first cross section (0) and the second cross section (1) over the interpolated curve. Thus, a straight line running from point (0,0) to (1,1) will be equivalent to the standard linear interpolation that would be carried out if no interpolation control curve were present. Note, however, that the interpolation control curve has no influence on the first and last copy of the respective cross section curve, unless the `"InterpolCtrl"` option is used. *

The Birail2 object watches the child objects and adapts to them automatically via the notification mechanism.

The following table briefly lists some capabilities of the Birail2 object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Birail2 | NCurve* | Yes | NPatch+ | No*

Birail2 Object Capabilities

The following parameters control the birailing process:

### Birail2Attr Property

The parameter `"Sections"` determines how many sections (in U direction) should be used, when generating the birailed NURBS patch. The birailed NURBS patch always has sections+1 control points in U direction.
Also zero is a valid setting for the `"Sections"` parameter and used as default value. *
If `"Sections"` is zero the number of sections is directly derived from the length of the first rail curve plus one (except for curves of length 2, where it is 1). See the table below for examples.
Moreover, if `"Sections"` is zero, the order of the birail in U direction is taken from the first rail curve. Otherwise, the order of the created patch depends on the number of sections as follows: for 1 and 2 sections the order will be 2 and 3 respectively, in all other cases it will be 4.

The parameter `"InterpolCtrl"` allows the interpolation controlling curve full influence on the birailed surface. If `"InterpolCtrl"` is disabled, the first and last border of the resulting surface will always exactly match the parameter curves (CS1 and CS2 respectively), regardless of the interpolation control curve.

The attributes `"StartCap"` and `"EndCap"` may be used to automatically create cap surfaces, that close the birailed surface on the respective end. Note that this only works properly if the cross section curve is closed and planar (e.g. defined in the XY plane).

Since Ayam 1.10 bevels are available for birails. They are accessible through the new command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a corresponding bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the birail, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

The following table shows some example parameter configurations for the birail object.

Sections | Rail1 Length | Rail1 Order | Birail2 Length | Birail2 Order
0 | 2 | 2 | 2 | 2
0 | 5 | 4 | 6 | 4
0 | 6 | 5 | 7 | 5
4 | 6 | 5 | 5 | 4
10 | 6 | 5 | 11 | 4

Birail2 Parameterisation Examples

### Conversion Support

The birailed surface, the bevels, and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the bevels and caps follow the birailed surface in the following order: end bevel, end cap, start bevel, start cap.

The Birail2 object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Birail2 objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: end bevel, end cap, start bevel, start cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.41 Skin Object

Skin Object (left: Curves, right: Resulting Skinned Surface)

The skin object forms a surface defined by a set of cross section curves, where the first and last curve will always be interpolated by the surface (this process is sometimes also called lofting). When only two parameter curves are used the skin forms a so called ruled surface.

The complete template for the Skin object hierarchy, consequently, looks like this:

> `

>     +-Skin
>      | C_1(NCurve)
>      | C_2(NCurve)
>      | [...
>      \ C_n(NCurve)]

> `

Note that in contrast to the build from curves tool, the curves may be of arbitrary length and order. One may e.g. easily use a parameter curve of order 2 and length 6 with a second curve of order 4 and length 4 and a third curve with order 3 and 5 control points. If the curves are of different length or order, they will all be converted internally until they are compatible. Be warned, that this process may consume a considerable amount of time because all unclamped curves have to be converted to clamped ones; then, for every curve with low order degree elevation has to be done; then a uniform knot vector has to be found; then all curves have to be refined using this new knot vector; interpolation adds another dimension of complexity. If you experience lags when editing the child curves of a skin object try to switch to lazy notification. Since Ayam 1.9, a skin object will also use all the curves of a tool object, that provides multiple curves, e.g. a clone object in mirror mode.

The direction of the parameter curves will be parallel to the v dimension (height) of the skinned surface. The number of the parameter curves will define the u dimension (width) of the skinned surface.

Also note that the resulting patch may be quite complex, even though the curves are not, if the orders or knot vectors of the curves do not match. For example, a skinned patch from two curves of length 4 but one with order 4 and the other with order 2 will result in a patch with a width of 2 and a height of 10.

The skin object has the generating NURBS curves as child objects and watches their changes and adapts to them automagically.

The following table briefly lists some capabilities of the Skin object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Skin | NCurve* | Yes | NPatch+ | No*

Skin Object Capabilities

The following parameters control the skinning process:

### SkinAttr Property

The first parameter `"Interpolation"` controls whether the inner curves should also be interpolated by the skinning surface.

The second parameter `"Order_U"` determines the order of the resulting surface in U direction (the order in V direction is determined by the curves). The order may not be higher than the number of curves used. If the specified value is higher than the number of curves, the order of the generated surface will be silently set to the number of curves. If `"Order_U"` is 0, a default value of 4 will be used.

Using the next parameter `"Knot-Type_U"`, you can adapt the type of the knot vector that should be used in the U direction of the skinned surface. Note that this setting will have no effect if interpolation is switched on because then a chord length parameterisation will be used. If the knot type is Bezier and the specified order (see above) does not exactly match the number of skinned curves, then the order will be silently adapted to the number of skinned curves. New in Ayam 1.7 is support for the knot type Custom, which creates a chord length parameterisation, even if interpolation is not enabled.

The attributes `"StartCap"` and `"EndCap"` may be used to automatically create cap surfaces to close the skinned surface on both ends. Note that this works only if the respective curves are closed and planar (e.g. defined in the XY plane). Furthermore, if the skin is not interpolating the respective parameter curves (this may be the case if the `"Knot-Type_U"` parameter is set to `"B-Spline"`) the cap(s) will not be created in the right place. The cap(s) will always be created in the position of the first (last) parameter curve.

Since Ayam 1.10 bevels are available for skins. They are accessible through the new command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a corresponding bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the skin, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

### Conversion Support

The skinned surface, the bevels, and the caps may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the bevels and caps follow the skinned surface in the following order: end bevel, end cap, start bevel, start cap.

The Skin object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Skin objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: end bevel, end cap, start bevel, start cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.42 Gordon Object

Gordon Object (left: Curves, right: Resulting Gordon Surface)

The Gordon object forms a surface defined by two sets of intersecting curves (a network of curves), where all curves will always be interpolated by the surface (see image above). The image below shows the simplest configuration of such a network, consisting of four parameter curves. Note the arrangement and the direction of the curves. Also note that this configuration is in fact equivalent to a Coons patch.

Gordon Surface with Parameter Curves (white)

The curves may be of arbitrary length and order. One may e.g. use a curve of order 2 and length 6 with a second curve of order 4 and length 4 and a third curve with order 3 and 5 control points for the U parametric dimension. Note, however, that in the general case only non-rational curves can be used as parameter curves for a Gordon surface. If the parameter curves are rational, the weight information of the curves will simply be ignored. However, since Ayam 1.13 there is a special case allowed: if exactly four parameter curves are present, their weight information will be used properly. Mind that for a correct surface interpolation the curves weights have to match in the respective end points.

The Gordon object has the generating NURBS curves as child objects and watches their changes and adapts to them automagically. Separation of the two sets of curves has to be done using an empty level object. The first set of curves determines the u direction and the second set of curves the V direction of the Gordon surface. For the example surface in the image above, the child objects of the Gordon object would have to look like this in the Ayam object tree view:

> `

>     +-Gordon
>      | U1(NCurve)
>      | U2(NCurve)
>      | Level
>      | V1(NCurve)
>      \ V2(NCurve)

> `

The creation of a Gordon surface is computationally expensive. It involves (interpolated) skinning of the two sets of parameter curves, finding the intersection points of the two sets of parameter curves, interpolating the matrix of intersection points, making the three resulting surfaces compatible, and finally combining the three surfaces into the resulting Gordon surface. If there are lags while editing the parameter curves of a Gordon surface, consider switching to lazy notification.

In order to ease the computationally intensive intersection detection for Ayam one may specify a third argument (separated from the two sets of parameter curves by a second empty level object). This third argument should be a NURBS patch object that describes all intersection points (by its control points). If present, this intersection patch always takes precedence over the intersection points calculated internally. One may want to add a `"NoExport"` tag to this patch, to prevent it from appearing in RIB output.

The object hierarchy of a Gordon object using such a patch may look like this:

> `

>     +-Gordon
>      | U1(NCurve)
>      | U2(NCurve)
>      | Level
>      | V1(NCurve)
>      | V2(NCurve)
>      | Level
>      \ Intersections(NPatch)

> `

The complete template for the Gordon object hierarchy, consequently, is as follows:

> `

>     +-Gordon
>      | U1(NCurve)
>      | U2(NCurve)
>      | [...
>      | Un(NCurve)]
>      | Level
>      | V1(NCurve)
>      | V2(NCurve)
>      | [...
>      | Vn(NCurve)]
>      | [Level
>      \ Intersections(NPatch)]

> `

The Gordon object watches the child objects and adapts to them automatically via the notification mechanism.

The following table briefly lists some capabilities of the Gordon object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Gordon | NCurve*/Level | Yes | NPatch+ | No*

Gordon Object Capabilities

The following parameters of the Gordon object further control the creation of the Gordon surface:

### GordonAttr Property

If the parameter `"WatchCurves"` is switched on, Ayam will check for all four outer parameter curves, whether they touch in their endpoints. If not, the endpoints will be corrected. Note that this works only properly with clamped curves and objects that directly contain editable control points (i.e. it works with NCurve and ICurve objects, but not with Instance or ConcatNC objects). If Ayam can determine which curve was modified last, the other curve that should meet at the endpoint in question will be modified by `"WatchCurves"`. If Ayam finds no information on modifications, the U curves take precedence (i.e. the V curves will be modified).

The parameters `"Order_U"` and `"Order_V"` determine the desired order of the resulting surface in U and V direction. However, depending on the number and configuration of curves used in the U or V direction, it may not be possible to create a Gordon surface of the desired order. If `"Order_U"` or `"Order_V"` are 0, a default value of 4 will be used.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

To help in the exact configuration of the Gordon surface, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

### Conversion Support

The Gordon surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

Gordon objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.43 Bevel Object

Bevel Object (left: Curve, right: Resulting Bevelled Surface)

The bevel object forms a bevelled surface from a single planar parameter curve. The bevel cross section shape may be defined by a second curve. Consequently, the template for the object hierarchy of a Bevel object looks like this:

> `

>     +-Bevel
>      | NCurve
>      \ [NCurve]

> `

Bevels are also available as properties of different tool objects (e.g. Extrude or Sweep). In fact, Bevel objects use the same creation algorithm as bevel properties but offer increased flexibility in terms of e.g. material settings. Surfaces created from bevel properties always share the material settings of the tool object. In contrast, Bevel objects may have their own material settings. Bevel objects are available in Ayam since version 1.10.

Note that the parameter curve of a Bevel object should be closed and planar to achieve best results; see section To XY Tool for information on how to easily achieve this. If the curve is closed or periodic, the appropriate curve type should be set in the curve object, otherwise the bevelled surface may expose defects.

Since Ayam 1.19 the bevel object supports a second parameter curve that defines the bevels cross section shape. It should run from 0,0 to 1,1. If present, the type parameter is ignored (with one notable exception) as the shape of the bevel is defined by the second curve. If the type is `"RoundCapped"` or `"LinearCapped"` the bevel will be extended to a cap. Note that even if the curve should end at 1,1, this is not mandatory and allows for bevels of differing width and height to be created.

The Bevel object watches the child object and adapts to it automatically via the notification mechanism.

The following table briefly lists some capabilities of the Bevel object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Bevel | NCurve+ | Yes | NPatch | No*

Bevel Object Capabilities

The following parameters of the Bevel object further control the creation of the bevelled surface:

### BevelAttr Property

- `"BevelType"` lets you choose between different shapes of bevels:
  - `"Round"` a quarter circle,
  - `"Linear"` a straight bevel,
  - `"Ridge"` a more complex ridged surface,
  - `"RoundCapped"` a quarter circle followed by a cap made by placing a single point in the center of the last bevel profile and extending the beveled surface to this point,
  - `"LinearCapped"` a straight bevel followed by a cap made by placing a single point in the center of the last bevel profile and extending the beveled surface to this point.
  Note that the bevel types `"RoundCapped"` and `"LinearCapped"` lead to degenerated NURBS surfaces. If applied shaders or textures look wrong, consider creation of real cap surfaces instead.
- `"BevelRadius"` controls the size of the bevelled surface when seen from the top of the parameter curve. Note that the size of the bevel is expressed in units defined by the object coordinate system of the controlling object. Scale values of the controlling object affect the bevel size.
- `"BevelRevert"` allows to revert the sense of the bevelled surface, should it round inwards or outwards? The sense may also be controlled using the direction of the parameter curve and, additionally, the sense in a different dimension may also be affected by using negative values for the bevel radius.

See section NPatchAttr for a description of the two attributes `"DisplayMode"` and `"Tolerance"` of the `"BevelAttr"` property.

To help in the exact configuration of the bevel, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

### Conversion Support

The bevelled surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

Bevel objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported. *

## 4.44 Cap Object

Cap Object (left: Curve, right: Resulting Cap Surface)

The cap object forms a surface that fills a closed planar NURBS curve. If multiple curves are present as child objects, the curves following the first curve define holes in the cap surface similar to the parameter curves of an extruded surface (see also section Using Holes and Bevels).

Cap from Non-Planar Curve (left: Curve, right: Resulting Cap Surface)

Since Ayam 1.13 the cap object also supports the so called Gordon mode. Here, only a single parameter curve may be present but, in contrast to the standard mode of operation (Trim), in the Gordon mode the parameter curve may be non-planar. Internally the cap object will split the parameter curve into four sections and build a Gordon surface from the four sections (see the image above for an example).

Consequently, the template for the object hierarchy of a Cap object looks like this:

> `

>     +-Cap
>      | Outline(NCurve)
>      | [Hole1(NCurve)]
>      +-[Hole2(Level)
>       | Part1(NCurve)
>       \ Part2(NCurve)]

> `

Note that, in Trim mode, the curves have to be planar and defined in the XY plane; see section To XY Tool for information on how to easily achieve this. Furthermore, cap generation may fail, if the control points of the first curve have weights and the curve leaves the convex hull of the control polygon. Be careful when using weights!

The Cap object watches the child objects and adapts to them automatically via the notification mechanism.

The following table briefly lists some capabilities of the Cap object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Cap | NCurve+ | Yes | NPatch | No*

Cap Object Capabilities

The following parameters control the cap creation process:

### CapAttr Property

The attribute `"Type"` determines whether a trimmed NURBS surface should be created (type `"Trim"`), or an untrimmed Gordon surface (type `"Gordon"`), see also the general discussion about the cap object above.

See section NPatchAttr for a description of the two attributes `"DisplayMode"` and `"Tolerance"` of the `"CapAttr"` property.

To help in the exact configuration of the cap, the `"NPInfo"` field always displays the parameters of the created NURBS patch.

### Conversion Support

The cap surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

Cap objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported. *

## 4.45 ConcatNP (Concatenate NURBS Patches) Object

ConcatNP Object (white) From Two NURBS Patches (blue)

The ConcatNP object concatenates all child objects, which should be NURBS patches or provide NURBS patches to a single NURBS patch (see also the image above). *

The concatenation simply splits all surfaces into curves, makes the curves compatible, and joins them to the concatenated surface.

Also NURBS curves or objects that provide NURBS curves can be used as parameter objects. *

Since the ConcatNP object also provides a NURBS patch, it is possible to use it as child object for another ConcatNP object (with possibly different parameters).

Attributes like display mode and tolerance for the new concatenated patch are simply taken from the first parameter patch. Eventually present trim curves will currently not be honored properly.

The following table briefly lists some capabilities of the ConcatNP object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ConcatNP | NPatch*/NCurve* | Yes | NPatch | No*

ConcatNP Object Capabilities

The following parameters further control the concatenation process:

### ConcatNPAttr Property

- Using `"Type"`, open, closed, or periodic concatenated patches may be created. If a closed surface is to be created and also `"FillGaps"` (see below) is enabled, an additional fillet will be created for the last and the first child curve to close the concatenated curve.
- `"Order"` is the desired order of the concatenated surface (in U direction), the default value (0) leads to a cubic surface. If the desired order is 1, the respective order from the first of the parameter surfaces is taken. If the desired order is higher than the number of curves (i.e. the total number of control points of all surfaces in their desired directions plus the number of eventually present parameter curves), it will be lowered to the number of curves silently.
- `"FillGaps"` creates fillet surfaces for all gaps between the parameter surfaces of the ConcatNP object. No fillet will be created if the end curves of two parameter surfaces match or if parameter curves are present between the parameter surfaces in question.

  Similar to the fillets for concatenated curves, the fillet surface will be constructed from four control points (in U direction). However, the tangent vectors will not be calculated directly, but instead derived from the respective control points.

- `"FTLength"` determines the distance of the inner fillet control points from their respective end points. This value can be adapted for smaller / larger gaps between parameter surfaces. If this parameter is negative, the distance between the two surfaces in the end points will be multiplied in so that a more pleasing fillet shape results in configurations where the distances vary a lot (see also the image below).

  Concatenated Surfaces (blue) with Fillets (left: FTLength 0.3, right: FTLength -0.3

- If `"Revert"` is enabled, the orientation of the concatenated surface will be reversed (in U direction).
- The `"Knot-Type"` parameter allows to choose a knot vector for the concatenated surface in U direction. Similar to the ConcatNC object, only `"Custom"` knots allow to preserve the shapes of the parameter surfaces completely but this comes at the price of multiple internal knots (see also ConcatNCAttr Property). In addition, for `"Custom"` knots, all parameter surfaces will be elevated to a common maximum order or atleast be clamped in the respective direction prior to the splitting to curves but after the fillet creation.
- The `"UVSelect"` option is a string that can be used to control the splitting direction for each parameter surface individually. Valid characters in this string are `"u"`, `"U"`, `"v"`, and `"V"`. The uppercase variants lead to a reverted surface. To connect two surfaces that share the same orientation "over a corner" one would e.g. need to set `"UVSelect"` to `"uV"` (see also the image below). The default, an empty string, is equivalent to `"u"` for all patches. Also incomplete strings lead to `"u"` for all remaining patches. There is no need to specify a value for fillets, those will always be created in a way that they can be split along the U direction.

  Concatenating two Surfaces with UVSelect == "uV"

- Finally, a `"NPInfo"` field informs about the actual configuration of the created NURBS patch.

### Conversion Support

The concatenated surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

ConcatNP objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported. *

## 4.46 ExtrNP (Extract NURBS Patch) Object

Extracted Surface (white) from Arbitrarily Shaped Surface (blue)

The ExtrNP object extracts a NURBS patch from another NURBS patch object, for use as parameter object for other tool objects (see image above). *

It also works with NURBS patch providing objects, so that the following example hierarchy is valid:

> `

>     --NPatch
>     +-ExtrNP
>      \ Instance_of_NPatch(Instance)

> `

Note that using an instance object of some other surface object (as shown in the above example) is in fact the recommended way of using the ExtrNP object. Therefore, the main menu entry `"Tools/Create/ExtrNP"` will automatically create an instance of the currently selected object and move it to the newly created ExtrNP object.

As the geometry of the extracted surface is completely defined by the master surface, ExtrNP objects do not support own transformation attributes. *

Also note that eventually present trim curves will not be honored properly.

The following table briefly lists some capabilities of the ExtrNP object.

Type | Parent of | Material | Converts to / Provides | Point Edit
ExtrNP | NPatch | Yes | NPatch | No*

ExtrNP Object Capabilities

The extraction process is controlled by the following attributes:

### ExtrNPAttr Property

- `"UMin"`, `"UMax"`, `"VMin"`, and `"VMax"` are parametric values that control which part of the original surface is to be extracted. The valid range of parameter values depends on the knot vectors of the original surface.
- `"Relative"` controls whether the parametric values should be interpreted in a relative way. * If enabled, a parametric value of 0.5 always extracts from the middle of the knot vector, regardless of the actual knot values, and the valid range for the parametric values is then consequently 0.0-1.0.
- `"PatchNum"` allows to select a patch from a list of patches delivered e.g. by a beveled extrude object as child of the ExtrNP object. This way it is possible to extract a patch from a bevel or cap surface of e.g. a Revolve object.
- See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

- Finally, a `"NPInfo"` field informs about the actual configuration of the extracted NURBS surface.

### Conversion Support

The extracted surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

ExtrNP objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported. *

## 4.47 OffsetNP (Offset NURBS Surfaces) Object

Offset Surface (white) from NURBS Surface (blue) with Offset 0.2

The OffsetNP object creates offset surfaces from NURBS surfaces using a simple algorithm. * The offsetting also works for closed and periodic surfaces in any possible combinations in the two dimensions. *

Note that degenerate and rational surfaces are still not supported.

The offset surface will always match the original surface in width/height, orders, and knots. See also the image above.

As the geometry of the offset surface is completely defined by the master surface, OffsetNP objects do not support own transformation attributes. *

The following table briefly lists some capabilities of the OffsetNP object.

Type | Parent of | Material | Converts to / Provides | Point Edit
OffsetNP | NPatch | Yes | NPatch | No*

OffsetNP Object Capabilities

The following parameters further control the offsetting process:

### OffsetNPAttr Property

- `"Offset"` determines the distance between original surface and offset surface. Negative values are allowed.
- See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

- Finally, a `"NPInfo"` field informs about the actual configuration of the created NURBS surface.

### Conversion Support

The offset surface may be converted to an ordinary NURBS patch using the main menu entry `"Tools/Convert"`.

### RIB Export

OffsetNP objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are supported. *

## 4.48 Text Object

Text Object set in Verdana

Text objects may be used to easily create objects that form letters or even whole words in very high quality. For that, they parse TrueType font description files, extract the Bezier curves from the font description, sort the curves, connect them properly and finally extrude them. As with the Extrude objects, caps and bevels may be created automatically.

Parsing of TrueType font descriptions is quite tricky. For the sake of brevity and ease of the implementation, Ayam does not support elaborate TrueType features like kerning tables, that e.g. control distances between certain letters (You are not going to typeset a book with Ayam anyway, aren't you?). Therefore you might experience wrong letter distances from time to time. If this happens, just create a Text object for each letter, and arrange the objects as you like.

You may convert the current Text object to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

The following table briefly lists some capabilities of the Text object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Text | No | Yes | NPatch+ | No*

Text Object Capabilities

The following attributes control the creation of the text objects.

### TextAttr Property

- Using `"FontName"` you specify a TrueType font description file. Those files usually have the file name extension `".ttf"`. Only real TrueType font files, containing Bezier curve font descriptions, are supported. There are also rastered, bitmap containing TrueType font description files, those will not work.
- Using `"String"` you specify the letters to be created. This entry (and the corresponding data structures) are Unicode clean. This means you can put any Unicode letters into this entry. You should of course make sure, that the specified letters are included in the selected font file.
- `"Height"` controls the height of the extruded object.
- `"Revert"` reverts the sense of inside-outside detection mechanism for the cap generation. Depending on the actual font description file (or even letter) you may need to toggle this to get caps.
- `"UpperCap"`, `"LowerCap"`, work like for the Extrude object (see section ExtrudeAttr Property for a more exhaustive description of those parameters).
- `"Add Start Bevel!"`, `"Add End Bevel!"`: Since Ayam 1.10 the bevel parameters of the text object are saved in bevel parameter tags and the property GUI changed to conform to all other bevel supporting tool objects. The old options `"LowerBevel"`, `"UpperBevel"`, `"BevelType"`, `"BevelRadius"`, and `"RevertBevels"` are no longer available. They were replaced with new dynamic tag creating bevel property GUI sections that are accessible through the new command entries `"Add Start Bevel!"` and `"Add End Bevel!"` respectively. If one of those entries is used, a bevel parameter tag is created and more options will be made available in the property GUI to adjust the bevel parameters or remove the tag again. A more thorough discussion of those options is available in section BevelAttr Property.

  Just one note: for some fonts, the bevel radius has to be set to really small values (about 0.0008) to get proper bevels and caps. This is because of sharp corners in some letters that lead to self overlapping borders of the bevel surfaces with high values for the bevel radius.

See section NPatchAttr for a description of the other two attributes `"DisplayMode"` and `"Tolerance"`.

### Conversion Support

The extruded surfaces, the bevels, and the caps, may be converted to ordinary NURBS patches using the main menu entry `"Tools/Convert"`.

If bevels or caps are present, an enclosing Level object will be created and the caps follow the extruded surfaced in the following order: end bevel, end cap, start bevel, start cap.

The Text object provides a list of NURBS patch objects in the same order as created upon conversion.

### RIB Export

Text objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

If caps or bevels are present, those follow as potentially trimmed NURBS patch primitives in the following order: end bevel, end cap, start bevel, start cap.

PV tags are supported but all NURBS patch primitives will get the same set of tags. *

## 4.49 Trim Object

The Trim object may be used in hierarchies of tool objects to trim NURBS patch providing objects otherwise unavailable to trimming like e.g. a Revolve object. * The first child of the Trim object is the NURBS patch providing object and the second object is the trim curve (defined in the parametric space of the NURBS surface). More curves and loops may follow. All curves must obey the rules for trimming as outlined in section Trim Curves. The surface may already be trimmed and there may be multiple provided patches, however only one of them will be trimmed by the Trim object.

The object hierarchy of a Trim object, thus, looks like this:

> `

>     +-Trim
>      | Surface(Revolve)
>      | Trim_1(NCurve)
>      +-[Trim_2(Level)
>      | | NCurve
>      | \ NCurve
>      | ...
>      \ Trim_n(ICurve)]

> `

The following table briefly lists some capabilities of the Trim object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Trim | NPatch/NCurve+/Level+ | Yes | NPatch | No

Trim Object Capabilities

The following parameters further control the trimming process:

### TrimAttrib Property

- `"PatchNum"` allows to select a patch, should the NURBS patch providing object deliver a list. This way, a bevel of an extrusion might be trimmed.

### Conversion Support

The trimmed surface may be converted to an ordinary NURBS patche using the main menu entry `"Tools/Convert"`.

### RIB Export

Trim objects will be exported as NURBS patch primitives:

> ``RiNuPatch(...);``

PV tags are currently not supported.

## 4.50 Script Object

Script objects are the most flexible object type of Ayam. They may be used to create new objects, modify existing objects, or realise mechanisms like constraints using small scripts that are embedded in the Script objects themselves.

Those small embedded scripts may employ functionality from Tcl and the Tcl scripting interface of Ayam (see also section Scripting Interface).

Script objects may also use arbitrary, plugin provided, scripting languages, like e.g. JavaScript, provided by the `"jsinterp"` plugin (see also: JavaScript Scripting Interface). *

### Safe Interpreter

In Ayam versions prior to 1.16 Script object scripts could use any functionality of Tcl, Tk, and the Tcl scripting interface of Ayam which posed a huge security risk. This is no longer the case. Script objects scripts now run in a safe interpreter with reduced instruction set. They can no longer write to the file system, get onto the network, or confuse the application state. Direct access to Tk is also completely blocked, but Script objects still can have their own property GUIs (refer to the examples below).

In particular, the following Tcl commands are not available in the safe interpreter: cd, encoding, exec, exit, fconfigure, file, glob, load, open, pwd, socket, source, unload; auto_exec_ok, auto_import, auto_load, auto_load_index, auto_qualify, unknown (the missing unknown and autoloading facilities lead to further unavailability of commands normally available via autoloading, like e.g. parray, history). The puts command is available in a limited fashion: only access to the stdout and stderr channels is allowed. Ayam scripting interface commands that directly manipulate the user interface are also not available (uS, rV etc.). Please refer to the documentation of the scripting interface commands about their availability in the safe interpreter (see section Index of Procedures and Commands).

In addition, access to global variables like env, ay, ayprefs is not allowed. In fact, the safe interpreter has a completely separate set of variables. Transfer of data between both interpreters must be arranged manually from the Ayam interpreter (e.g. scripts that run in the Ayam console).

With the help of scripts, that run in the Ayam interpreter, more commands may be transfered to or made available in the safe interpreter. But this may, of course, open security holes again.

You can also still re-enable full access from script objects to the complete scripting interface by recompiling Ayam. If you do so, for security reasons, if scene files containing script objects are loaded, Ayam will raise a warning dialog, offering to temporarily disable all script objects that will be read. The script objects will be disabled using the `"Active"` script object property and may be enabled after careful inspection of the script code manually or using the main menu entry `"Special/Enable Scripts"`.

### Script Object Usage

The script of a script object will be run each time the script is modified and each time the notification callback of the script object is called (e.g. because one of the children of the script object changed). As long as the script of a script object is executed, Ayam will not process any events except for checking whether the script emergency hotkey `<Ctrl+Shift+c>`, that may also be used to escape from infinite loops in the Ayam console, is pressed. Calling commands and procedures that lead to the processing of events or that are slow because they manipulate or update the GUI of Ayam should be avoided. In particular, the following procedures and commands should not be used: uS, uCR, uCL, selOb, plb_update, undo!

Since Ayam 1.8.2 script objects may also create their own property GUIs for e.g. script parameters. This may be accomplished by adding tags of type `"NP"` with the name of the new property as value to the script object. The script itself is responsible for data management and property GUI creation.

Since Ayam 1.9 the parameters set via a new property GUI may be comfortably saved with scene files by just adding the following comment as first line to the script:

    # Ayam, save array: <arrayname>

where arrayname designates the name of the global Tcl array the property GUI elements operate with. Note that with the introduction of individual parameters in Ayam 1.15 not all members of the arrays will be saved. Only members from the `"SP"` list (see below) will be considered, which gives script object developers fine grained control over what actually goes to the Ayam scene file.

Since Ayam 1.12 there is also a tag type to remove properties (`"RP"`). Using this tag, one can e.g. hide the actual script code and block users from unintentionally changing it.

Since Ayam 1.15 script objects can have individual sets of parameters, so that multiple copies of a script object can be used (without individual parameters all copies would share the same parameter values). For this, the new variable `"SP"` in the script data array contains a list of parameter names in that array that are individual (not shared by all copies of the script object).

Starting with Ayam 1.16, the environment for running script objects scripts has been refined to allow more complex scripts (that traverse the scene or use the clipboard) to be written: When a script is running, the current level is the child level of the respective script object. Furthermore, the object clipboard is saved for running the script and re-established after the script finished.

Since Ayam 1.18 Script objects may also use arbitrary, plugin provided, scripting languages. To switch to a different language, the first line of the script must be a comment (in the syntax of the other language) with the word `"use:"` followed by the language name, as provided by the corresponding plugin, e.g. for JavaScript the first line should look like this:

    /* Ayam, use: JavaScript */

The special comments for saving of array items and language switching can be used in conjunction like this:

    /* Ayam, use: JavaScript, save array: MyArr */

The binary and source distributions of Ayam contain several example scripts for script objects in the `"ayam/bin/scripts"` and `"ayam/src/scripts"` directories, respectively. In addition, there are example scene files using script objects in the `"ayam/scn/scripts"` directory.

The following table briefly lists some capabilities of the Script object.

Type | Parent of | Material | Converts to / Provides | Point Edit
Script | Any+ | No | Any+ | No*

Script Object Capabilities

The next section discusses the available script object types and additional controlling parameters.

### ScriptAttr Property

- If `"Active"` is disabled, the script will not be run.
- `"Type"` is the type of the script object. Three types of script objects are currently available:
  - `"Run"`, the script will be run and no special action will take place.
  - `"Create"`, the script will be run and will create and parameterise new objects. After running the script, the newly created object(s) will automatically be moved into the internal data structure of the script object. The script object will look like and act as an object of the type that the script created. If the script creates e.g. a NCurve object, the script object may be used as parameter object of a tool object that needs a NCurve, e.g. a Sweep:

    > `

    >     +-Sweep
    >      | Cross_Section(Script)
    >      \ Path(NCurve)

    > `

    If the newly created object has to be selected by the script code for further parameterisation purposes, the selection should be done using the scripting interface command `"sL"` (which performs a hidden selection in the safe interpreter context). Consequently, the most simple example script for a script object of type `"Create"` looks like this:

        crtOb NCurve

    Or, with further parameterisation

        crtOb NCurve
        sL
        setProperty NCurveAttr(Order) 2

  - `"Modify"`, if the script object has child objects, these child objects will be temporarily moved into the internal data structure of the script object. A copy of all child objects will be created as new children of the script object. A selection of the new child objects will be established, then the script will be run. Usually, the script modifies one of the selected objects (moves control points, adds tags, or does something similar). Afterwards, the two sets of objects will be exchanged, the modified objects will be moved to the internal data structure of the script object while the unmodified original child objects will again be child objects of the script object. The modified objects will be provided upstream to potential parents. If certain actions in the script shall be restricted to one of the child objects of the script object, the `"withOb"` command may be used to accomplish this easily. The script object will look like and act as an object of the type of the first child object of the script object. If the script object has e.g. a NCurve object as first child, the script object may be used as parameter object of a tool object that needs a NCurve, e.g. a Sweep:

    > `

    >     +-Sweep
    >      +-Cross_Section(Script)
    >      |\ NCurve
    >      \ Path(NCurve)

    > `

    A simple example script for a script object of type `"Modify"` that needs a single NURBS curve as child object may look like this:

        revertC

    Note: In order to make this work for objects providing NURBS curves (interpolating curves or instances of NURBS curves) the code has to look like this:

        convOb -inplace; revertC

- `"Script"` is the script code. The corresponding widget is a standard Tcl text widget that allows to directly edit the code. It is also possible to edit the code in an external editor and copy it to the script object using the operating system clipboard and the `"Paste (Replace)"` context menu entry of the text widget. If the first line of the script is a comment like

      # Ayam, save array: <arrayname>

  then the global Tcl array `<arrayname>` will be saved with the script object to Ayam scene files. The array must contain an entry `"SP"` that lists all individual parameters of the script object. Note that only parameters from this list will be saved to Ayam scene files. Note also, that `"SP"` must never contain `"SP"`. All copies of a script object must share the same set of individual vs. shared parameters. If objects need to store differing/individual amounts of parameter data, lists can be used as individual parameters.

### Script Object Examples

This section illustrates the development of a script object for parametric lines, otherwise unavailable in Ayam.

We start with a simple version, that first creates a NURBS curve object with two control points and then places the control points each at +/- half the desired line length on the x axis. Just copy the following code to the Script property of a script object of type `"Create"`, and activate it.

    set length 1
    crtOb NCurve -length 2
    sL
    setPnt 0 [expr {-$length/2.0}] 0.0 0.0 1.0
    setPnt 1 [expr {$length/2.0}] 0.0 0.0 1.0

Simple Script for Parametric Line Primitive

This code works, but if lines of a different length than 1 are needed, the user must edit the script which is not very convenient and error prone. A complete, easy to use, and safe GUI for the length parameter can be added by changing the script code (`"# ^^^"` lines designate changed or added code):

    # Ayam, save array: LineAttrData
    if { ![info exists ::LineAttrData] } {
        array set ::LineAttrData {
            Length 1
            SP {Length}
        }
    }
    if { ![info exists ::LineAttrGUI] } {
        set w [addPropertyGUI LineAttr]
        addParam $w LineAttrData Length
    }
    set length $::LineAttrData(Length)
    # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    crtOb NCurve -length 2
    sL
    setPnt 0 [expr {-$length/2.0}] 0.0 0.0 1.0
    setPnt 1 [expr {$length/2.0}] 0.0 0.0 1.0

and by adding a `"NP"` (new property) tag to the script object with the value `"LineAttr"`, resulting in a new clickable graphical user interface as can be seen in the following image:

Parametric Line Primitive with Parameter GUI

The GUI setup code creates a Tcl array essential to manage the data of an Ayam object property (LineAttrData). Then, the LineAttr property GUI is created and a GUI element is added to the GUI using `"addParam"`. Note that the `"addPropertyGUI"` command expects for a property named `"SomePropertyName"` a corresponding property data array named `"SomePropertyNameData"` to exist. The GUI setup code should just run once, therefore it checks for the presence of the variable LineAttrGUI (which is set on the first run of `"addPropertyGUI"`) first. See also section Global Property Management and Data Arrays for more information about property GUIs and the Ayam scripting interface.

Finally, to enable saving of the parameter value in the new property `"LineAttr"` to scene files, a comment must be prepended to the script (`"Ayam, save array: LineAttrData"`), and to enable multiple and individually parameterised copies of this script object, a `"SP"` entry needs to be added to the `"LineAttrData"` array as well.

The complete script is also available as example script file `"scripts/crtlinegui.tcl"` in the Ayam distribution.

In addition, a second example demonstrates the scene traversal and hierarchy building capabilities available to script objects since Ayam 1.16. Create a script object, and add two children to it, a box and a NURBS curve (order 2, knot type: chordal works best). Then add the following script to the script object:

    # this script needs object type "Modify" and two children:
    # a box/sphere and a curve
    withOb 1 {estlenNC len}
    cutOb
    crtOb Clone
    goDown -1
    pasmovOb
    goUp
    sL
    getProp
    set CloneAttrData(NumClones) [expr round($len)]
    setProp

This little script first determines the length of the curve, then it creates a Clone object and moves the children of the Script object to it (via the object clipboard). Finally, the Clone object is parameterised, so that the trajectory is completely filled (assuming that each copy of the first child needs 1 length unit on the trajectory) with objects. One may now modify the curve using interactive modelling actions, change its length, and the trajectory is always completely filled. See example image below (compare the Clone configurations from the two different trajectory curves):

Hierarchy Building Script Object Example

## 4.51 Custom Objects

Custom objects are plugins that extend the Ayam capabilities by defining totally new types of e.g. geometric objects. This may be done easily, because the Ayam core is written in a modelling paradigm independent way.

A simple example of a custom object is the CSphere, which implements a simple sphere and has a new property named `"CSphereAttr"`. This property contains all parameters of a simple RenderMan Interface quadric sphere. A more complex example would be the MetaObj custom object. It is possible, but not planned for now, to integrate the T-Spline modelling paradigm into Ayam this way.

Since a custom object has total control over properties and representations, you should refer to the documentation of the respective custom object for more information regarding its properties.

One custom object is already distributed with Ayam. This Metaball custom object is documented in the next section:

## 4.52 Metaball Object

A Metaball Object from Six Meta Components

A metaball object is a custom object (see also section Custom Object). It allows you to model with implicit surfaces in realtime.

To start modelling you should first create a `"MetaObj"` object using the menu entry `"Create/Custom Object/MetaObj"` (if this menu entry is not available, you have to load the `"metaobj"` plugin using the menu entry `"File/Load Plugin"` first). `"Create/Custom Object/MetaObj"` creates a so called meta world with a single meta component (a sphere) in it. The meta world is represented by a `"MetaObj"` object and the component by a `"MetaComp"` object which is a child of the `"MetaObj"` object.

The complete template for the MetaObj object hierarchy, consequently, looks like this:

> `

>     +-MetaWorld(MetaObj)
>      | C1(MetaComp)
>      | [...
>      \ Cn(MetaComp)]

> `

The following table briefly lists some capabilities of the MetaObj and MetaComp objects.

Type | Parent of | Material | Converts to / Provides | Point Edit
MetaObj | MetaComp+ | Yes | PolyMesh | No
MetaComp | No | No | N/A | No

MetaObj/MetaComp Object Capabilities

Meta components live only in a meta world, therefore it makes no sense to create `"MetaComp"` objects in other places except as a child of a `"MetaObj"` object. Type, parameters, and transformation attributes of the meta components define the function of an implicit surface. The `"MetaObj"` object, that represents the meta world, evaluates this function on a regular three-dimensional grid and creates a polygonal representation for a specific function value (the so called threshold value).

This process may be further parameterised using the `"MetaObjAttr"` property:

### MetaObjAttr Property

- With the parameter `"NumSamples"` you specify the resolution of the three-dimensional regular grid, on which the implicit function is evaluated, in each dimension. A higher number of samples results in better quality but more polygons are created and more CPU power and memory are needed. For modelling you should set this to a lower value of about 40. For final rendering you may increase this to about 160.
- `"IsoLevel"`, defines the threshold value for that a polygonal representation of the implicit function should be created. Normally, you should not need to change this value.
- To show the actual bounds of the meta world, you may enable the `"ShowWorld"` parameter.

New in Ayam 1.5 is an adaptive calculation mode of the implicit surface. It may be switched on using the new attribute `"Adaptive"`. In the adaptive calculation mode, Ayam tries to vary the resolution of the resulting polygonal mesh according to the features of the implicit surface in order to capture fine details, even though a coarse grid is used. This is not done using a successively refined grid but by a refinement of the triangles created by the original algorithm (see also XXXX). You may control the adaptation process using three parameters: `"Flatness"`, `"Epsilon"`, and `"StepSize"`. If `"Adaptive"` is set to `"automatic"`, Ayam will not use the adaptive calculation while a modelling action is in progress. This mode has been introduced, because the adaptive mode may consume a considerable amount of CPU resources.

While modelling with meta balls you may add other `"MetaComp"` objects to the `"MetaObj"` object and parameterise them. A `"MetaComp"` object has the following properties.

### MetaCompAttr Property

- `"Formula"` specifies the type of the meta component. The following types are available: Metaball, Torus, Cube, Heart, and Custom. The latter gives you the possibility to use your own formulas.
- With the parameter `"Negative"` you define a component with a negative effect on the implicit function value. Negative components are not visible on their own but they are useful for modelling holes. Just try it.

The other parameter are specific to the type of the component:

### Metaball

- `"Radius"` sets the radius of the metaball
- `"EnergyCoeffA"`, `"EnergyCoeffB"`, and `"EnergyCoeffC"` are some parameters for the metaball formula. Usually you can leave those parameters at their default values. If you change them, be careful.

### Torus

- `"Ri"` the inner radius of the torus
- `"Ro"` the outer radius if the torus
- `"Rotate"` rotates the torus about 90 degree

### Cube

- `"EdgeX"`, `"EdgeY"`, and `"EdgeZ"`, let you define the sharpness of the edges of the cube

### Custom

- `"Expression"` is a piece of Tcl script, that represents your own custom formula for a meta component. The expression may call any Tcl commands to calculate a field value from the current grid position, which is given in the global variables `"x"`, `"y"`, and `"z"`. The expression has to return the field value in the global variable `"f"`. Here is an example for a custom expression:

      set f [expr {pow($x,4)+pow($y,4)+pow($z,4)}]

  Note that those expressions are called many times and since they are programmed in Tcl, this can be quite slow. You should use any tricks (like the curly braces in the expr-statement above) to speed up the expression.

### Conversion Support

Metaball objects may be converted to PolyMesh objects using the main menu entry `"Tools/Convert"`.

### RIB Export

Metaball objects will be exported as RiPointsGeneralPolygons primitives (regardless of whether the actual configuration would fit into a simpler polygonal primitive of the RenderMan interface, e.g. a RiGeneralPolygon).

PV tags are currently not supported.

## 4.53 SDNPatch Object

SDNPatches, l: control mesh, m: subdivided mesh with knot, r: subdivided mesh without knot

The SDNPatch custom object is available since Ayam 1.16 and allows to model with Subdivision NURBS, which extend the traditional subdivision schemes with knot values (see also the image above, where in the middle mesh a knot value has been set in the left hand side of the mesh). The SDNPatch plugin is based on libsnurbs by Tom Cashman.

There are some special modelling actions for Subdivision NURBS defined (see below) and there are PLY import/export facilities. Furthermore, there are two conversion operations that convert NURBS patch and PolyMesh objects to SDNPatch objects. Thus, SDMesh objects may be converted in two steps to SDNPatch objects, first to a PolyMesh then to the SDNPatch.

Please note that the plugin is still in experimental state, there is limited error checking and crashes may occur, if the special modelling actions are used.

The following table briefly lists some capabilities of the SDNPatch object.

Type | Parent of | Material | Converts to / Provides | Point Edit
SDNPatch | No | Yes | PolyMesh | Yes

SDNPatch Object Capabilities

### SDNPatchAttr Property

The SDNPatchAttr property allows you to set the following SDNPatch specific attributes:

- `"Degree"` is the degree of the subdivision NURBS surface, the only valid values are currently 3, 5, and 7.
- `"Level"` is the subdivision level, a high level leads to many polygons and a smooth surface; useful values range from 0 to 5.

### SDNPatch Modelling Actions

This section, briefly, explains the special modelling actions defined for the SDNPatch custom object. In order to select a face or edge for such an operation, just select all the control points defining the face or edge. All modelling actions can be started via the `"Custom/SDNPatch"` main menu.

- `"Face Extrude"`, new faces are inserted in the mesh at all edges of the selected faces, the selected faces themselves are displaced along their respective normals. If this operation is picking the wrong direction, try to revert all faces first, see below. Since Ayam 1.17 this operation has two parameters that control the offset of the extrusion operation (parameter `"Length"`) and a scaling factor applied to the new displaced set of control points (parameter `"Scale"`). The length parameter may be negative, to revert the direction of the extrusion.
- `"Face Remove"`, the selected face is removed from the mesh.
- `"Face Merge"`, the first two selected faces are removed from the mesh, the neighboring patches of the second face are connected to the neighboring faces of the first face. The decision, which vertices of the faces will actually be connected, depends on the relative vertice distances: you need to move the two faces near each other to make clear, how the new connection shall be established.
- `"Face Connect"`, the first two selected faces are removed from the mesh, the neighboring patches of the second face are connected to the neighboring faces of the first face via a set of new faces. The decision, between which vertices of the faces the new faces are built, depends on the relative vertice distances: you need to move the two faces near each other to make clear, how the new connection shall be established.
- `"Reset All Knots"`, set all knot values to 1.0 (the default).
- `"Set Knot"`, set the knot value of the selected edge.
- `"Revert"`, reverts all faces.
- `"Merge"`, merges multiple SDNPatch objects into one new.
- `"Import PLY"`, import a PLY file.
- `"Export PLY"`, export the currently selected SDNPatch object to a PLY file.

In addition, there are two conversion operations that convert NURBS patch objects (or NURBS patch providing objects) and PolyMesh objects (or PolyMesh providing objects) to SDNPatch objects.

Note that the PolyMesh to SDNPatch conversion only accepts closed quadrilateral polygon meshes (Triangles are omitted) and expects an optimized mesh (i.e. adjacent faces should share the same vertices).

### Conversion Support

SDNPatch objects may be converted to PolyMesh objects using the main menu entry `"Tools/Convert"`.

### RIB Export

SDNPatch objects will be exported as RiPointsGeneralPolygons primitives (regardless of whether the actual configuration would fit into a simpler polygonal primitive of the RenderMan interface, e.g. a RiGeneralPolygon).

PV tags are currently not supported.

## 4.54 Standard Properties

Most Ayam objects have standard properties. They are used to control transformations and common attributes of objects. The following sections describe the standard properties `"Transformations"`, `"Attributes"`, `"Material"`, `"Shaders"`, and `"Tags"`.

### Transformations Property

Use the `"Transformations"` property to edit the location, orientation, and size of an object.

The corresponding property GUI contains the following elements:

- `"Reset All!"` immediately resets all transformation attributes to the default values.
- `"Translate_X (_Y, _Z)"` is the displacement of the object from the world origin in X (Y, Z) direction.
- `"Rotate_X (_Y, _Z)"` is the angle (in degrees) of the rotation of the object around the X (Y, Z) axis. Read the next section for more information on how to use these entries. Read it!
- `"Quaternion"` the quaternion that is used to determine the orientation of the object in space.
- `"Scale_X (_Y, _Z)"` determines a scale factor that will be applied to the object in the direction of the local X (Y, Z) axis.

The transformations are applied to the object in the following order: Scale, Rotation, Translation.

How to use the rotation attributes?

The orientation of an object in space may be expressed using so called Euler angles. This notation (simply three angles determining a rotation about the axes of the coordinate system) suffers from a phenomenon called gimbal lock.

To avoid gimbal locks, Ayam internally holds the orientation of an object in a quaternion. This quaternion not only holds information about the angles but also about the order in which partial rotations occured.

It is important to know, that the values of the angles of the rotation property must not be read in a way that the object will first be rotated around X by x-angle degrees then around Y y-angle degrees then around Z z-angle degrees. In fact, no information about the order in which partial rotations occured may be derived from that three values. This implies, that e.g. the values 0 0 45 may denote a different orientation than the very same values 0 0 45 (no joke)!

But how do you get the three entries to do what you want? You either want to rotate the object around an axis by a given amount or you want to undo a rotation or undo all rotations.

Rotating an object is easy, simply add the amount about which you want to rotate the object to the value currently displayed in the appropriate entry. If you want to rotate about 45 degrees about X and the x-angle entry displays a 30, enter 75. Then press the apply button.
If you change multiple entries the rotations made will be in the order X (if changed) then Y (if changed) then Z (if changed). Do not change more than one entry at once unless you exactly know what you are doing.

Undoing a single rotation works in the same way, just use a subtraction instead of an addition.

Undoing all rotations (resetting the object to its original state) is simple too: enter 0 for all three entries at once, then press apply.

If you want to copy just the orientation of an object to other objects using the property clipboard, mark/select all Translate and Scale property elements, then use `"Edit/Copy Property"`. Just marking the Rotate elements and then using `"Edit/Copy Marked Prop"` will not work, because the quaternion will not be copied properly.

### Attributes Property

The `"Attributes"` property of an object contains currently:

- `"Objectname"`, the name of the object. It is also displayed in the object listbox or tree and may be written to RIB streams.
- `"Hide"`, if this attribute is set this object is not drawn. It may also be excluded from RIB export.
- `"HideChildren"`, if this attribute is set, the child objects of this object are not drawn. This attribute is e.g. used by `"NPatch"` objects to prevent the trim curves from being drawn in normal views.
- `"RefCount"`, just displays how many objects point to this object e.g. through master-instance or object-material relationships. Objects with a reference count higher than zero may not be deleted.

### Material Property

The `"Material"` property allows you to connect geometric objects to material objects (see also section Material Object). The material property GUI consist of the following elements:

- `"Clear Material!"` immediately clears any connection of the current object to its material.
- `"Add/Edit Material!"` adds a material to the current object (if it has none) and immediately selects the new material object for editing. If the current object already has a material, this material object is searched for and selected for editing.
- `"Materialname"` is the name of the material of this object. If you change the name, the object will be disconnected from the old material and connected to the new material. An easier way to connect geometric objects to material objects is to simply drop the geometric objects onto the material object using drag and drop in the tree view.

### Shader Properties

Shader properties are used to attach shaders of a certain type to objects. The name of the property contains the type of the shader, e.g. light shaders may be attached using a property named `"LightShader"` only. Other types of shaders or shader properties available are: `"Surface"`, `"Displacement"`, `"Interior"`, `"Exterior"`, `"Atmosphere"`, and `"Imager"`.

Each shader property GUI, even if no shader is attached to an object, starts with the `"Set new shader."`-button. This button allows to select a new shader of the appropriate type. If you press the `"Set new shader."`-button, a dialog with a list of shaders pops up. If this list is empty, Ayam is probably not set up properly (or you simply do not have shaders of the appropriate type). Check the preference setting `"Main/Shaders"`. After a new shader has been set, the arguments of the shader will be parsed and a GUI will be generated to allow the arguments of the shader to be filled with values.

The `"Delete shader."`-button may be used to delete the current shader from the selected object.

The `"Default Values."`-button resets all arguments of the shader to the default values. See also section Working with Shaders below.

All other elements of the shader property GUI depend on the currently attached shader.

Shader Parsing

If no plugin is loaded, the official Ayam binaries use libslcargs (from BMRT) to parse shaders that have been compiled with slc (the shader compiler from BMRT). Parsing incorporates detecting the type of the shader and detecting the names, types, and default values of all shader arguments.

Note that currently, Ayam only works properly with shaders that have at most two dots in their file name and that Ayam will simply skip all array arguments (and emit a warning message) while parsing a shader. Those array arguments consequently never appear in the shader property GUIs and RIBs exported by Ayam. Also note that default values for shader arguments of type color will be silently clamped to the range 0-255.

Many shaders use array arguments to define transformation matrices. If this is the case and you have access to the shader source code you may want to modify those shaders to enable working with the transformation matrix carrying shader arguments. To do this, just change all definitions of transformation matrix carrying floating point arrays to real matrices. If the shader contains a

`"float a_matrix_parameter[16]"`

change this to

`"matrix a_matrix_parameter"`.

Note that these changes of the shader argument definitions probably also require changes of the shader source code that uses those arguments. Ayam is able to deal with matrices because of their fixed size of 16 float values, and because libslcargs is able to deliver the default values for a matrix (but not for an array!).

If Ayam has been compiled without a shader parsing library (e.g. without libslcargs), Ayam will parse XML files created by `"sl2xml"` from the K-3D project (see `"http://www.k-3d.org/"`) instead of compiled shaders. The `"Set new shader."`-button will in this case always open a file requester, allowing you to select a XML file, that has been created by sl2xml. Furthermore, the `"Default Values."`-button will not be available; you have to use `"Set new shader."` instead.

From version 1.3 on, Ayam also supports shader parsing plugins to allow parsing of shaders compiled with different shader compilers, see also section Shader Parsing Plugins.

Working with Shaders

The `"Default Values."`-button resets all arguments of the shader to the default values. Additionally, the compiled shader will be parsed again and the property GUI will be adapted (new shader arguments will appear, removed shader arguments will disappear). Therefore, this button is quite handy if you have to deal with changing shaders: just edit the shader, recompile it, then back in Ayam just hit the `"Default Values."`-button. Note that this destroys your possibly carefully adjusted shader argument values.

If you want to keep the old shader argument values when a shader changes, simply copy the shader property using the property clipboard (main menu: `"Edit/Copy Property"`) before you load the new default values and paste the property back using `"Edit/Paste Property"` after loading of the new default values. Beware! This works properly only, if you do not change the type of existing shader arguments and if no shader arguments are removed in the new version of the shader.

You can also just copy certain parameter values (shader arguments whose types do not change) by selecting them using double-clicks on the parameter names in the shader property GUI and then use e.g. `"Edit/Copy Marked Prop"` (see also the description of the property clipboard in section Properties).

### Tags Property

Use the `"Tags"` property to edit the tags of an object.

Tags provide an easy way to attach arbitrary information (e.g. additional RenderMan interface attributes, special attributes for plugins or even scripts) to objects. A tag consists of two strings, one defining the type and one defining the value of the tag.

The tags property GUI consists of the following standard elements:

- `"Remove all Tags!"` immediately removes all tags from the object.
- `"Remove Tag!"` is a menu, that allows you to select and remove a single tag from the object.
- `"Add Tag!"` opens a small dialog box, where you may enter a new tag type and value. Once you press the `"Ok"` button, a new entry will be added to the tags property, displaying the new tag. Just click on the entry to get back to the dialog, to remove the tag using `"Clear"` then `"Ok"`, or to change the type or value of the tag.

The next sub-sections describe the tag types currently available in Ayam and the plugins distributed with Ayam. Note that extensions and plugins may define their own types.

## 4.55 Tags

Tags provide an easy way to attach arbitrary information (e.g. additional RenderMan interface attributes, special attributes for plugins or even scripts) to objects. A tag consists of two strings, one defining the type and one defining the value of the tag.

This section documents all currently known tag types.

### RiAttribute Tag

Description

The tag type `"RiAttribute"` can be used to attach arbitrary RenderMan interface attributes to objects. This is handy if a renderer with lots of RiAttributes that differ from the standard RiAttributes is in use.

`"RiAttribute"` tags attached to a geometric object override `"RiAttribute"` tags possibly attached to the material object of this geometric object.

In order to create a tag of type RiAttribute, the type string must be `"RiAttribute"`. The syntax of the value string is as following:

`<attrname>,<paramname>,<paramtype>,<param>`

where attrname is the name of the attribute (e.g. "render") paramname is the name of the parameter (e.g. "displacementbound") paramtype is a single character defining the type of the parameter (it may be one of `f` – float, `g` – float pair, `i` – integer, `j` – integer pair, `s` – string, `c` – color, `p` – point) and finally param is the value of the parameter itself (e.g. a float: "1.2", an integer value: "3", a string: "on", a color: "1,1,1" or a point: "0.4,0.5,1.0").

Example

Some examples for valid RiAttribute tags:

> `

>     RiAttribute render,truedisplacement,i,1
>     RiAttribute dice,numprobes,j,3,3
>     RiAttribute radiosity,specularcolor,c,0.5,0.5,0.5

> `

Notes

The `"RiAttribute"` tag handles just a single parameter at once. Also note that `"RiAttribute"` tags may be created much more easily using the menu entry `"Special/Tags/Add RiAttribute"`. The database of RiAttributes for this GUI may be extended by editing the ayamrc file, see section Ayamrc File.

### RiOption Tag

Description

The tag type `"RiOption"` can be used to attach arbitrary RenderMan interface options to the scene. This is handy if a renderer with lots of RiOptions that differ from the standard RiOptions is in use. However, they will be only used by the RIB exporter if they are attached to the `"Root"` object. The syntax is similar to the `"RiAttribute"` tag type, see above.

Notes

RiOption tags may be created easily using the menu entry `"Special/Tags/Add RiOption"`. Tags created with this GUI will always be added to the `"Root"` object. It does not have to be selected when the GUI is used. Furthermore, the database of RiOptions for this GUI may be extended by editing the ayamrc file, see section Ayamrc File.

### TC (Texture Coordinates) Tag

Description

The tag type `"TC"` can be used to attach texture coordinates to objects or materials.

The `"TC"` tag always contains a list of eight comma separated float values, that specify a mapping for four 2D points (a quadrilateral) in texture space from the default values (0,0), (1,0), (0,1), and (1,1) to the new specified values.

Example

> `

>     TC 0,0,10,0,0,10,10,10

> `

Changes the texture coordinate space so that more and smaller tiles of a texture would be displayed on a primitive.

> `

>     TC 0,0,0,1,1,0,1,1

> `

Flips the texture coordinate space over two corners. A shader normally generating vertical stripes will create horizontal stripes now.

> `

>     TC 0,1,0,0,1,1,1,0

> `

Turns the texture coordinate space by 90 degrees. A shader normally generating vertical stripes will create horizontal stripes now.

Notes

`"TC"` tags attached to a geometric object override `"TC"` tags possibly attached to the material object of this geometric object.

The exact behaviour of an object equipped with a `"TC"` tag depends heavily on the shader and its use of the texture coordinates.

Note also that using `"TC"` tags you change the texture coordinates of entire primitives only, if you want to change the texture coordinates of sub-primitives (e.g. of single control points of a NURBS patch) you would need to use a `"PV"` (Primitive Variable) tag instead.

To ease setting of `"TC"` tag values Ayam provides a special graphical editor as outlined below.

The texture coordinate editor may be opened using the main menu entry `"Special/Tags/Edit TexCoords"` and lets you edit texture coordinate tags in an intuitive way.

For that, the current texture coordinates are displayed as a black polygon in a canvas with regard to the original (default) values, that are displayed in gray. Small arrows point to positive s and t direction respectively.

Texture Coordinate Editor

The `"RotateR"` and `"RotateL"` buttons shift the coordinate values between the four points. This results in a 90 degree rotation of the texture space.

The `"FlipS"` and `"FlipT"` buttons flip the texture coordinate values in s and t direction respectively. This is useful, if you, for example, want to correct a texture mapping for an image that appears upside down.

The next buttons allow to move (using `"MoveS"` and `"MoveT"`) and scale (using `"ScaleS"` and `"ScaleT"`) the texture coordinates by a specific amount that is given in the first entry field.

The `"Load"` and `"Save"` menu buttons allow you to:

- load the default texture coordinate values ((0,0), (1,0), (0,1), (1,1)),
- load texture coordinates from a selected BPatch object: The xy coordinates of the four points of the selected BPatch will be interpreted as st coordinates. This allows for more complex transformations of the texture coordinates e.g. rotations about an angle of 45 degrees. For that just create a BPatch object, rotate it accordingly, then load the coordinates into the texture coordinate editor.
- load TC tags from the selected object,
- save the texture coordinates to a BPatch object,
- save TC tags to a selected object. Note that it is not possible to directly save the TC tag to multiple selected objects. But you can use the property clipboard to copy the tag after saving to a single object.

Note that the tag numbers in the menu entries count TC tags only.

The texture coordinate dialog is modeless, it may stay open while you model. The `"Dismiss"` button closes the dialog.

### PV (Primitive Variable) Tag

Description

The tag type `"PV"` can be used to attach arbitrary data to geometric primitives and even sub-primitives. With the help of primitive variables you can e.g. attach your own texture coordinates to a NURBS patch primitive or attach distinct colors to the faces or even to single vertices of a polygonal mesh. In the latter case, the data is properly interpolated by the RenderMan renderer before it is handed over to the surface shader.

When rendering, all data defined in a `"PV"` tag is handed over to the surface shader that is attached to the respective geometric primitive using additional shader parameters. For RIB export, proper `"RiDeclare"` statements will be created automatically by Ayam.

However, Ayam does not check, whether your shaders actually use the data from the `"PV"` tag.

The syntax of the value string of a PV tag is as following:

`<name>,<detail>,<type>,<ndata>,<data>`

where `"<name>"` is the name of the primitive variable; `"<detail>"` (or storage class) should be one of `"uniform"`, `"varying"`, `"vertex"`, or `"constant"`; `"<type>"` is a single character describing the type of the data (one of `"c"` (color), `"f"` (float), `"g"` (float[2]), `"n"` (normal), `"p"` (point), `"s"` (string), or `"v"` (vector), see also the documentation of the `"RiAttribute"` tag above); `"<ndata>"` is an integer number describing how many data elements will follow; and `"<data>"` is a comma separated list consisting of `"<ndata>"` elements of type `"<type>"`.

Examples

> `

>     PV mycolor,constant,c,1,0,1,0

> `

adds a single color value (0,1,0), which is the same all over the primitive, the respective surface shader should have a parameter `"color mycolor"`;

> `

>     PV mys,varying,f,4,0.1,0.2,0.3,0.4

> `

could be used to add a distinct float value to each corner point of a four point NURBS patch (of order, width, and height 2), the respective surface shader should have a parameter `"varying float mys"`.

Notes

The following data types are not supported: i, j. Support for the data types n (normal), and v (vector) was added in Ayam 1.17.

Not all geometric objects currently honour PV tags on RIB export. The geometric objects currently supporting PV tags are: SDMesh, PolyMesh, PatchMesh, NPatch, and BPatch.

Furthermore, the number of data elements, which depends on the detail or storage class, the type of geometric primitive, and the configuration of the geometric primitive is not checked by Ayam. Some RIB writing libraries, however, check the number and silently omit the primitive variable if there are mismatches. Check your RIB for the presence of the primitive variable after export, especially, if you are adding or editing PV tags manually.

### RiHider Tag

Description

The tag type `"RiHider"` can be used to choose and parameterise different algorithms for hidden surface removal when rendering the exported scene with a RenderMan compliant renderer. RiHider tags have to be attached to the root object in order to be used. The syntax of a RiHider tag is quite similar to a RiAttribute tag: `"<type>,<parameterlist>"` where `"<parameterlist>"` is a comma separated list of triplets consisting of name, type, and value of a parameter.

Example

A RiHider tag could look like this:

> `

>     RiHider hidden,depthfilter,s,midpoint

> `

### RiDisplay Tag

Description

The tag type `"RiDisplay"` can be used to add output files of different type (e.g. containing depth-buffer information) to the scene or to directly control the output format when rendering the exported scene with a RenderMan compliant renderer. RiDisplay tags have to be attached to the root object in order to be used. The syntax of a RiDisplay tag is as follows: `"<name>,<type>,<mode>,<parameterlist>"`, where name is e.g. a file or device name, type specifies the destination of the image data (e.g. screen or file), mode specifies which information should be stored or displayed (e.g. color values: rgb, or depth values: z), and `"<parameterlist>"` is a comma separated list of triplets consisting of name, type, and value of a parameter.

Example

A RiDisplay tag to add output of the depth-buffer information to the file `"imagez.tif"` could look like this:

> `

>     RiDisplay imagez.tif,file,z

> `

Notes

The name will be automatically changed to `"+name"` on RIB export if it does not already start with a plus.

### NoExport Tag

Description

The tag type `"NoExport"` can be used to exclude certain objects from exported RIBs. The value string of this tag is ignored. All that counts is the presence of the tag. Child objects of objects with the `"NoExport"` tag will also be excluded from the RIB. Since Ayam 1.6, light objects also honour the `"NoExport"` tag. Note that regardless of potentially present `"NoExport"` tags, RIB archives will be created for all referenced objects all the time (even if `"NoExport"` tags are added to all instances).

### SaveMainGeom Tag

Description

The tag type `"SaveMainGeom"` can be used to save the geometry of the main window and the toolbox window (if open) to a scene file. For that the scene saving code checks for the presence of a `"SaveMainGeom"` tag for the root object and fills it with the current geometry information. The scene reading code checks for the presence of a `"SaveMainGeom"` tag for the root object after replacing a scene and re-establishes the geometries of main and toolbox window.

### SavePaneLayout Tag

Description

The tag type `"SavePaneLayout"` can be used to save the relative sizes of the internal windows of the main window when Ayam runs in the single window GUI mode to a scene file. For that the scene saving code checks for the presence of a `"SavePaneLayout"` tag for the root object and fills it with the current geometry information. The scene reading code checks for the presence of a `"SavePaneLayout"` tag for the root object after replacing a scene and re-establishes the geometries of the internal windows.

### TP (Tesselation Parameter) Tag

Description

The tag type `"TP"` can be used to save tesselation parameters to objects of type `"NPatch"` (and objects that may be converted to `"NPatch"` objects). Those tesselation parameters will be used when the NPatch object is tesselated for e.g. a conversion to a PolyMesh object. The syntax of the TP tag is: `"<tmethod>,<tparamu>,<tparamv>"` where `"<tmethod>"` is an integer value between 1 and 3, describing which tesselation method to use (1 – ParametricError, 2 – PathLength, and 3 – DomainDistance) and `"<tparamu>"` and `"<tparamv>"` are float values describing the respective parameter value for the chosen tesselation method. The second parameter value is ignored for the tesselation methods 1 and 2.

Note that the syntax of the `"TP"` tag changed in Ayam 1.9, the old syntax only allowed one parameter.

TP tags may be easily created using the tesselation GUI, that can be started with the main menu entry `"Tools/Surface/Tesselate"` (see also section Tesselation Tool).

Example

A TP tag could look like this:

> `

>     TP 1,0.5,0.6

> `

### DC (Depth Complexity) Tag

Description

The tag type `"DC"` is only used by the AyCSG CSG preview plugin to store the depth complexity of CSG primitives. The syntax of the DC tag is: `"<dcval>"` where `"<dcval>"` is a positive integer value describing the depth complexity of the CSG primitive. See also section CSG preview using the AyCSG plugin for more information regarding the depth complexity value.

Example

A DC tag (valid for e.g. a torus) could look like this:

> `

>     DC 2

> `

### NP (New Property) Tag

Description

The tag type `"NP"` (new property) may be used to add new property GUIs to single objects. The value of the tag is the name of a new property. The necessary code to manage the property data and the windows that make up the property GUI itself have to be present in the Tcl context of Ayam before the user clicks on the new property in the property list box.

Example

> `

>     NP Transformations

> `

### RP (Remove Property) Tag

Description

The tag type `"RP"` (remove property) may be used to remove GUI access to a property from single objects. The value of the tag is the name of the property to be removed. The GUI access will be blocked by simply omitting the property from the property listbox. Note well: the property is still present and active in the objects themselves and values may still be set using the scripting interface.

Example

> `

>     RP Script

> `

removes direct access to the Script property of a Script object. Ideally, the Script object also has a `"NP"` tag, to allow direct control of script parameters. This way, the user does not see the script (code), just a clean parameter GUI.

### BNS (Before Notify Script) Tag

Description

The tag type `"BNS"` (before notify script) may be used to add scripts to an object, that will be run before the notification callback of that object completed. The notification, in turn, will be executed because e.g. one of the children of the object changed.

Example

A simple BNS tag could look like this:

> `

>     BNS puts "notify callback about to fire"

> `

Notes

In Ayam versions prior to 1.16 BNS tag scripts could use any functionality of Tcl, Tk, and the Tcl scripting interface of Ayam which posed a huge security risk. This is no longer the case. BNS tag scripts now run in a safe interpreter with reduced instruction set. They can no longer write to the file system, get onto the network, or confuse the application state, see also section Safe Interpreter. Consequently, the warning dialog that appeared when files with BNS tags were loaded is also gone.

You can still re-enable the old functionality by recompiling Ayam. If you do so, for security reasons, if scene files containing BNS tags are loaded, Ayam will again raise the warning offering to temporarily disable all such tags that will be read. To disable a BNS tag, Ayam simply changes its type from `"BNS"` to `"DBNS"` (disabled before notify script). It will not be executed then. Disabled notify script tags may be enabled after careful inspection by simply changing their type back to `"BNS"` or by using the main menu entry `"Special/Enable Scripts"`.

### ANS (After Notify Script) Tag

Description

The tag type `"ANS"` (after notify script) may be used to add scripts to an object, that will be run after the notification callback of that object completed. The notification, in turn, will be executed because e.g. one of the children of the object changed.

Example

A simple ANS tag could look like this:

> `

>     ANS puts "notify callback completed"

> `

Notes

In Ayam versions prior to 1.16 ANS tag scripts could use any functionality of Tcl, Tk, and the Tcl scripting interface of Ayam which posed a huge security risk. This is no longer the case. ANS tag scripts now run in a safe interpreter with reduced instruction set. They can no longer write to the file system, get onto the network, or confuse the application state, see also section Safe Interpreter. Consequently, the warning dialog that appeared when files with ANS tags were loaded is also gone.

You can still re-enable the old functionality by recompiling Ayam. If you do so, for security reasons, if scene files containing ANS tags are loaded, Ayam will again raise the warning offering to temporarily disable all such tags that will be read. To disable a ANS tag, Ayam simply changes its type from `"ANS"` to `"DANS"` (disabled before notify script). It will not be executed then. Disabled notify script tags may be enabled after careful inspection by simply changing their type back to `"ANS"` or by using the main menu entry `"Special/Enable Scripts"`.

### UMM/VMM (U/V Min Max) Tag

Description

The tag types `"UMM"` (u min max) and `"VMM"` (v min max) may be used to store additional parametric domain trimming values to NURBS curve and NURBS patch objects. Note that the GLU NURBS display modes do not honor those tags, but the RIB export does.

Example

An UMM tag could look like this:

> `

>     UMM 0.4,0.6

> `

### BP (Bevel Parameters) Tag

Description

The tag type `"BP"` (bevel parameters) is used by all bevel supporting tool objects to store their bevel information. The syntax of the BP tag is: `"<side>,<type>,<radius>,<revert>"` where `"<side>"` is an integer value from 0 - 3 defining the side of the surface, where the bevel should be applied to, `"<type>"` is an integer value from 0 - 4 defining the type of the bevel, `"<radius>"` is a floating point value defining the radius of the bevel, and `"<revert>"` is either 0 or 1 and may be used to revert the bevel.

Example

A BP tag could look like this:

> `

>     BP 0,0,0.1,0

> `

### Internal Tags

The following tags are used by Ayam internally only; they will not appear in the tags property GUI and they can not be deleted or changed using the scripting interface.

- OI (Object ID) Tag

  This tag is used by the RIB exporter and the scene storage facility to establish links between instance objects and the original objects they are pointing to.

- MI (Material ID) Tag

  This tag is used by the RIB exporter and the scene storage facility to establish links between material objects and the objects they are assigned to.

- NO/NM Tags

  These tags are internal binary tags, that transport the notification across the scene.

### List of Known Tags

This section contains a comprehensive list of tag names, that are known since Ayam 1.10 and in all accompanying extensions (plugins).

`"RiAttribute", "RiOption", "RiHider", "RiDisplay", "NoExport", "TC", "PV", "SaveMainGeom", "SavePaneLayout", "TP", "MI", "OI", "DC", "TM", "NP", "RP", "BNS", "DBNS", "ANS", "DANS", "NO", "NM", "UMM", "VMM", "BP", "IDR", "IIDR", "RIDR", "R3IDR", "CIDR", "CCIDR"`

The following tags are for internal use (they will not be displayed in the Tags property of an object): `"MI", "OI"`

Tags of type `"NO", "NM"` are binary, they also never show up in the Tags property.

Documentation on all those tags can be found in the sections above.

Next Previous Contents