Keywords: main

Next: 5. Usage and Command Up: 4. Geometry Shaders Previous: 4.3 Geometry Shader API
Subsections

- 4.4.1 Instances
- 4.4.2 Groups
- 4.4.3 Cameras
- 4.4.4 Lights
- 4.4.5 Functions
- 4.4.6 User Data
- 4.4.7 Function Declarations
- 4.4.8 Boxes
- 4.4.9 Objects
- 4.4.10 Approximations
- 4.4.11 Polygon Lists
- 4.4.12 Polygon Indices
- 4.4.13 Polygon Vertices
- 4.4.14 Polygon Vectors
- 4.4.15 Surfaces: Face List
- 4.4.16 Surfaces: Surface List
- 4.4.17 Surfaces: Curve Segment List
- 4.4.18 Surfaces: Scalar Lists
- 4.4.19 Surfaces: Curve Point Lists
- 4.4.20 Surfaces: Basis Lists
- 4.4.21 Surfaces: Algebraic Lists
- 4.4.22 Space Curves2.1
- 4.4.23 Books and Pages
- 4.4.24 Subdivision Surfaces
- 4.4.25 Materials
- 4.4.26 Rendering Options
- 4.4.27 Images
- 4.4.28 Strings
- 4.4.29 Tag Lists

# 4.4 Geometry Shader Data Structures

This chapter describes the data structures that define a scene in memory. While the scene is constructed using API calls, there is not an API call for all operations that merely write a value into an existing data structure. Instead, the mi_api_*_begin calls return a pointer to the data structure just created and expect the caller to fill in simple parameters. This chapter describes these data structures.

This section discusses every element type in detail. There is one subsection for each element type. Each describes

- the element type (as returned by mi_db_type),

- the C data type of the contents. Some elements are arrays of this type.

- the extra arguments given to the create and resize functions to preallocate variable-sized sections.

- a brief descriptions of the defaults stored by the create function.

- the declaration of the data type, with description.

This chapter describes the data structures used by mental ray 2.1. The data structures for mental ray 2.0 are similar, but lack a number of fields. These fields are marked ``2.1''.

## 4.4.1 Instances

Element type: | miSCENE_INSTANCE
Data type: | miInstance
Sizes: | int param_size
Defaults: | all nulls, two identity matrices, parameter size as given by size argument

    enum miGenMotionType {
            miGM_INHERIT = 0,
            miGM_TRANSFORM,
            miGM_OFF
    };

    typedef struct miTransform {
            miTag           function;               /* function, may be null tag */
            float           time;                   /* the last evaluation time */
            miMatrix        global_to_local;        /* transformation in world */
            miMatrix        local_to_global;        /* transformation to world */
            miCBoolean      identity;               /* SCENE: matrices are ident.*/
            miCBoolean      spare[3];               /* SCENE: not used */
            int             id;                     /* SCENE: unique transform ID*/
    } miTransform;

    typedef struct miInstance {
            miTransform     tf;                     /* space transformation */
            miMatrix        motion_transform;       /* motion transformation */
            miTag           item;                   /* instanced item */
            miTag           material;               /* inherited material or list*/
            miTag           parent;                 /* SCENE: leaf inst. parent */
            miTag           boxes;                  /* SCENE: renderable repres. */
            miTag           next;                   /* SCENE: leaf instance list */
            miTag           prev;                   /* SCENE: leaf instance list */
            int             mtl_array_size;         /* if mtl array, array size */
            int             n_boxes;                /* SCENE: # of boxes attached */
            miTag           userdata;               /* optional user data blocks */
            miUint          label;                  /* optional label */
            miTag           geogroup;               /* SCENE: geomshader group */
            miCBoolean      off;                    /* ignore this instance */
            miUint1         gen_motion;             /* motion information */
            miUint1         visible;                /* visible ? */
            miUint1         shadow;                 /* casts shadow? */
            miUint1         trace;                  /* visible as reflection? */
            miUint1         caustic;                /* caustic bitmap */
            miUint1         globillum;              /* globillum bitmap */
            miCBoolean      temp_material;          /* SCENE: has inherited mtl */
            int             spare[3];               /* not used */
            miTag           param_decl;             /* parameter declaration */
            int             param_size;             /* parameter size in bytes */
            char            param[8];               /* arbitrary-sized parameters*/
    } miInstance;

A translator must provide: either `tf.function` and `time`, or `global_to_local` and `local_to_global`; also `item` (using mi_scene_link), `param_decl`, `param_size`, and `param`.

All fields except the matrices, the material, and the parameters are reserved for Scene and may not be modified by other modules. The tags can be modified indirectly with the link and unlink functions, which take care of reference counts. The instance element has two variable parts; one for inherited shader parameters and one for the relation list. The latter is maintained exclusively by Scene.

tf.function optionally points to a transformation function that computes a matrix from the current time. If present, this function is called during preprocessing with three parameters: a pointer to the result global-to-local matrix, the instance tag, and the time as given in the preprocessing control structure.

tf.time is the time the evaluation function, if present, was last called with. If it matches the current time, the matrices need not be calculated by calling the function again.

tf.global_to_local transforms the parent space to the local space of the instanced subtree. If a transformation functions exists, it writes its result here; if not, the translator must store an appropriate matrix here.

tf.local_to_global is the inverse matrix, set by Scene after the transformation function (if it exists) has returned the `tf.global_to_local` matrix.

tf.identity is `miTRUE` if the transformation matrices in this instance are identity transforms (this saves the renderer unnecessary ray transformations).

tf.id is a unique transformation ID. Scene creates it during preprocessing, trying to assign identical IDs to identical transformations. This is especially important for leaf instances: the renderer does not have to retransform the current ray if the new box has the same transformation (same ID) as the previous.

motion_transform specifies the transformation from parent space to local space for motion blur transforms. If this is a null matrix, the instance transformation `tf` is used.

item is the tag of the element being instanced. Only groups, cameras, lights, objects, functions and boxes can be referenced. If a box is referenced, it is taken as a ``trivial object'' that does not need tessellation; boxes that result from tessellation are not attached here. If a function-list is instanced, actually the geometry shader created scene elements are intended to be instanced.

material is either a material (if mtl_array_size is 0) or a material list (if mtl_array_size is nonzero) used for material inheritance (as opposed to parameter inheritance). During scene preprocessing, the non-null material tag closest to a geometrical object (lowest in the DAG hierarchy) becomes the default material for any polygon or surface in the object that does not have its own non-null material tag. If the tag references a list (type `miSCENE_TAG`) or materials, it is expected to contain mtl_array_size tags, which will be indexed with the polygon or surface label during rendering.

mtl_array_size Specifies the number of tags in the material tag list if nonzero. If the material tag specifies a material directly, it must be zero. This number is used during rendering as a flag that tells mental ray that the material tag references a list, and also how many items there are in the list to prevent array bounds overflows.

boxes is used to point to boxes that resulted from tessellation. They are used in two cases only: object or box instances attach to the cached untransformed boxes (see above for a definition) if enabled; and leaf instances attach to the final renderable representation.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

n_boxes is the number of boxes attached to boxes. Keeping this separate avoids having to access boxes to count them.

geogroup is used to point to the group element which contains all the geometry-shader created scene elements for this instance.

off, if true, stops the recursive descent during preprocessing as if the instance and its instanced item didn't exist. This is useful for temporary suspending subtrees without deleting them.

gen_motion specifies the motion blur generation for the instance. Setting this field to `miGM_OFF` switches off motion blur for this instance. Motion blur is always generated when this field is set to `miGM_TRANSFORM`. The parent instance determines whether motion blur is active or not when it is set to `miGM_INHERIT`.

visible, shadow, trace, caustic, and globillum2.1flags are inherited in the scene DAG. During scene preprocessing, the non-null flag in the DAG instance closest to a geometrical object (lowest in the DAG hierarchy) is put into the leaf instance. Before rendering starts the leaf instance flags are merged with the object flags and stored in internal raylib rendering data structures. In the merging operation these flags are treated as "fuzzy booleans", that is, a zero value means that the flag is ignored (the object flag is taken), 1 disables the flag (even if the object has enabled it) and 2 enables it (even if the object has not set the flag). The caustic bitmap has the same bit interpretation as the corresponding field in the `miObject`, but has three more bits defined here. Bit 2, if set, disables generation of caustics cast by this object. Bit 3, if set, disables receiving caustics. Bit 5, if set, enables photons to intersect with this object. In the merging, bit 0 and bit 1 of the leaf instance and object caustic bitmaps are logically combined with an `OR` operation followed by `AND` of the instance caustic bitmap bits 2 and 3, inverted and shifted right two times. Also in the merging, bit 4 of the leaf instance and object caustic bitmaps are logically `OR`ed followed by an `AND` with bit 5 of the instance caustic bitmap inverted and shifted right one position. The globillum2.1bitmap is similar to the caustic bitmap.

temp_material is a flag that tells SCENE postprocessing that the material field contains a material that was created during preprocessing, and must be deleted on postprocessing. This happens if the inheritance shader sets one or more of the material fields in its material argument, to implement Catia aspect inheritance.

param_decl points to a parameter declaration that describes the parameters. If parameters exist, this tag must be set by the translator to allow data exchange with other hosts. If it is missing, no data will be swapped regardless of the remote host's byte order. In leaf instances, Scene stores the most recent parent instance's parameter declaration tag here.

param_size is the size of the parameters in bytes. It is taken from the first and only argument of the create and resize calls. In the leaf instance, the inheritance function determines the size.

param is an arbitrary-sized array of parameters stored by the translator. During preprocessing, the DAG is traversed, and the parameters are passed to an inheritance function that is called for every instance found during traversal. The end result is stored in the leaf instance by Scene.

## 4.4.2 Groups

Element type: | miSCENE_GROUP
Data type: | miGroup
Sizes: | int max_kids, int max_connections
Defaults: | all nulls, max_* as given by size arguments

    typedef struct miGroup {
            miGeoScalar     merge;          /* merge tolerance */
            miTag           boxes;          /* SCENE: cached shared tesselation */
            int             n_boxes;        /* SCENE: # of boxes attached */
            miBoolean       merge_group;    /* perform merging on members? */
            int             max_kids;       /* number of kids allocated */
            int             no_kids;        /* number of kids actually used */
            int             max_connections;/* number of connections allocated */
            int             no_connections; /* number of connections used */
            miTag           userdata;       /* optional user data blocks */
            miUint          label;          /* optional label */
            int             spare[3];       /* not used */
            miTag           kids[2];        /* kid list (instances) */
    } miGroup;

    typedef struct {
            miTag           instance[2];    /* the two face type object instances*/
            miGeoIndex      face[2];        /* indices of the two miFace's */
            miGeoIndex      curve[2];       /* indices of the two miCurves*/
            miGeoRange      range[2];
    } miConnection;

A translator must provide: nothing.
A translator may provide: `merge_group`, `merge`, the connection array.

Groups have two variable-sized sections, one for the list of instances and one for the list of connections. The latter exists only if the group is a merge group. The macro `miGROUP_GET_CONNECTIONS(n)` returns a `miConnection` pointer to the n-th connection. Note that instances must be added to groups with mi_scene_link, but the connection tags are written directly to the `miConnection`.

boxes is used to point to boxes that resulted from tessellation. They are used in two cases only: object or box instances attach to the cached untransformed boxes (see above for a definition) if enabled; and leaf instances attach to the final renderable representation.

n_boxes is the number of boxes attached to boxes. Keeping this separate avoids having to access boxes to count them.

merge_group is `miTRUE` if this group is a merge group. Merge groups are treated like objects; all their subobjects are tessellated as one object. In fact, the Scene module treats merge groups like objects and lets GAP pick apart the group and its subtrees.

merge is the merge epsilon. It is used only in merge groups.

max_kids is the current size of the kids array.

no_kids is the number of instances stored in the kids array.

max_connections is the current size of the connection array.

no_connections is the number of connections in the connection array.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

label2.1a numeric value assigned by applications.

kids is the beginning of the variable section of `miGroup`, consisting of an array of instance tags followed by an optional array of connections.

## 4.4.3 Cameras

Element type: | miSCENE_CAMERA
Data type: | miCamera
Sizes: | --
Defaults: | as described below

    typedef struct miCamera {
            miBoolean       orthographic;           /* orthographic rendering? */
            float           focal;                  /* focal length */
            float           aperture;               /* aperture */
            float           aspect;                 /* aspect ratio of the image */
            miRange         clip;                   /* min/max clipping */
            int             x_resolution;           /* x resolution */
            int             y_resolution;           /* y resolution */
            struct {int xl, yl, xh, yh;}
                            window;                 /* corners of subwindow */
            miTag           volume;                 /* opt. volume shader */
            miTag           environment;            /* opt. environment shader */
            miTag           lens;                   /* opt. lens shader */
            miTag           output;                 /* opt. output shaders/files */
            int             frame;                  /* current frame number */
            float           frame_time;             /* ... as time in seconds */
            int             frame_field;            /* 0=frame, 1/2=field number */
            float           x_offset;               /* x image offset in pixels */
            float           y_offset;               /* y image offset in pixels */
            miTag           userdata;               /* optional user data blocks */
            int             spare[15];              /* not used */
    } miCamera;

A translator must provide: nothing.
A translator may provide: all fields.

orthographic (default `miFALSE`) switches the camera from the standard pinhole camera to an orthographic camera.

focal (default 1.0) is the focal length of the camera (the distance between the camera and the viewing plane).

aperture (default 1.0) is the width of the viewing plane in 3D space.

aspect (default 1.0) is the height of a pixel 1 unit wide.

clip (default 0.0001, 1000000.0) describes the minimum (hither) and maximum (yon) limits of the scene. Geometry outside these limits will not be rendered.

x_resolution (default 768) is the width of the rendered image in pixels.

y_resolution (default 576) is the height of the rendered image in pixels.

window (default 0, 0, 65535, 65535) describes the lower left and upper right corners of the rendered subwindow. Pixels outside this window will be black. If the upper right pixel exceeds the resolution, it is clipped to the resolution.

volume (default `miNULLTAG`) is the optional atmosphere volume shader.

environment (default `miNULLTAG`) is the optional view environment shader that is called for all (including primary) rays leaving the scene (the active environment shader for secondary rays may be overridden by materials).

lens (default `miNULLTAG`) is the optional first lens shader.

output (default `miNULLTAG`) is the optional first output shader or output file.

frame (default 0) is the frame number of the current render. It is not used by mental ray but is accessible to shaders.

frame_time (default 0.0) is the same as the frame number, but expressed in seconds. It is not used by mental ray.

frame_field (default 0) is the number after the `field` substatement in a `frame` statement. Since frame numbers are integers, the field number must be used to distinguish the first and second field of the frame, if field rendering is in effect. By convention, 0 means that the entire frame is rendered; 1 is the first (odd) and 2 is the second (even) field. It is not used by mental ray.

x_offset (default 0.0) is the x offset of the rendered image from the center of the camera axis in pixel units.

y_offset (default 0.0) is the y offset of the rendered image from the center of the camera axis in pixel units.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

## 4.4.4 Lights

Element type: | miSCENE_LIGHT
Data type: | miLight
Sizes: | --
Defaults: | as described below

    enum miLight_type {
            miLIGHT_ORIGIN,
            miLIGHT_DIRECTION,
            miLIGHT_SPOT
    };

    enum miLight_area {
            miLIGHT_NONE = 0,
            miLIGHT_RECTANGLE,
            miLIGHT_DISC,
            miLIGHT_SPHERE,
            miLIGHT_CYLINDER
    };

    typedef struct miLight {
            enum miLight_type type;           /* light type */
            enum miLight_area area;           /* area? */
            miScalar          exponent;       /* global illum. 1/r^(2*exp)*/
            unsigned int      caustic_store_photons;/*caust. photons to store*/
            unsigned int      global_store_photons; /*glob. photons to store */
            miColor           energy;         /* global illum. intensity */
            miTag             shader;         /* light shader */
            miTag             emitter;        /* photon emitter shader */
            miVector          origin;         /* opt. origin */
            miVector          direction;      /* opt. normalized direction */
            float             spread;         /* size of spot? (cos angle) */
            union {
                    struct miLight_rectangle    rectangle;
                    struct miLight_disc         disc;
                    struct miLight_sphere       sphere;
                    struct miLight_cylinder     cylinder;
            }               primitive;        /* area primitive */
            short           samples_u;        /* area u samples */
            short           samples_v;        /* area v samples */
            short           low_samples_u;    /* low area u samples */
            short           low_samples_v;    /* low area v samples */
            short           low_level;        /* switch to low at this lvl */
            short           spare1;           /* not used */

            miBoolean       use_shadow_maps;  /* for this light */
            miTag           shadowmap_file;   /* the shadow map file */
            int             shadowmap_resolution; /* resolution */
            float           shadowmap_softness;   /* sample region size */
            int             shadowmap_samples;    /* #samples */
            miBoolean       visible;          /* visible? area lights only */
            miUint          label;            /* light label */
            miTag           userdata;         /* optional user data blocks */
            unsigned int    caustic_emit_photons;/*caust. photons to emit*/
            unsigned int    global_emit_photons; /*glob. photons to emit */
            int             spare[4];         /* not used */
    } miLight;

    struct miLight_rectangle {
            miVector        edge_u;
            miVector        edge_v;
    };

    struct miLight_disc {
            miVector        normal;
            miScalar        radius;
    };

    struct miLight_sphere {
            miScalar        radius;
    };

    struct miLight_cylinder {
            miVector        axis;
            miScalar        radius;
    };

A translator must provide: `type`, `shader`, `origin` and/or `direction` and `spread` depending on `type`, all primitive fields for area light sources.

type (default `miLIGHT_ORIGIN`) distinguishes between point lights (origin only), directional lights (direction only), and spot lights (origin, direction, and spread angle).

area (default `miLIGHT_NONE` describes the type of area light geometry, and is one of `miLIGHT_NONE`, `miLIGHT_RECTANGLE`, `miLIGHT_DISC`, `miLIGHT_SPHERE`, and `miLIGHT_CYLINDER`.

exponent (default 2) controls the falloff of the light at a given distance. An exponent of 2 is physically correct, but other exponents can be chosen to make the light reach farther or less far than it should. An exponent of 1 means that the light energy does not fall off with distance. Exponents other than 2 disturb the energy balance in the scene.

caustic_store_photons is the maximum number of photons from this light source to store in the caustic photon map. If set to zero, the number of photons to emit must be specified, which then controls the number of emitted photons no matter how many are stored. (The zero value is supported in mental ray 2.1.,37 and later, earlier versions require setting it to a very high number.)

caustic_emit_photons is the maximum number of caustic photons to emit from this light source. Emission of caustic photons from a light stops when either caustic_store_photons or caustic_emit_photons has been reached.

global_store_photons2.1is the maximum number of photons from this light source to store in the global illumination photon map. Again, a value of zero disables the store limit in mental ray 2.1.37 and later.

global_emit_photons2.1is the maximum number of global illumination photons to emit from this light source. Emission of global illumination photons from a light stops when either globillum_store_photons (if nonzero) or globillum_emit_photons has been reached.

shader (default `miNULLTAG`) is the tag of a database element of type `miSCENE_FUNCTION` containing the light shader, which computes illumination by this light at render time.

emitter (default `miNULLTAG`) is the tag of a database element of type `miSCENE_FUNCTION` containing the light photon emitter shader, which emits photons during the global illumination or caustics preprocessing phase.

origin (default 0, 0, 0) is the origin of the light in object space. It is used only if type is `miLIGHT_ORIGIN` or `miLIGHT_SPOT`.

direction (default 0, 0, 0) is the direction of a directional light. It is used only if type is `miLIGHT_DIRECTION` or `miLIGHT_SPOT`.

spread is used only by spot lights and it specifies the size of the outer spotlight cone.

primitive contains the size of the area light source if area is not `miLIGHT_NONE`. Depending on `area`, the width and height of the rectangle are given in rectangle.edge_u and rectangle.edge_v, or the orientation and radius of the disc are given in disc.normal and disc.radius, or the radius of the sphere is given in sphere.radius, or the axis and radius of the cylinder are given in cylinder.axis and cylinder.radius. All defaults are 0.

samples_u (default 3) is the number of samples taken in the U direction of the area light source if area is not `miLIGHT_NONE`.

samples_v (default 3) is the number of samples taken in the V direction of the area light source if area is not `miLIGHT_NONE`.

low_samples_u (default 2) is the number of samples taken in the U direction of the area light source if area is not `miLIGHT_NONE`, when the trace depth specified by low_level is reached or exceeded.

low_samples_v (default 2) is the number of samples taken in the V direction of the area light source if area is not `miLIGHT_NONE`, when the trace depth specified by low_level is reached or exceeded.

low_level (default 3) is the sum of the reflection and refraction trace depth at which area light sampling switches from samples to low_samples. 0 means that no switching takes place and samples are always used.

use_shadow_maps specifies whether shadow maps are used for this light source.

shadowmap_file is the tag of a string containing the filename for the shadowmap. If the tag is null, no file loading and saving will be done. For point lights, six files will be generated, each with an identifying number (1...6) appended to the filename. If the file name contains the `#` character, it will be expanded to a hexadecimal number identifying the particular instance of this light. This allows different instances of a light to use different files.

shadowmap_resolution is the resolution of the shadow map. For point lights, the individual images will have a lower resolution, so that the total number of pixels rendered will be approximately shadowmap_resolution `x` shadowmap_resolution.

shadowmap_softness when non-zero, enables soft shadows. The value given specifies the rectangular size of the region in the shadow map's projection plane in which samples are placed. If this parameter is 0 only one sample will be used, creating sharp shadows. The size is given in internal space units on the shadowmap projection plane.

shadowmap_samples is the number of samples taken from the shadow map. When `shadowmap_softness` is zero, this value is ignored.

visible is `miTRUE` if the light should be seen in the rendering. This only applies to area light sources.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

label2.1a numeric value assigned by applications.

## 4.4.5 Functions

Element type: | miSCENE_FUNCTION
Data type: | miFunction
Sizes: | int param_size
Defaults: | all nulls

    enum miFunction_type {
            miFUNCTION_C,                           /* regular C/C++ shader */
            miFUNCTION_PHEN,                        /* phenomenon interface */
            miFUNCTION_C_REQ,                       /* C/C++ shader with reqmnts */
            miFUNCTION_OUTFILE,                     /* write an image to a file */
            miFUNCTION_DATA                         /* user data decl, no miFunc */
    };

    typedef struct miFunction {
            miPointer       user;                   /* for shader (init data etc)*/
            miPointer       cached_address;         /* for RC only */
            miPointer       cached_result;          /* array[thread#] of results */
            miPointer       cached_ghost_ptr;       /* if ghost_offs, tag ptrs */
            miPointer       gcache_timestamp;       /* if ghost_offs, eval time */
            miPointer       lightlist;              /* array of lights for shader*/
            miLock          lock;                   /* local shader lock */
            enum miFunction_type type;              /* C/C++, phenomenon, or file*/
            miUint          out_typemap;            /* if output, IMG_TYPE bitmap*/
            miUint          out_interpmap;          /* if output, interpolate bm */
            miTag           function_decl;          /* declaration if C or PHEN */
            miTag           next_function;          /* next function call in list*/
            miTag           parameter_indirect;     /* get params from this func */
            miTag           interfacephen;          /* parent phen, if any */
            miBoolean       spare2;                 /* not used */
            int             parameter_size;         /* size of parameter block */
            int             result_size;            /* size of result struct */
            int             ghost_offs;             /* offset to tag ghost, or 0 */
            int             spare1[2];              /* not used */
            miCBoolean      has_init_shader;        /* init shader exists */
            miCBoolean      func_init;              /* was function initialized? */
            miCBoolean      inst_init_req;          /* init every instance too? */
            miCBoolean      inst_init;              /* was instance initialized? */
            miCBoolean      no_expl_params;         /* candidate for indirect par*/
            miCBoolean      spare[4];               /* not used */
            miCBoolean      simple;                 /* PHEN: can use fast call */
            miUchar         ret_type;               /* PHEN:return type of shader*/
            miUchar         label;                  /* sequential # for bitmasks */
            char            parameters[8];          /* parameter block, then */
                                                    /* miTag ghost for phenomena */
    } miFunction;

A translator must provide: `function_decl` (using mi_scene_link), `parameter_size` (as mi_scene_create argument), `result_size`, `parameters`.
A translator may provide: `next_function`.

Functions are shading functions are pairs of a function identification (the shader name) and a parameter block. They are used for materials, textures, lights, transformations, and many other purposes. Most are called during rendering; some are called during preprocessing or tessellation.

user is not used by mental ray. It is provided so init shaders can access the function and hang local instance data (color tables etc) off this pointer. Previous versions of mental ray required hacks such as adding dummy integers to the shader parameters as a place to store instance data.

cached_address is used to reduce the number of lookups of shader names. After the first lookup, the result of the lookup is cached, and all future lookups first check the address and skip the lookup if it is nonzero. All addresses are stored as a `miPointer` to ensure that they occupy 64 bits in the data structure, regardless of whether the host uses 32-bit or 64-bit pointers.

cached_result is used by mi_call_shader and similar functions to cache the result of the last call to this shader. The cache is an array of `result_size` bytes for each thread. This data structure is maintained by mi_call_shader and should not be modified by translators. This and the next two fields exist to support phenomena.

cached_ghost_ptr is also created and used exclusively by mi_call_shader. It points to an array that has twice the size of the standard tag ghost array (see `parameters` below), and contains one pointer for every tag in that array. It is twice the size because a `miPointer` must be 64 bits wide. The pointer array is used to avoid looking up tags all the time.

gcache_timestamp is also created and used exclusively by mi_call_shader. It points to an array that contains one timestamp for every render thread. Whenever a new phenomenon is executed, a global time (per thread) is incremented. If this global time does not agree with the timestamp, `cached_result` is not valid and the shader must be called. If they do agree, the shader has been called before inside the current phenomenon, and the cached result can be used directly.

lightlist is a pointer to an array of light tags. It is used for shaders that have their light list modified according to the global light list.

lock is a lock shared by all instances of a shader. Every shader such as soft_material has exactly one local lock that is shared by all concurrent invocations of this shader.

out_typemap is a bitmap that contains the image types needed for the function if it is either an output shader or an output file.

out_interpmap is a bitmap that contains the interpolation flags for each bit in the out_typemap bitmap.

function_decl is the declaration of the function, containing both the shader name and a declaration of the parameters it requires. Declaration database elements have type `miSCENE_FUNCTION_DECL`; see below.

next_function references the next function in a chain. Some shader types allow chaining; for example there may be multiple lens shaders anchored in the camera that are called in sequence.

has_init_shader and the other three flags help to determine whether the function and the function instance have been initialized. Except for func_init these flags are copies from the declaration (see below) and are here to find out quickly whether it is necessary to access the declaration and do a full init. They are used internally only to cache declaration flags.

parameter_indirect, if nonzero, is the tag of another function that contains the parameters to be used for this function. parameter_size and parameters are unaffected. This is used for parameterless shadow and photon shaders, which are called with the corresponding material shader's arguments to avoid having to copy the parameters.

interfacephen is the tag of the phenomenon that contains the shader. Presently only used internally to cache the phenomenon tag for lens shaders required by a phenomenon. Should not be used by translators.

parameter_size is the size of the shader parameter area in bytes. Shader parameters are stored at the beginning of the parameters array.

result_size is the number of bytes in the result data structure. By default this is 16 (the size of `miColor`, which is the default return type). It must be set to match the `result_size` field of the declaration.

ghost_offs is nonzero for phenomenon `miFunction`s and provides an offset into the `parameters` array where the tags begin. This value is either zero or the smallest multiple of 4 equal to or greater than `parameter_size` because tags are integers that must be properly aligned.

ret_type is internally used by the PHEN module for caching the function declaration return type.

label is a number in the range 0 ... 255 that helps distinguishing shaders. A new number is assigned automatically whenever a new function is created, but no attempt is made to keep the numbers unique. This helps the incremental rendering heuristics to decide whether a pixel should be re-rendered.

parameters contains one or two variable-sized data areas: the function parameters, arranged as described in the mental ray User Manual, and the optional tag ghost array. A pointer to the parameter block is passed to the shader whenever it is called. The parameters are expected to be laid out as described by the function declaration.

The tag ghost array is used for phenomenon `miFunction`s. It exists only if `ghost_offs` is nonzero. It has the same layout as the parameter array, such that there is one tag for every parameter at the same offset in the respective array. If the tag for a parameter is nonzero, the tag points to another `miFunction` which must be called (unless its cache is valid, in which case the previous result is re-used; see above) to provide the parameter instead of using the parameter directly. In this case the parameter in the parameter array is the offset into the result returned by the call.

## 4.4.6 User Data

Element type: | miSCENE_USERDATA
Data type: | miUserdata
Sizes: | int parameter_size
Defaults: | all nulls

    typedef struct miUserdata {
            miTag           data_decl;              /* parameter declaration */
            miTag           next_data;              /* next data block in list */
            miUint          label;                  /* user-defined label integer*/
            int             parameter_size;         /* size of parameter block */
            short           one;                    /* ==1, for byte order check */
            short           spare1;                 /* not used */
            int             spare2;                 /* not used */
            char            parameters[8];          /* parameter block */
    } miUserdata;

This element describes a user-definable opaque data block. The API supports setting up these blocks from literal data, from a file, or from shader-like declared parameters. The purpose is carrying user data to shaders that would be too large, contain nonstandard data types, or be repeated in too many places to make storing it as shader parameters feasible. Except in the shader-like parameter case, the data is not byte-swapped by mental ray when transported to another host; this becomes the responsibility of the data recipient.

data_decl is the tag of the declaration of the parameters, if the user data block is defined with parameters. If it was defined with literal data or read from a file, this field is a null tag.

next_data allows chaining of user data blocks, much like shaders can be chained.

parameter_size is the number of bytes stored in this data block, beginning at parameters. The rest of the header leading up to the data is not included. Zero is allowed but not useful. mental ray warns if a data block is defined larger than 16 MB.

one is set to 1 when the data block is defined, and when it was defined with parameters and has been imported and byte-swapped. Since literal and file user data blocks are not swapped, the data recipient must assume that non-byte data read from the user data block must be byte-swapped if one has the value 0x0100 instead of 1.

parameters contains the user data. Although declared with only eight characters, it is allocated smaller or larger depending on the user data block size such that it holds parameter_size bytes.

## 4.4.7 Function Declarations

Element type: | miSCENE_FUNCTION_DECL
Data type: | miFunction_decl
Sizes: | int decl_size
Defaults: | all nulls, type `miFUNCTION_C`

    typedef enum {
            miTYPE_BOOLEAN = 0,                     /* simple types: used for */
            miTYPE_INTEGER,                         /* returns and parameters */
            miTYPE_SCALAR,
            miTYPE_STRING,
            miTYPE_COLOR,
            miTYPE_VECTOR,
            miTYPE_TRANSFORM,
            miTYPE_SHADER,                          /* complex types: used for */
            miTYPE_SCALAR_TEX,                      /* parameters only */
            miTYPE_COLOR_TEX,
            miTYPE_VECTOR_TEX,
            miTYPE_LIGHT,
            miTYPE_STRUCT,
            miTYPE_ARRAY,
            miTYPE_TEX,
            miTYPE_MATERIAL,                        /* phenomenon types */
            miTYPE_GEOMETRY,
            miTYPE_DATA,                            /* free-form user data */
            miNTYPES
    } miParam_type;

    typedef struct miPhen_decl {
            int             n_subtags;              /* # of subshader/mtl tags */
            miTag           root;                   /* root attachment point */
            miTag           lens;                   /* optional lens shaders */
            miTag           output;                 /* optional output shaders */
            miTag           volume;                 /* optional volume shaders */
            miTag           environment;            /* optional environm. shaders*/
            miTag           geometry;               /* optional geometry shaders */
            miTag           contour_store;          /* opt'l contour store func */
            miTag           contour_contrast;       /* opt'l contour contrast f. */
            int             lens_seqnr;             /* opt'l sequence number */
            int             output_seqnr;           /* opt'l sequence number */
            int             volume_seqnr;           /* opt'l sequence number */
            int             environment_seqnr;      /* opt'l sequence number */
            /* Fuzzy booleans (0=dont care, 1=false, 2=true) */
            miCBoolean      scanline;               /* need scanline? */
            miCBoolean      trace;                  /* need ray tracing? */
            /* Normal Booleans (these cannot be set explicitly off): */
            miCBoolean      deriv1;                 /* need first derivatives? */
            miCBoolean      deriv2;                 /* need second derivatives? */
            miUchar         mintextures;            /* not used */
            miUchar         minbumps;               /* not used */
            miUchar         minusers;               /* not used */
            miUchar         parallel;               /* parallel output shader */
            char            shadow;                 /* 0, 1, 'l' sort, 's' segm */
            char            face;                   /* 'f'ront, 'b'ack, 'a'll */
            char            render_space;           /* 'c'amera, 'o'bject, 0 any */
            char            spare2;                 /* not used */
    } miPhen_decl;

    typedef struct miFunction_decl {
            miLock          lock;                   /* local shader lock */
            miPointer       cached_address;         /* for RC only */
            enum miFunction_type type;              /* C function or phenomenon */
            miParam_type    ret_type;               /* return type of shader */
            int             declaration_size;       /* size of declaration */
            int             result_size;            /* size of result struct */
            int             version;                /* shader version from .mi */
            miUint          apply;                  /* what can it be used for? */
            miPhen_decl     phen;                   /* if type==miFUNCTION_PHEN */
            int             spare[2];               /* not used */
            miCBoolean      has_init_shader;        /* init shader exists */
            miCBoolean      has_no_init_shader;     /* checked before, no init sh*/
            miCBoolean      inst_init_req;          /* init every instance too? */
            miCBoolean      func_init;              /* was function initialized? */
            char            name[miNAMESIZE];       /* ascii name */
            char            declaration[4];         /* declaration string */
    } miFunction_decl;

    #define miDECL_SUBTAG(d,i) (...)

A translator must provide: `name`, `result_size`, `declaration`, `version`.
A translator may provide: `type`, `ret_type`.
Provided by mi_scene_create: `parameter_size`, `declaration_size`, `parallel`, `apply`.

lock is a lock shared by all instances of a shader. Every shader such as soft_material has exactly one local lock that is shared by all concurrent invocations of this shader.

cached_address is used to reduce the number of lookups of shader names. After the first lookup, the result of the lookup is cached, and all future lookups first check the address and skip the lookup if it is nonzero. The address is a `miPointer` because the structure must have the same size regardless of whether pointers are 32 or 64 bits.

type must currently be `miFUNCTION_C`.

ret_type is the return type of the function. For backwards compatibility, undefined return types default to `miTYPE_COLOR`. The type is important for subshaders in shader trees. Only ``simple types'' are allowed here.

has_init_shader and the other three flags help the renderer to determine whether the function and the function instance have been initialized. has_no_init_shader is intended for remembering whether the renderer has already checked whether there is an init shader; if not, no further tests are needed.

name is an ASCII string identifying the shader. This name will be looked up in LINK's symbol table at runtime.

parameter_size helps the translator decide how many bytes to allocate when a new `miFunction` entry is allocated, see above. The parameter size does not include space needed for parameter arrays.

declaration_size is the size of the declaration array in bytes, including the trailing null byte.

result_size is the number of bytes in the result data structure. By default this is 16 (the size of `miColor`, which is the default return type). It must be set to match the `result_size` field of the declaration.

version is the declaration version. It can be queried by the shader using mi_query and allows the shader to ensure that the declaration and the shader agree. Also, if a shader library contains a function named shadername`_version`, it is caled and its returned integer value must match the version. It is highly recommended to use this feature.

apply is a bitmap that specifies what the shader can be used for. Each bit stands for a specific type of shader:

`miAPPLY_LENS` | lens shader in a camera
`miAPPLY_MATERIAL` | material shader in a material
`miAPPLY_LIGHT` | light shader
`miAPPLY_SHADOW` | shadow shader in a material
`miAPPLY_ENVIRONMENT` | environment shader in a material or camera
`miAPPLY_VOLUME` | volume shader in a material or camera
`miAPPLY_TEXTURE` | texture shader
`miAPPLY_PHOTON` | photon shader in a material
`miAPPLY_GEOMETRY` | geometry shader
`miAPPLY_DISPLACE` | displacement shader in a material
`miAPPLY_PHOTON_EMITTER` | photon emitter shader in a light
`miAPPLY_OUTPUT` | output shader in a camera

If the apply bitmap is zero (the default), it is not known what the shader can be used for, and all uses are legal. mental ray does not currently enforce non-applicability, this is only a hint.

phen is a substructure containing fields used if the `type` is `miFUNCTION_PHEN`. The `miPhen_decl` substructure is still under development. Note that phenomena keep a list of tags of shaders, materials, lights, and other sub-objects defined in the scope of the phenomenon in a tag list that follows the declaration string. Tags in this list can be accessed with the `miDECL_SUBTAG` macro.

declaration describes the parameter layout required by the shader. It is a sequence of ascii characters, each describing a type or structure; the sequence is an abbreviated form of the declaration syntax in the .mi file. The declaration is a list of return and parameter declarations. Each list item begins with an optional `'a'` for array, followed by the type (one of `biscvtSCVlS$` for boolean, integer, scalar, color, vector, transform, scalar texture, color texture, vector texture, light, shader, and string) followed by a double-quoted name. Substructures are defined with {`"`name`"` followed by the structure name followed by the structure definition followed by }. The declaration has two parts separated by an equals sign; the first part declares the return type and the second part declares the parameters. The first part may have only one field that may not be an array and whose double-quoted name part is omitted, but it may be a structure containing named fields. One null byte terminates the entire declaration.

For example, a shader returning a color r and accepting three parameters, a scalar s, an array of structures t containing two integers i1 and i2, followed by a light array l would lead to the following declaration string:

`c=s"s"a`{`"t"i"i1"i"i2"`}`al"l"`

If the return type were a structure containing a color c and a boolean b, the declaration changes to:

{`c"c"b"b"`}`=s"s"a`{`"t"i"i1"i"i2"`}`al"l"`

## 4.4.8 Boxes

Element type: | miSCENE_BOX
Data type: | miBox
Sizes: | miVector_list *, miVertex_content *,
| int nvert, npri, enum miBox_type type, miBoolean moving
Defaults: | all nulls except stored arguments

       enum miBox_type { miBOX_TRIANGLES, miBOX_ALGEBRAICS };

       typedef struct miBox {
            miUint          label;          /* translator: object label */
            miTag           next_box;       /* translator or gap: box list  */
            enum miBox_type type;           /* type of primitives */
            miBoolean       visible;        /* visible? */
            miBoolean       shadow;         /* casts shadow? */
            miBoolean       trace;          /* visible as reflection? */
            miBoolean       mtl_is_label;   /* triangle mtls are labels */
            miUint1         caustic;        /* bit0=cast, bit1=receive */
            miUint1         globillum;      /* bit0=cast, bit1=receive */
            miCBoolean      spare[6];       /* not used */
            miTag           userdata;       /* optional user data blocks */
            int             spare2[2];      /* not used */
            miVertex_content vert_info;     /* size  content of vertices */
            miVector_list   vect_info;      /* sections of vector array */
            miIndex         no_vertices;    /* number of vertices */
            miIndex         no_primitives;  /* number of primitives */
            miVector        bbox_min;       /* bounding box: low corner */
            miVector        bbox_max;       /* bounding box: high corner */
            miVector        vectors[1];     /* vectors, vertices, primitives */
    } miBox;

A translator must provide: `vectors`, vertices4.1, primitives.
A translator may provide: `label`, `next_box` (using `mi_scene_link`), `visible`, `shadow`, `trace`, `caustic`, `globillum`2.1, and `mtl_is_label`. Provided by mi_scene_create: `type`, `vert_info`, `vect_info`, `no_vertices`, and `no_primitives`

Boxes consists of a `miBox` header, followed by three variable-sized parts: the vector list, the vertex list, and the primitive list. Currently only triangles can be used as a primitive type. All primitives must have the same data type. All primitives in a box were always generated from the same object, no two objects share a box.

label is the label value copied from the object. It is used by shaders only, and can be written to label frame buffers.

next_box is used to chain boxes when more than one box results from an object. The maximum size of boxes is limited by the capacity of `miIndex`.

type is either `miBOX_TRIANGLES` and `miBOX__ALGEBRAICS`. Algebraics are not currently supported. Together with vert_info.motion_offset (which indicates moving motion-blurred geometry if nonzero), the type determines the data type of the primitives, currently only (`miTriangle`.

visible (default `miTRUE`) makes the triangles visible to primary rays.

shadow (default `miTRUE`) enables shadows cast by the triangles.

trace (default `miTRUE`) makes the triangles visible to second-generation rays.

caustic is a bitmap with three valid bits. Bit 0, if set, enables generation of caustics cast by this object. Bit 1, if set, enables receiving caustics. Bit 4, if set, makes this object invisible to caustic photons.

globillum2.1is a bitmap with three valid bits. Bit 0, if set, enables generation of global illumination from this object. Bit 1, if set, enables receiving of global illumination. Bit 4, if set, makes this object invisible to global illumination photons.

mtl_is_label is a flag that informs the renderer that the material field in the triangles does not hold a material but an integer label. The renderer must ignore the material in this case and use the inherited material. This flag is set for tagged objects in the mi2 language.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

no_vertices is the number of vertices, each of which consists of vert_info.sizeof_vertex `miIndex` values.

no_primitives is the number of primitives (triangles or algebraics).

There are two data structures that are used in boxes and several other places to describe the format of vertices and boxes:

    typedef struct miVertex_content {
            miUchar         sizeof_vertex;  /* size of a vertex
                                               (in the input in miGeoIndex's;
                                                in boxes     in miIndex's) */
            miUchar         normal_offset;  /* when 0, not present */
            miUchar         motion_offset;  /* when 0, not present */
            miUchar         derivs_offset;  /* surf derivs, when 0, not present */
            miUchar         derivs2_offset; /* 2nd derivs, when 0, not present */
            miUchar         texture_offset; /* when 0, not present */
            miUchar         no_textures;    /* number of textures */
            miUchar         bump_offset;    /* when 0, not present */
            miUchar         no_bumps;       /* number of bumps */
            miUchar         user_offset;    /* when 0, not present */
            miUchar         no_users;       /* number of user vectors */
    } miVertex_content;

A translator must provide: all fields.

This structure is used in `miBox` to describe which information is stored with each vertex. It is also used to inform the tessellator what information to create vertices with. Vertices always consist of at least one vector reference for the point in space. The normal, the motion vector, the surface derivative pair, the list of textures, the list of bump basis vectors, and the list of user vectors are all optional.

As described in the subsection for boxes below, a vertex is a list of indices into the actual vector table. Each such list begins with the index for the point in space, said to be at offset 0 in the list. The `miVertex_content` structure describes at which offset in the list other vector indices can be found. For example, if there is an index for a normal in the list directly after the index for the point in space, `normal_offset` would be 1. Offset value 0 is reserved for nonexisting items; no item can have offset 0 because the point in space index is stored there.

If some vertices have a certain type type of index and others do not (like some vertices have normals and others do not), the offset in the `miVertex_content` structure is nonzero but the index is set to `miNULL_INDEX` resp. `miNULL_GEOINDEX` in those vertices that do not need it. Using 0 for nonexistent offset members is ok because the first index in a vertex (which has offset 0) is the point in space, which must always exist. Do not confuse null offsets with null indices, which must use `miNULL_INDEX` resp. `miNULL_GEOINDEX` instead of 0 because the first vector in a polygon vector list can be something other than a point in space. This is inconvenient for the polygon-to-box tessellation code because box vector lists are divided into sections, and the vector list does begin with points in space so non-point-in-space indices cannot be 0, but this rule applies only to boxes. Polygon lists mirror the order in the .mi file, which traditionally does allow index 0 for vectors that are not points in space.

The second recurring structure is the vector list header. Depending on whether the list contains miGeoVectors (in the input) or miVectors (in the boxes) miGeoIndex or miIndex variables are used to reference them.

    typedef struct miGeoVector_list {
            miGeoIndex      no_vectors;     /* total number of input vectors */
            miGeoIndex      no_points;      /* number of points in space */
            miGeoIndex      no_normals;     /* number of normals */
            miGeoIndex      no_derivs;      /* number of 1st/2nd surface derivs */
            miGeoIndex      no_motions;     /* number of motion vectors */
            miGeoIndex      no_textures;    /* number of texture coordinates */
            miGeoIndex      no_bumps;       /* number of bump basis vectors */
            miGeoIndex      no_users;       /* number of user-defined vectors */
    } miGeoVector_list;

    typedef struct miVector_list {
            miIndex         no_vectors;     /* total number of box vectors */
            miIndex         no_points;      /* number of points */
            miIndex         no_normals;     /* number of normals */
            miIndex         no_derivs;      /* number of surf. derivs. */
            miIndex         no_motions;     /* number of motion vectors */
            miIndex         no_textures;    /* number of texture vectors */
            miIndex         no_bumps;       /* number of bump vectors */
            miIndex         no_users;       /* number of user vectors */
    } miVector_list;

A translator must provide: all fields.

All the vertex indices described by the `miVertex_content` structure are indices into the actual vector list. The vector list itself is partitioned in the seven ``sections'': one for points in space, one for normals, one for surface derivatives, and so on. This partitioning allows the preprocessing stage to quickly transform a box without traversing the vertex index list; points are transformed in a different way than normals or motion vectors, and some vectors such as user vectors are not transformed at all.

The complete box structure can be summarized as:

Box Geometry Storage

The header is declared as `miBox` itself. The vector part is a `miVector` array. The vertex part is a `miIndex` array. The primitive part is an array of triangles, which are declared as follows. Fields marked ``R:'' are reserved for the renderer and should not be used by any other module.

    enum miTriangle_projection { TRI_XY_P = 0, TRI_YZ_P, TRI_ZX_P,
                                 TRI_XY_N = 4, TRI_YZ_N, TRI_ZX_N };

    /* gap_flags */
    #define miISOLATED_TRI 0x1
    #define miIS_STRIP 0x2
    #define miSTRIP_BEGIN 0x4
    #define miSTRIP_RIGHT 0x8

    typedef struct {
            miUchar         proj;           /* R: miTriangle_projection flag */
            miUchar         gap_flags;      /* flags for strip output */
            miIndex         a;              /* vertex index */
            miIndex         b;              /* vertex index */
            miIndex         c;              /* vertex index */
            miTag           material;       /* opt. material */
            miVector        normal;         /* R: normal */
            miScalar        d;              /* R: distance */
    } miTriangle;

A translator must provide: `a`, `b`, `c`, `material`.

projection is a flag used by the renderer to cache the best projection plane of the triangle. Possible values are `TRI_XY`, `TRI_XZ`, and `TRI_YZ`. It is declared as a `miUchar` because declaring it as an `enum miTriangle_projection` (a 4-byte `int`) would cause a structure misalignment.

gap_flags store information about triangle strips indicating whether the triangle is not adjacent to its predecessor or successor in the box (`miISOLATED_TRI`), whether it belongs to a strip or fan (`miIS_STRIP`), whether it is the first triangle of a fan or strip (`miSTRIP_BEGIN`), and the type of strip (`miSTRIP_RIGHT`). `gap_flags` are computed when the option `strips` is set.

a, b, c are indices into the vertex list. The first vertex is numbered 0. The indices are multiplied by vert_info.sizeof_vertex before the actual array lookup; up to 65536 vertices can be indexed.

material is the tag of a material for this primitive. The referenced database element must have type `miSCENE_MATERIAL`.

normal is the geometric triangle normal. Normals are calculated and accessed by the renderer only.

## 4.4.9 Objects

Element type: | miSCENE_OBJECT
Data type: | miObject
Sizes: | --
Defaults: | as described below

    enum miObject_type {
            miOBJECT_POLYGONS,
            miOBJECT_FACES,
            miOBJECT_BOXES,
            miOBJECT_SPACECURVES,                   /* for future use */
            miOBJECT_SUBDIVSURFS,                   /* for future use */
            miOBJECT_ALGEBRAICS                     /* for future use */
    };

    typedef struct miObject {
            miTag                   boxes;          /* SCENE: cached shared tess */
            int                     n_boxes;        /* SCENE: # of boxes attached */
            miTag                   geogroup;       /* SCENE: geomshader group */
            enum miObject_type      type;           /* which in union to use */
            miBoolean               visible;        /* object visible? */
            miBoolean               shadow;         /* cast a shadow? */
            miBoolean               trace;          /* reflection and refraction? */
            miUint1                 caustic;        /* bit0=cast, bit1=receive */
            miUint1                 globillum;      /* bit0=cast, bit1=receive */
            miCBoolean              spare_1[2];     /* not used */
            miBoolean               view_dependent; /* miOBJECT_FACES only */
            miBoolean               mtl_is_label;   /* poly/surf mtls are labels */
            miScalar                maxdisplace;    /* max return of displ shader*/
            miBoolean               spare_2[1];     /* not used, for padding */
            miTag                   userdata;       /* optional user data blocks */
            miUint                  label;          /* optional label */
            miVector                bbox_min;       /* bounding box: low corner */
            miVector                bbox_max;       /* bounding box: high corner */
            miTag                   functions;      /* SCENE: material req list */
            unsigned int            n_functions;    /* SCENE: # tags in functions*/
            union {
                miPolygon_list      polygon_list;
                miFace_list         face_list;
                miTag               box_list;
                miSpacecurve_list   spacecurve_list;/* for future use */
                miSubdivsurf_list   subdivsurf_list;/* for future use */
            }                       geo;            /* geometry */
    } miObject;

    typedef struct miPolygon_list {
            miGeoIndex              no_polygons;
            miGeoIndex              no_indices;
            miGeoIndex              no_vertices;
            miGeoVector_list        vect_info;      /* contents of vector array */
            miVertex_content        vert_info;      /* vertex size & content */
            miTag                   polygons;       /* array of miPolygon */
            miTag                   indices;        /* array of miGeoIndex */
            miTag                   vertices;       /* see vert_info */
            miTag                   vectors;        /* array of miGeoVector */
            miApprox                approx;         /* poly approx technique */
    } miPolygon_list;

    typedef struct miFace_list {
            miGeoIndex      no_faces;
            miGeoIndex      no_surfaces;
            miGeoIndex      no_curves;
            miGeoIndex      no_specpnts;
            miGeoIndex      no_surf_scalars;
            miGeoIndex      no_curve_scalars;
            miTag           faces;                  /* array of miFace */
            miTag           surfaces;               /* array of miSurface */
            miTag           curves;                 /* array of miCurve */
            miTag           specpnts;               /* array of miCurve_point */
            miTag           surf_scalars;           /* array of miGeoScalar */
            miTag           curve_scalars;          /* array of miGeoScalar */
            miTag           basis_list;             /* miBasis_list */
    } miFace_list;

    typedef struct miSpacecurve_list {
            miGeoIndex      no_spacecurves;
            miGeoIndex      no_curves;
            miGeoIndex      no_specpnts;
            miGeoIndex      no_curve_scalars;
            miTag           spacecurves;            /* array of miSpacecurve */
            miTag           curves;                 /* array of miCurve */
            miTag           specpnts;               /* array of miCurve_point */
            miTag           curve_scalars;          /* array of miGeoScalar */
            miTag           basis_list;             /* miBasis_list */
            miBoolean       pad;                    /* not used */
    } miSpacecurve_list;

A translator must provide: `type`; all `miPolygon_list` fields for polygonal objects; `no_faces`, `no_surfaces`, `no_surf_scalars`, `faces`, `surfaces`, `surf_scalars`, `basis_list`.

boxes is used to point to boxes that resulted from tessellation. They are used in two cases only: object or box instances attach to the cached untransformed boxes (see above for a definition) if enabled; and leaf instances attach to the final renderable representation.

n_boxes is the number of boxes attached to boxes. Keeping this separate avoids having to access boxes to count them.

geogroup is used to point to the group element which contains all the geometry-shader created scene elements for this object.

type (default `miOBJECT_POLYGONS`) specifies the type of the geometry attached to this object. It may be one of `miOBJECT_POLYGONS`, `miOBJECT_FACES`, `miOBJECT_BOXES`, or `miOBJECT_ALGEBRAICS`. This field determines which member of the union is used. Algebraics are not currently supported.

visible (default `miTRUE`) makes the object visible to primary rays.

shadow (default `miTRUE`) enables shadows cast by this object.

trace (default `miTRUE`) makes the object visible to second-generation rays.

view_dependent (default `miFALSE`) enables view-dependent tessellation if the object has type `miOBJECT_FACES`. It should be set to `miTRUE` iff any of the surfaces in the object references a view-dependent approximation. It should not be changed between preprocessing and postprocessing.

caustic is a bitmap with three valid bits. Bit 0, if set, enables generation of caustics cast by this object. Bit 1, if set, enables receiving caustics. Bit 4, if set, makes this object invisible to caustic photons.

globillum2.1is a bitmap with three valid bits. Bit 0, if set, enables generation of global illumination from this object. Bit 1, if set, enables receiving of global illumination by this object. Bit 4, if set, makes this object invisible to global illumination photons.

mtl_is_label is a flag that informs the renderer that the material field in the polygons or surfaces does not hold a material but an integer label. The renderer must ignore the material in this case and use the inherited material. This flag is set for tagged objects in the mi2 language.

userdata2.1allows attaching a user data block (miUserdata) or a chain of user data blocks. Shaders can retrieve the data with mi_query.

label is a 32-bit integer that may be used to identify the object in shaders. mental ray does not use it in any way.

functions if this is not a null tag, it points to a list of material tags. This list represents the required materials for the object.

n_functions the number of tags in the functions taglist.

geo is a union containing type-specific data. The suffix ``_list'' indicates that several types store the actual geometry in one or more lists of specific types; these lists are anchored here. The `box_list` case is a tag of a database element of type `miSCENE_BOX`. The box data type has been described above. Polygonal geometry is stored in four lists, all anchored in the `geo.polygon_list` structure.

The following diagram shows the connections between the four lists:

Polygonal Geometry Storage

Arrows indicate indices into the pointed-to data structure. All four grey boxes are separate Scene database element types, refer to the sections for `miSCENE_POLYGON`, `miSCENE_GEOINDEX`, and `miSCENE_GEOVECTOR`, respectively. The data structures are similar to the box data structure, except that the lists are stored in separate database elements, and that an index list is inserted that allows storing polygons with different numbers of vertices in a `miPolygon` data structure that has a constant size. The polygon points to the first vertex index in the index list and gives the number of vertices, as opposed to triangles in boxes that contain the three vertex indices directly.

geo.polygon_list.no_polygons is the number of polygons in the polygons list.

geo.polygon_list.no_indices is the number of indices in the indices list.

geo.polygon_list.no_vertices is the number of vertices in the vertices list. Each vertex consists of vert_info.sizeof_vertex indices.

geo.polygon_list.vect_info describes the sections of the vector list. For details, see the section for boxes above.

geo.polygon_list.vert_info describes the layout of the indices in the vertex list. For details, see the section for boxes above.

geo.polygon_list.polygons is the tag of the polygon list.

geo.polygon_list.indices is the tag of the index list.

geo.polygon_list.vertices is the tag of the vertex list.

geo.polygon_list.vectors is the tag of the vector list.

geo.polygon_list.approx is the approximation technique for displacement-mapped polygons. (It does not apply to polygons whose material does not specify displacement maps.)

Surface geometry is more complex. It is stored in up to seven different database elements, all of which are anchored in geo.face_list. The term face describes one complete visible free-form surface, which is built from one geometry surface and multiple optional texture surfaces, bump surfaces, and/or motion surfaces that provide certain types of mappings on the surface. For details on texture surfaces, refer to the mental ray User Manual. Unlike polygons, surfaces store their parameter lists and vectors in large `miGeoScalar` lists. This simplifies storing one, two, three, and four dimensional data in the same list. Trimming, hole, and special curves can optionally be attached to faces; they have their own scalar lists. Both surfaces and curves may reference optional special points. Every surface references two bases, and every curve references one base. Again, all lines in the following diagram indicate indices.

Free-form Surface Geometry Storage

geo.face_list.no_faces is the number of faces in the geo.face_list.faces list.

geo.face_list.no_surfaces is the number of surfaces in the geo.face_list.surfaces list.

geo.face_list.no_curves is the number of curves in the geo.face_list.curves list.

geo.face_list.no_specpnts is the number of special points in the geo.face_list.specpnts list.

geo.face_list.no_surf_scalars is the number of surface scalars in the geo.face_list.surf_scalars list.

geo.face_list.no_curve_scalars is the number of curve scalars in the geo.face_list.curve_scalars list.

geo.face_list.faces is the tag of the list of faces.

geo.face_list.surfaces is the tag of the list of surfaces.

geo.face_list.curves is the tag of the list of curve.

geo.face_list.specpnts is the tag of the list of special points.

geo.face_list.surf_scalars is the tag of the list of surface scalars, which are used for parameter vectors, control points, weights etc. that define all surfaces in this object.

geo.face_list.curve_scalars is the tag of the list of curve scalars, which are used for parameter vectors, control points, weights etc. that define all curves in this object.

geo.face_list.basis_list is the tag of the list of all bases.

An object of type `miOBJECT_SPACECURVE` contains a list of space curves. A single space curve consists of curve segments which are approximated as a single three dimensional curve. The approximation result is stored in a miLinebox.

geo.spacecurve_list.no_spacecurves is the number of space curves in the geo.spacecurve_list.spacecurves list.

geo.spacecurve_list.no_curves is the number of curves in the geo.spacecurve_list.curves list.

geo.spacecurve_list.no_specpnts is the number of special points in the geo.spacecurve_list.specpnts list.

geo.spacecurve_list.no_curve_scalars is the number of curve scalars in the geo.spacecurve_list.curve_scalars list.

geo.spacecurve_list.spacecurves is the tag of the list of spacecurves.

geo.spacecurve_list.curves is the tag of the list of curves.

geo.spacecurve_list.specpnts is the tag of the list of curve special points.

geo.spacecurve_list.curve_scalars is the tag of the list of curve scalars.

geo.spacecurve_list.basis_list is the tag of the list of all bases used by the curves.

## 4.4.10 Approximations

Element type: | --
Data type: | miApprox
Sizes: | --
Defaults: | as set by miAPPROX_DEFAULT()

    enum miApprox_method {
            miAPPROX_PARAMETRIC,
            miAPPROX_REGULAR,
            miAPPROX_SPATIAL,
            miAPPROX_CURVATURE,
            miAPPROX_LDA,
            miAPPROX_ADJACENCY,             /* only for curves */
            miAPPROX_ALGEBRAIC,             /* only for surfaces */
            miAPPROX_DEFTRIM,               /* only for miFace def_trim_approx */
            miAPPROX_NMETHODS
    };

    enum miApprox_style {
            miAPPROX_STYLE_NONE,
            miAPPROX_STYLE_GRID,
            miAPPROX_STYLE_TREE,
            miAPPROX_STYLE_DELAUNAY,
            miAPPROX_NSTYLES
    };

    #define miCNST_UPARAM 0 /* regular/parametric only */
    #define miCNST_VPARAM 1
    #define miCNST_LENGTH 0 /* curvature/spatial only */
    #define miCNST_DISTANCE 1
    #define miCNST_ANGLE 2

    typedef struct miApprox {
            miGeoScalar          cnst[3];   /* indexed with miUPARAM...miANGLE */
            miCBoolean           spare0[2]; /* not used                         */
            miCBoolean           any;       /* stop if any criterion is met     */
            miCBoolean           view_dep;  /* view dependent ?                 */
            enum miApprox_method method;
            enum miApprox_style  style;
            miUshort             subdiv[2]; /* recursive subdivision depth      */
            miGeoIndex           max;       /* maximum number of triangles      */
            miGeoIndex           spare1;    /* not used                         */
    } miApprox;
    #define miSWAP_SCENE_APPROX "dddiiiss"

    #define miAPPROX_MAX_SUBDIV 7
    #define miAPPROX_DEFAULT(A) \
            (A).style         = miAPPROX_STYLE_TREE;\
            (A).method        = miAPPROX_PARAMETRIC;\
            (A).view_dep      = miFALSE;            \
            (A).cnst[0]       = 1.0;                \
            (A).cnst[1]       = 1.0;                \
            (A).cnst[2]       = 0.0;                \
            (A).subdiv[miMIN] = 0;                  \
            (A).subdiv[miMAX] = 5;

A translator may provide: all fields.

The approximation structure is a substructure of miPolygon_list, miCurve, and miSurface. It does not have its own database entry and no associated SCENE functions of its own.

method is the approximation method, and must be one of `miAPPROX_PARAMETRIC`, `miAPPROX_REGULAR`, `miAPPROX_SPATIAL`, `miAPPROX_CURVATURE`, `miAPPROX_LDA`, `miAPPROX_ADJACENCY` (available for curves only), and `miAPPROX_ALGEBRAIC` (available for surfaces only). The default is `miAPPROX_PARAMETRIC`. ``LDA'' stands for Length, Distance, Angle; this mode combines the spatial and curvature-dependent modes.

style is the approximation style, and must be one of `miAPPROX_NONE`, `miAPPROX_GRID`, `miAPPROX_TREE`, and `miAPPROX_STYLE_MESH`. Tree mode is the default. The API and GAP module will automatically change the style field to grid mode if the method is parametric or regular.

any, if `miTRUE`, makes the tessellation stop if any criterion is met, instead of when all criteria are met. Close faces are tessellated more finely than distant faces. This mode is not available for the parametric and regular method.

view_dep, if `miTRUE`, turns on view-dependent tessellation. Close faces are tessellated more finely than distant faces. This mode is not available for the parametric and regular method.

cnst[0], cnst[1], and cnst[2] specify the approximation precision. They depend on the approximation method. The defaults are 1.0 (which is not ideal for curvature-dependent tessellation). The cnst array should be indexed using the `miCNST_`* constants.

technique | `cnst[0]` | `cnst[1]` | `cnst[2]`
parametric | number of U subdivs degree | number of V subdivs degree | --
regular | number of U subdivs | number of V subdivs | --
spatial | edge length limit | -- | --
curvature | -- | distance tolerance | angle tolerance
lda | edge length limit | distance tolerance | angle tolerance

subdiv[0] and subdiv[1] specify the recursion limits. The defaults are 0 and 5, respectively. The maximum value is 7. A subdivision level n means that the curve, triangle, or surface is halved in each parameter direction n times, yielding on the order of 2n segments. The limits have no effect on Delaunay triangulation.

max is used only for Delaunay triangulation. It specifies the maximum number of triangles to create. The number may be exceeded if the trimming and hole curves have too many vertices.

## 4.4.11 Polygon Lists

Element type: | miSCENE_POLYGON
Data type: | miPolygon[ ]
Sizes: | int no_polys
Defaults: | all nulls

    typedef struct miPolygon {
            miGeoIndex      no_loops;       /* 1 + (number of holes) */
            miGeoIndex      no_vertices;    /* total number of vertices + headers*/
            miGeoIndex      vertex_idx;     /* into indices list, for sharing */
            miTag           material;       /* surface properties */
            miCBoolean      convex;         /* is polygon convex ? */
            miCBoolean      spare[3];       /* not used */
    } miPolygon;

A translator must provide: all fields except `spare`.

no_loops is the number of loops of the polygon. Every polygon has exactly one outer boundary loop, plus any number of optional hole loops. Every loop is stored as a pseudo-index called a ``header'' that doesn't actually refer to the vector list but gives the number of indices to follow, followed by that many indices.

no_vertices is the total number of headers (the number of holes plus 1) plus the total number of vertices for this polygon.

vertex_idx is an index to the first header of the polygon in the index list. no_vertices indices beginning at vertex_idex define the polygon.

material is the tag of the material of the polygon. It must refer to a database element of type `miSCENE_MATERIAL`.

convex is a flag telling the tessellator that the polygon has no holes and is guaranteed to be convex. This saves time because GAP can use a very simple tessellation algorithm.

## 4.4.12 Polygon Indices

Element type: | miSCENE_GEOINDEX
Data type: | miGeoIndex[ ]
Sizes: | int no_indices
Defaults: | all nulls

Polygon indices are simple `miGeoIndex` arrays. As described above, each polygon indexes a consecutive block of indices that describes one or more loops, each of which begins with a header pseudo-index giving the number of loop indices to follow. Each index indexes into the vertex list, after being multiplied by vert_info.sizeof_vertex.

## 4.4.13 Polygon Vertices

Element type: | miSCENE_GEOVERTEX
Data type: | miGeoIndex[ ]
Sizes: | int no_indices
Defaults: | all nulls

The vertex list is an `miGeoIndex` array. It works exactly like the vertex section of boxes; see above. The vert_info structure in `miPolygon` determines how many indices make up one vertex, and how it is laid out. Note that the no_indices argument of the create and resize functions is the number of indices, not the number of vertices.

## 4.4.14 Polygon Vectors

Element type: | miSCENE_GEOVECTOR
Data type: | miGeoVector[ ]
Sizes: | int no_vectors
Defaults: | all nulls

The vector list is a `miGeoVector` array. It is partitioned into sections as described by the vect_info structure in `miPolygon`.

## 4.4.15 Surfaces: Face List

Element type: | miSCENE_FACE
Data type: | miFace[ ]
Sizes: | int no_faces
Defaults: | all nulls except where otherwise noted

    typedef struct miFace {
            miApprox        def_trim_approx;  /* approx techn. for default trims */
            miGeoRange      range[miUV_DIM];  /* min/max for parameter vals*/
            miGeoIndex      no_curves;        /* total number of curves */
            miGeoIndex      no_surfaces;      /* total # of surfs: 1 geo. + xtras */
            miGeoIndex      surface_idx;      /* surface list index */
            miGeoIndex      curve_idx;        /* index into the 'curves' list*/
            miTag           material;         /* optional: material of the face */
            miVertex_content gap_vert_info;   /* For calculating box sizes */
    } miFace;

A translator must provide: `range`, `no_surfaces`, `surface_idx`, `material`, `gap_vert_info`.
A translator may provide: `def_trim_approx`, `no_curves`, `curve_idx`.

def_trim_approx is the approximation for default trimming curves. Default trimming curves are automatically created if the face has no explicit trimming curves attached. The default trimming curve follows the edges of the face. The `miAPPROX_DEFTRIM` approximation technique, which is allowed only here, should be used as default to create a default trim curve that does not introduce new vertices.

range[miU] and range[miV] specify the minimum and maximum values of the U and V parameter vectors.

no_curves specifies the total number of curves used by this face.

no_surfaces is the total number of surfaces for this face. This is at least 1 for the geometric surface, plus the numbers of texture, bump, and/or motion surfaces.

surface_idx is the index of the first surface in the surface list anchored in the object (see above) that is used for this face. This is the first of no_surfaces consecutive surfaces to use.

curve_idx is the index of the first curve in the curve list anchored in the object that is used for this face. This is the first of no_curves consecutive curves to use.

material specifies the tag of a material to use for the face.

gap_vert_info describes the layout and size of the vertices to create during tessellation. The boxes created during tessellation will get a copy of this vertex info structure.

## 4.4.16 Surfaces: Surface List

Element type: | miSCENE_SURFACE
Data type: | miSurface[ ]
Sizes: | int no_surfaces
Defaults: | all nulls, except where otherwise noted

    typedef struct miSurface {
            miApprox        approx;                 /* approx techn. for surface */
            miApprox        disp_approx;            /* approx for disp. surface */
            miGeoIndex      no_parms[miUV_DIM];     /* no of parameter values */
            miGeoIndex      no_ctls;                /* no of control points */
            miGeoIndex      no_specpnts;            /* no of special points */
            miGeoIndex      scalar_idx;             /* surf_scalar list index */
            miGeoIndex      specpnt_idx;            /* special points list index */
            miGeoIndex      basis_idx[miUV_DIM];    /* index into basis list */
            enum miSurface_type type;
            miUshort        degree[miUV_DIM];       /* from bases, for GAP */
            miUshort        ctl_dim;                /* control pnt dimension */
            miUshort        spare[3];
    } miSurface;

A translator must provide: `type`, `approx`, `disp_approx`, `ctl_dim`, `degree`, `no_parms`, `no_ctls`, `scalar_idx`, `basis_idx`.
A translator may provide: `no_specpnts`, `specpnt_idx`.

type must be one of the following: `miSURFACE_GEOMETRIC`, `miSURFACE_GEOMOTION`, `miSURFACE_TEXTURE`, `miSURFACE_BUMP`, `miSURFACE_TEXBUMP_2D`, or `miSURFACE_TEXBUMP_3D`. The 2D variants perform seam rewind correction, the 3D variants do not. All surfaces begin with either `miSURFACE_GEOMETRIC` or `miSURFACE_GEOMOTION`, optionally followed by one of the others for each texture space, beginning with space 0 up to a maximum of space 63.

approx is the approximation technique as described above, in the `miFace` description.

disp_approx is the approximation technique for the displaced surface, if a displacement shader is available.

ctl_dim is the number of scalars per control point:

| `miSURFACE_GEOMETRIC`, non-rational: | 3
| `miSURFACE_GEOMETRIC`, rational: | 4
| `miSURFACE_GEOMOTION`, non-rational: | 6
| `miSURFACE_GEOMOTION`, rational: | 7
| `miSURFACE_TEXTURE_2D` | 2
| `miSURFACE_TEXTURE_3D` | 3
| `miSURFACE_BUMP`: | 3
| `miSURFACE_TEXBUMP_2D`, non-rational: | 5
| `miSURFACE_TEXBUMP_2D`, rational: | 6
| `miSURFACE_TEXBUMP_3D`, non-rational: | 5
| `miSURFACE_TEXBUMP_3D`, rational: | 6

degree[0] and degree[1] contains the degree of the surface in the U and V directions, respectively. This is used by GAP to cache the degree from the surface bases.

no_parms[0] and no_parms[1] are the lengths of the U and V parameter vectors, respectively.

no_ctls is the total number of control points for this surface. The number of scalars required in the scalar list is no_ctls . ctl_dim.

no_specpoints is the number of special points to be included in the tessellation.

scalar_idx is the index of the first scalar in the surface scalar list (also anchored in the object, see above). The scalar list for one surface consists of the U parameter vector, followed by the V parameter vector, followed by the geometric control points (all X first, then all Y, then all Z, then all W, then all motion X, then all motion Y, then all motion Z, if present), followed by the texture and bump control points in the same XYZW order if present.

specpnt_idx is the index of the first special point in the special points list (anchored in the object) to use.

basis_idx[0] and basis_idx[1] are indices for the bases in the basis list (anchored in the object) to use, separate for the U and V parameter directions.

## 4.4.17 Surfaces: Curve Segment List

Element type: | miSCENE_CURVE
Data type: | miCurve
Sizes: | int no_curves
Defaults: | as described below

    enum miCurve_type {
            miCURVE_TRIM,
            miCURVE_HOLE,
            miCURVE_SPECIAL,
            miCURVE_SPACE
    };

    typedef struct miCurve {
            enum miCurve_type type;
            miApprox        approx;         /* approx techn. for surface */
            miBoolean       new_loop;       /* F=concatenate to prev, T=begin new */
            miUshort        ctl_dim;        /* control point dimension 2 or 3 */
            miUshort        degree;         /* from basis, for ease in GAP */
            miGeoRange      range;          /* min/max for curve params. */
            miGeoIndex      no_parms;       /* number of curve parameters */
            miGeoIndex      no_ctls;        /* number of control points */
            miGeoIndex      no_specpnts;    /* number of special points */
            miGeoIndex      scalar_idx;     /* index into curve_scalar list */
            miGeoIndex      specpnt_idx;    /* index into special points list */
            miGeoIndex      basis_idx;      /* index into basis list */
    } miCurve;

A translator must provide: `type`, `approx`, `new_loop`, `ctl_dim`, `degree`, `range`, `no_parms`, `no_ctls`, `scalar_idx`, `basis_idx`.
A translator may provide: `no_specpnts`, `specpnt_idx`.

type specifies what the curve is used for. It must be one of `miCURVE_TRIM`, `miCURVE_HOLE`, `miCURVE_SPECIAL` or `miCURVE_SPACE`. The default is `miCURVE_TRIM`.

approx is the approximation technique as described above, in the `miFace` description.

new_loop is `miTRUE` for every new loop. Loops can be pieced together from multiple consecutive curves. The default is `miTRUE`.

ctl_dim is the control point dimension; 2 for UV curves or 3 for space curves. The default is 2.

degree is the degree of the curve. The default is 3.

range is the range over which the curve is evaluated. The value depends on the parameter list. The defaults are 0.0 and 1.0.

no_parms is the length of the parameter vectors.

no_ctls is the number of control points for this curve. The number of scalars required in the curve scalar list is no_ctls . ctl_dim.

no_specpoints is the number of special points to be included in the approximation.

scalar_idx is the index of the first scalar in the curve scalar list (also anchored in the object, see above). The scalar list for one curve consists of the parameter vector, followed by the control points (all X first, then all Y, then all Z, if present).

specpnt_idx is the index of the first special point in the special points list (anchored in the object) to use.

basis_idx is the index of the basis in the basis list (anchored in the object) to use.

## 4.4.18 Surfaces: Scalar Lists

Element type: | miSCENE_SCALAR
Data type: | miGeoScalar[ ]
Sizes: | int no_scalars
Defaults: | all nulls

Both surfaces and curves store all their geometric data (parameter lists and control points) in unstructured scalar lists. The exact layout and the size of each control point depends on the surface or curve. Surfaces and curves store their scalars in separate scalar lists, but all surfaces in an object share one scalar list, and all curves in the object share the other (which is omitted if there are no curves). Each surface and curve has an index that specifies where in the respective scalar list the scalars for the surface or curve begin. All scalars for a single surface or curve are consecutive. The internal layout of each such curve depends on the surface or curve; see above for details. In general, the parameter vectors come first, followed by the control points in X, Y, Z, W order. All the X are given before the Y, etc.

## 4.4.19 Surfaces: Curve Point Lists

Element type: | miSCENE_CURVPNT
Data type: | miCurve_point[ ]
Sizes: | int no_points
Defaults: | all nulls

    typedef struct miCurve_point {
            miGeoVector     v;              /* xyz point on surface of curve at t */
            miGeoVector2d   uv;             /* uv value of curve at t */
            miGeoScalar     t;              /* curve parameter value */
            miUshort        flags;          /* GAP: */
            miCBoolean      is_t;           /* is t value present */
            miCBoolean      is_uv;          /* is uv value present */
            miCBoolean      is_v;           /* is xyz value present */
            miCBoolean      spare;          /* not used */
    } miCurve_point;

A translator must provide: all fields except `spare`.

(Despite the name, curve points may also be referenced as special points by surfaces.)

is_t, is_uv, and `is_v`, if `miTRUE`, specify that t, uv, or v are valid, respectively.

t, if enabled by is_t, gives the parameter value of the special point.

uv, if enabled by is_uv, gives the UV value of the curve at the special point.

v, if enabled by is_v, gives the location in space of the special point.

## 4.4.20 Surfaces: Basis Lists

Element type: | miSCENE_BASIS_LIST
Data type: | miBasis_list[ ]
Sizes: | int no_bases, int no_scalars
Defaults: | all nulls

    enum miBasis_type {
            miBASIS_NONE = 0,               /* for internal use */
            miBASIS_BEZIER,
            miBASIS_BSPLINE,
            miBASIS_CARDINAL,
            miBASIS_MATRIX,
            miBASIS_TAYLOR
    };

    typedef struct {
            miGeoIndex      no_bases;
            miGeoIndex      no_scalars;
            miBasis         bases[1];
    } miBasis_list;

    typedef struct miBasis {
            enum miBasis_type type;
            miGeoIndex      degree;         /* undefined for Cardinal */
            miGeoIndex      stepsize;       /* only for miBASIS_MATRIX */
            miGeoIndex      value_idx;      /* index into the basis scalar list */
    } miBasis;

A translator must provide: `type`, `degree`; if the type is basis matrix, also `stepsize` and `value_idx`.

no_bases specifies the number of bases in the basis list.

no_scalars specifies the number of scalars that follow the basis list. Scalars are used for basis matrix bases, which require degree2scalars for a matrix defining the basis. The first scalar in the list has index 0.

bases is the basis array. It is actually allocated larger.

type is one of `miBASIS_BEZIER`, `miBASIS_BSPLINE`, `miBASIS_CARDINAL`, `miBASIS_MATRIX`, and `miBASIS_TAYLOR`.

degree is the degree of the basis.

stepsize is used for basis matrix bases only. For an explanation, see the description of bases in the mental ray User Manual.

## 4.4.21 Surfaces: Algebraic Lists

Element type: | miSCENE_ALGEBRAIC
Data type: | miAlgebraic[ ]
Sizes: | --
Defaults: | --

This type is not currently supported.

## 4.4.22 Space Curves2.1

Element type: | miSCENE_SPACECURVE
Data type: | miSpacecurve[ ]
Sizes: | int no_spacecurves
Defaults: | all nulls except where otherwise noted

    typedef struct miSpacecurve {
            miApprox        def_approx;       /* default approximation */
            miGeoIndex      no_curves;        /* total number of curves */
            miGeoIndex      curve_idx;        /* index into the 'curves' list*/
            miBoolean       pad;              /* not used */
            miVertex_content gap_vert_info;   /* For calculating box sizes */
    } miSpacecurve;

A translator must provide: `no_curves`, `curve_idx`, `gap_vert_info`.
A translator may provide: `def_approx`.

def_approx is the default approximation for curve segments which do not have their own approximation defined.

no_curves specifies the total number of curves used by this space curve.

curve_idx is the index of the first curve in the curve list anchored in the object that is used for this space curve. This is the first of no_curves consecutive curves to use.

gap_vert_info describes the layout and size of the vertices to create during tessellation. The boxes created during tessellation will get a copy of this vertex info structure.

## 4.4.23 Books and Pages

Element type: | miSCENE_BOOK
Data type: | miBook
Sizes: | miGeoIndex line_size, no_lines
Defaults: | all nulls except where otherwise noted

    #define miSCENE_BOOK_MAXSWAP 16

    typedef struct miBook {
            miUint          label;          /* type of book                     */
            miGeoIndex      no_pages;       /* number of used pages             */
            miGeoIndex      page_size;      /* number of lines on first page    */
            miGeoIndex      line_size;      /* size of elments in bytes         */
            miGeoIndex      next_free_line; /* index of next free line          */
            char            swap[miSCENE_BOOK_MAXSWAP];
                                            /* string for change of byte order  */
            miTag           next_book;      /* tag for next book                */
            miTag           pages[1];       /* array of page tags               */
    } miBook;

When a box is created the line size and the swap string must be supplied. The number of lines influences the size of the page. If it is smaller than some threshold a default page size is used.

label is a variable at the disposal of the application using `miBook`s. It is not used by any of the book management functions described below.

no_pages is the number of used memory pages.

page_size is the number of lines on the first page. Consecutive pages grow in geometric progression. The details are implementation dependent and may change in the future.

line_size is the size of the lines in bytes in the current book.

next_free_line is the index of the element of the linked list of free lines.

swap is string of at most `miSCENE_BOOK_MAXSWAP - 1` characters which indicates how the bytes in a line of a book should be swapped when being transferred between machines of different byte order.

next_book is a tag that allows to build chains of books. These may be accessed and enumerated more efficiently than single books.

pages is an array of page tags. It is guaranteed to be big enough to hold all pages that might be allocated to keep the maximum total number of `miMAX_GEOINDEX` lines.

None of the structure elements above except the `label` should be accessed directly. The same applies to the pages the books consist of.

Element type: | miSCENE_PAGE
Data type: | miPage
Sizes: | miGeoIndex page_size, line_size
Defaults: | all nulls except where otherwise noted

    typedef struct miPage {
            char            swap[miSCENE_BOOK_MAXSWAP];
                                            /* string for change of byte order  */
            miGeoIndex      page_size;      /* number of lines on current page  */
            miGeoIndex      line_size;      /* size of elments in bytes         */
    } miPage;

When a page is created the page and line sizes and the swap string must be supplied. However, pages should not be created directly but only through the calls to manage books described below.

`swap` is a string to indicate how lines should be swapped when pages are transferred between machines of different byte order. It has to stored in the pages too, because they are swapped independently of the books.

`page_size` is the number of lines on the current page.

`line_size` is the size of the lines on this page in bytes.

Apart from the Scene module calls to create books etc. the calls to manage books are:

         void *mi_scene_book_get_line(
                 miBook             *book,
                 miGeoIndex         line_num)

Access a line with index `line_num` of a given book and returns a void pointer to it.

         void *mi_scene_book_allocate_line(
                 miBook             *book,
                 miGeoIndex         *line_num)

Return a void pointer to a free element in a given book and set the `line_num` passed by reference. This may be a yet unused line or one that has been previously deleted with a call to `mi_scene_book_release_line`. If the lines on existing pages are exceeded a new page is allocated.

         void mi_scene_book_release_line(
                 miBook             *book,
                 miGeoIndex         line_num)

Delete a line from a given book.

         void mi_scene_book_enumerate(
                 miBook             *book,
                 void               (*cb_func)(void *,
                                               miGeoIndex,
                                               void *),
                 void               *cb_data)

Look at each element in a book in turn and if it is in use executes a call-back function. `mi_scene_book_enumerate` takes three arguments. The first is a pointer to an `miBook`, the second a pointer to the call-back function, and the third a pointer to optional data that are passed to the call-back when it is called. If either the book or the call-back pointer is `NULL` nothing is done. Otherwise the book is traversed and for each valid element the function pointed to by the second argument is called. The argument of this call-back function are a pointer to the element in the book, its index and the optional data pointer. An element in a book is valid if it has been allocated by a call to `mi_scene_book_allocate_line` and not been free-d subsequently by a call to `mi_scene_book_release_line`. Neither the call-back function nor `mi_scene_book_enumerate` return a value.

         miGeoIndex mi_scene_book_free_blk_start(
                 miBook             *book)

Return the index of the first line in the completely unused part of a book.

         miGeoIndex mi_scene_book_no_used_lines(
                 miBook             *book)

Return the number of used lines in a book.

         miGeoIndex mi_scene_book_max_lines(
                 miBook             *book)

Return the maximum allocated number of lines in a book.

         miBoolean mi_scene_book_line_valid(
                 miBook             *book,
                 miGeoIndex         line)

Return `miTRUE` if a given line index refers to a used line and `miFALSE` otherwise.

         miTag mi_scene_book_attach(
                 miTag              old_book,
                 miTag              new_book,
                 miGeoIndex         position)

Concatenate chains of books. Insert the new book at the specified position in the chain and returns the tag of the first book in the chain after insertion.

         miTag mi_scene_book_detach(
                 miTag              book,
                 miGeoIndex         position)

Split off a component from a chain of books. Return the tag of the first book in the remaining chain.

## 4.4.24 Subdivision Surfaces

Element type: | miSCENE_SUBDIVSURF
Data type: | miSurf_subsurf[ ]
Sizes: | int nsdsurfs
Defaults: | all nulls except where otherwise noted

    typedef struct miSurf_subsurf {
            miApprox        approx;         /* approximation technique for      */
                                            /*   subdivision surface            */
            miCBoolean      spare[4];
            miGeoIndex      max_subdiv_level;/* maximum level of vertices and   */
                                            /*   faces in the surface           */
            miTag           base_tris;      /* tag for book of base mesh        */
                                            /*   triangles                      */
            miTag           hira_tri_kits;  /* tag for book of hierarchy        */
                                            /*   triangle kits                  */
            miTag           base_quads;     /* tag for book of base mesh        */
                                            /*   quadrangles                    */
            miTag           hira_quad_kits; /* tag for book of hierarchy        */
                                            /*   quadrangle kits                */
            miSurf_vertex_content vert_info;/* tag for miSurf_vertex_content    */
            miTag           vertices;       /* tag for array of tags for books  */
                                            /*   of vert_info.sizeof_vertex     */
                                            /*   components                     */
    } miSurf_subsurf;

A translator must provide: `approx`, `max_subdiv_level`, a tag for `base_tris` or `base_quads`, `vert_info` and `vertices`. The default of `approx` is set by miAPPROX_DEFAULT(). The default of the tt sizeof_vertex field of the `miSurf_vertex_content` structure is 1.

## 4.4.25 Materials

Element type: | miSCENE_MATERIAL
Data type: | miMaterial
Sizes: | --
Defaults: | all nulls

    typedef struct miMaterial {
            miBoolean       opaque;                 /* no transparency? */
            miTag           shader;                 /* material shader */
            miTag           displace;               /* opt. displacement shader */
            miTag           shadow;                 /* opt. shadow shader */
            miTag           volume;                 /* opt. volume shader */
            miTag           environment;            /* opt. environment shader */
            miTag           contour;                /* opt. contour shader */
            miTag           photon;                 /* opt. photon RT shader */
            miTag           photonvol;              /* opt. photon volume shader */
            int             spare[2];               /* not used */
    } miMaterial;

A translator must provide: `shader`.
A translator may provide: all others.

opaque informs mental ray that the material is always opaque and casts an opaque shadow. This is a hint to mental ray and may not be used by all renderers.

shader is the tag of a material shading function. It must refer to a database element of type `miSCENE_FUNCTION`. This tag may not be `miNULLTAG`.

displace is the tag of an optional displacement shader function.

shadow is the tag of an optional shadow shader function.

volume is the tag of an optional volume shader function.

environment is the tag of an optional environment shader function.

contour is the tag of an optional contour shader function.

photon is the tag of an optional photon shader function.

photonvol is the tag of an optional photon volume shader function.

## 4.4.26 Rendering Options

Element type: | miSCENE_OPTIONS
Data type: | miOptions
Sizes: | --
Defaults: | as described below

The rendering options were designed to accommodate as wide a range of renderers as possible, from simple wireframe displayers to complex ray tracers. The interpretation of the structure members is left to the renderer. Generally, no renderer will require all provided fields; each renderer may use a different subset. This data structures was named `miRc_options` in earlier versions of raylib; the old name still works.

    typedef struct miOptions {
            miBoolean       trace;                  /* 2nd generation ray trace? */
            int             scanline;               /* 0=off, 1=on, 'o'=OpenGL */
            miBoolean       motion;                 /* motion blur? : miFALSE */
            miBoolean       shadow_sort;            /* Obsolete! Do not use */
            miBoolean       preview_mode;           /* for future use */
            int             reflection_depth;       /* refl. trace depth : 1 */
            int             refraction_depth;       /* refr. trace depth : 1 */
            int             trace_depth;            /* refl. + refr. depth : 1 */
            int             min_samples;            /* min. sampling level : -2 */
            int             max_samples;            /* max. sampling level : 0 */
            miColor         contrast;               /* sampling contrast: .1 */
            miColor         time_contrast;          /* temporal sampling contrast*/
            miTag           contour_contrast;       /* NULLTAG */
            miTag           contour_store;          /* NULLTAG */
            miBoolean       caustic;                /* enable caustics: miFALSE */
            miBoolean       globillum;              /* enable global il.: miFALSE*/
            int             caustic_accuracy;       /* no. caus. photons in est. */
            float           caustic_radius;         /* maxdist for caus. photons */
            int             globillum_accuracy;     /* no. glob. photons in est. */
            float           globillum_radius;       /* maxdist for glob. photons */
            float           caustic_filter_const;   /* filter const. for caus. */
            float           filter_size_x;          /* filter size in x : 1.0 */
            float           filter_size_y;          /* filter size in y : 1.0 */
            float           jitter;                 /* sample jittering : 0.0 */
            float           shutter;                /* shutter speed for motion:0*/
            int             subdivision;            /* ray class. adjustment : 0 */
            int             subdivision_2d;         /* eye + shadow adjustment:0 */
            int             subdivision_memory;     /* ray class. memory (mb): 6 */
            int             space_max_size;         /* space subdiv. leaf size: 4*/
            int             space_max_depth;        /* space subdiv. depth : 25*/
            float           grid_size;              /* typical # voxels per tri */
            int             no_images;              /* # images : 1 */
            miImg_type      image_types[miRC_MAX_IMAGES]; /* image types */
            miBoolean       write_image[miRC_MAX_IMAGES]; /* write image?*/
            miBoolean       interp_image[miRC_MAX_IMAGES]; /* interpolate image? */
            miTag           shader_tree_image;      /* for previewing */
            miTag           pixel_sample_image;     /* for previewing */
            miCBoolean      use_shadow_maps;        /* use shadow maps ? 0 */
            miCBoolean      rendering_shadow_maps;  /* Shadow map mode? 0 */
            char            recompute_shadow_maps;  /* 'n'o,'y'es (could be Bool)*/
            char            shadow;                 /* shadow casting? */
            char            caustic_filter;         /* filter-type */
            miCBoolean      spare3;
            char            filter;                 /* sample filter type */
            char            acceleration;           /* acceleration: 'b' */
            char            face;                   /* primitive facing */
            char            field;                  /* field rendering? */
            char            smethod;                /* sampling algorithm */
            char            render_space;           /* coordinate space */
            miCBoolean      pixel_preview;          /* pixel selective sampling */
            miCBoolean      task_preview;           /* task selective sampling */
            miCBoolean      visible_lights;         /* any visible area lights? */
            miCBoolean      shadow_map_motion;      /* motion blurred shadowmaps?*/
            int             task_size;              /* image task size */
            miBoolean       strips;                 /* create triangles in strips*/
            miTag           photonmap_file;         /* photon map file name */
            miBoolean       photonmap_rebuild;      /* photon map rebuild ? */
            int             photon_reflection_depth;/* photon refl. depth */
            int             photon_refraction_depth;/* photon refl. depth */
            int             photon_trace_depth;     /* total photon trace depth */
            int             space_max_mem;          /* maximum bsp memory (mb):0 */
            miPointer       image[miRC_MAX_IMAGES]; /* pointers to frame buffers */
            miCBoolean      no_lens;                /* disable lens shaders */
            miCBoolean      no_volume;              /* disable volume shaders */
            miCBoolean      no_geometry;            /* disable geometry shaders */
            miCBoolean      no_displace;            /* disable displace shaders */
            miUint1         no_output;              /* disable output shaders */
            miCBoolean      no_merge;               /* disable surface merging */
            miUint1         caustic_flag;           /* def. caustic flag for objs*/
            char            diagnostic_mode;        /* miSCENE_DIAG_* flags */
            int             photonvol_accuracy;     /* no. vol. photons in est. */
            float           photonvol_radius;       /* maxdist for vol. photons */
            miUint1         globillum_flag;         /* def. globil. flag for objs*/
            miCBoolean      spare1[9];              /* future disable flags */
            miCBoolean      first_cut;              /* first cookie cut */
            miCBoolean      last_cut;               /* last cookie cut */
            int             cut_windows;            /* cookie cutter cuts: 1 */
            miScalar        cut_expand;             /* tessellate outside frustr.*/
            miTag           userdata;               /* optional user data blocks */
            miApprox        approx;                 /* approximation overrides if*/
            miApprox        approx_displace;        /* style != APPROX_STYLE_NONE*/
            miBoolean       finalgather;            /* fg. for globillum: miFALSE*/
            int             finalgather_rays;       /* no. rays in final gather */
            float           finalgather_maxradius;  /* maxdist for finalgather */
            float           finalgather_minradius;  /* mindist for finalgather */
            float           diag_photon_density;    /* density for diag */
            float           diag_grid_size;         /* gridsize for diag */
            int             spare2[14];             /* not used */
    } miOptions;

A translator must provide: nothing.
A translator may provide: all fields.

The parameters are described very briefly; for a detailed description refer to the mental ray User Manual.

trace (default `miTRUE`) enables ray tracing.

scanline (default `miTRUE`) enables the first-generation scanline algorithm if applicable to improve speed. `miFALSE` disables scanline rendering, and `'o'` replaces the standard scanline renderer with an OpenGL renderer that used the OpenGL hardware of the system for fast rendering (SGI only).

motion (default `miFALSE`) enables motion blurring.

preview_mode (default `miFALSE`) not currently used.

shadow (default `1`) controls shadow casting. It is one of `0` (no shadows), `1` (normal shadows), `'s'` (shadow segments with separate volume shaders), and `'l'` (shadow intersections sorted from the light source towards the illumination point). Note: Version 2.0.8 older versions do not yet support shadow sorting and shadow segments, and use a simple shadow boolean and a nonfunctional shadow_sort flag. Shadow segments belong to a new set of space probing features introduced in 2.0.4.

filter (default `'b'`) is one of `'b'` (box filter), `'t'` (triangle filter), `'g'` (Gaussian filter), `'m'` (Mitchell filter2.1), or `'l'` (Lanczos filter2.1).

acceleration (default `'b'`) is one of `'b'` (space subdivision, BSP), `'c'` (ray classification), and `'g'` (grid).

face (default `'a'`) enables backface culling, one of `'f'` (front-facing only), `'b'` (back-facing only), and `'a'` (both).

field (default `0`) enables field rendering, one of `0` (no field rendering), `'e'` (even fields only), and `'o'` (odd fields only).

reflection_depth (default 1) limits the ray tracing depth for reflection rays.

refraction_depth (default 1) limits the ray tracing depth for refraction or transparency rays.

trace_depth (default 1) limits the ray tracing depth for the sum of all rays.

min_samples (default -2) specifies the minimum number of samples in recursive oversampling mode. At least 2min_samplessamples will be taken.

max_samples (default 0) specifies the maximum number of samples in recursive oversampling mode. At most 2max_samplessamples will be taken.

contrast (default 0.1 0.1 0.1 0.1) specifies the contrast limit above which more spatial samples are taken.

time_contrast (default 0.3 0.3 0.3 0.3) specifies the contrast limit for motion blurring above which more time samples are taken. Because of blurring, this can usually be much higher than the spatial contrast.

contour_contrast (default no shader) specifies a function that computes contrasts in contour rendering mode.

contour_store (default no shader) specifies a function that collects and stores sample information for use by the contour contrast function, in contour rendering mode.

caustic specifies whether caustics should be rendered.

globillum specifies whether global illumination should be rendered. This mode is available only in version 2.1 or later.

caustic_accuracy specifies the number of photons to use when estimating radiance for caustics.

caustic_radius specifies the maximum distance in which photons used in the radiance estimate for caustics are located. If the radius is 0.0 then an estimate based on the scene extent will be used.

global_accuracy specifies the number of photons to use when estimating radiance for global illumination.

global_radius specifies the maximum distance in which photons used in the radiance estimate for global illumination are located. If the radius is 0.0 then an estimate based on the scene extent will be used.

caustic_filter_const is a constant used when filtering caustics radiance estimates.

caustic_filter is the type of filter used: 'b' box filter, 'c' cone filter and 'g' gauss filter.

rendering_caustics is set when caustics are being rendered.

filter_size_x (default 1.0) specifies the width of the filter specified in the `filter` field.

filter_size_y (default 1.0) specifies the height of the filter specified in the `filter` field.

jitter (default 0.0) is the jitter interval. Jittering displaces samples to avoid sampling artifacts.

shutter (default 1.0) is the shutter time of the camera if motion blurring is enabled.

subdivision (default 0) is a correction factor for the number of ray space subdivisions in ray classification acceleration mode.

subdivision_2d (default 0) is a correction factor for the number of shadow ray space subdivisions in ray classification acceleration mode.

subdivision_memory (default 6) specifies how many megabytes the ray classification algorithm should use for acceleration data structures.

space_max_mem (default 0) specifies the maximum memory in megabytes used in the BSP preprocessing. A value of zero indicates that there is no limit on the memory consumption, this is the default. This flag is useful only on multiprocessor machines since the memory consumption increases with the number of rendering threads. When the specified amount of allocated memory is reached, mental ray will prevent threads from being scheduled for preprocessing, thus reducing the memory requirements.

space_max_size (default 4) is the maximum leaf size in BSP mode.

grid_size (default 10.0) specifies the grid size for the grid acceleration method.

space_max_depth (default 24) is the maximum tree depth in BSP mode.

image_types (default `miIMG_TYPE_RGBA`) is an array specifying the image types to be generated during rendering. See the documentation of the IMG module for a list of allowed types.

write_image (default `miTRUE, miTRUE, ...`) specifies for each image whether it is written to a file after rendering completes.

interp_image (default `miTRUE, miFALSE, ...`) specifies for each image whether it is to be interpolated. This means that if fewer than one sample per pixel is taken, the holes are filled in.

shader_tree_image (internal to rc) is an image which remembers which shaders have been used to render each individual pixel. Each pixel contains 32 bits corresponding to 32 different shaders. If shader 31 is used to render a pixel then bit 31 is set in this image for this pixel. If the image uses more than 32 shaders then then the shader number modulo 32 are used to identify the right bit.

pixel_sample_image (internal to rc) is an image in which each pixel set indicates a pixel which should be re-rendered.

no_images (default 1) is the number of valid entries in the three image arrays above.

use_shadow_maps if miTRUE specifies that shadow maps should be used for the light sources which have shadow maps. This is the global on/off control. The default is off.

rendering_shadow_maps is miTRUE when the shadow maps are being rendered. This option is internal to RC and only used to optimize the rendering of shadow maps.

recompute_shadow_maps can be 'y' or 'n'. 'y' means that all shadow maps are recomputed even if they could have been loaded from a file. 'n' means that shadow maps are only computed if they could not be re-used or loaded from a file (shadow maps are recomputed "intelligently" meaning that the shadow map code tries to identify those light sources for which a new shadow map needs to be recomputed. This recomputation currently only applies to light sources for which the position or direction of the emitted light - ie. the transformation matrix - changes in an animation).

pixel_preview is set when pixel previewing should be used. The default is off.

task_preview is set when task previewing should be used. The default is off.

visible_lights is set if there are any area lights with the 'visible' flag. This option is internal to RC and used to optimize rendering.

shadow_map_motion enables motion blurring of shadowmap shadows. The default is on.

task_size (default 0) is the size of the image tasks to be rendered. If it is zero, a heuristic based on the image resolution will be used in RC in order to calculate an appropriate value. task_size can also be specified explicitly.

strips specifies whether the approximated geometry is represented as triangle strips and fans. The default is off.

photonmap_file is a string containing the filename of a file from which a photon map should be loaded (if possible) or otherwise saved to. If this tag is a miNULLTAG then no photon map is loaded or saved.

photonmap_rebuild will, if true, enforce a recomputation of the photon map even if it could have been loaded from a file.

photon_reflection_depth controls the trace depth of reflected photons. The default is 5.

photon_refraction_depth controls the trace depth of refracted photons. The default is 5.

photon_trace_depth controls the combined trace depth of reflected and refracted photons. The default is 5.

image is an array of pointers to frame buffers. It is valid only in output shaders. Use `(miImg_image *)image[n].p` to access.

no_lens, if `miTRUE`, disables all lens shaders. The default is `miFALSE`.

no_volume, if `miTRUE`, disables all volume shaders. The default is `miFALSE`.

no_geometry, if `miTRUE`, disables all geometry shaders. The default is `miFALSE`.

no_displace, if `miTRUE`, disables all displacement shaders. The default is `miFALSE`.

no_output is a bitmap. Bit zero, it set, disables all output shaders. Bit one, if set, disables writing of output image files. The default is zero for both bits.

no_merge, if `miTRUE`, disables all edge merging and adjacency detection. The default is `miFALSE`.

caustic_flag is the default caustic flag for objects. The default value is 3, making all objects caustic generators and caustic receivers.

diagnostic_mode controls alternate rendering modes for diagnostic purposes. It is a bitmap. The only currently supported bit is `miSCENE_DIAG_SAMPLES` which, when set, turns on sample view mode. The default value is zero for all bits.

photonvol_accuracy specifies the number of photons to use when estimating radiance inside participating media.

photonvol_radius specifies the maximum distance in which photons used in the radiance estimate for participating media are located. If the radius is 0.0 then an estimate based on the scene extent will be used.

cut_windows enables rendering every image as n `x` n cut windows if set greater than zero. This is available in mental ray 2.0 and 2.1 only.

cut_expand increases the cut window frustum by a factor all around the frustum if greater than zero, to catch invisible outside geometry that becomes visible because it is displaced into the frustum. The default is 0.1. It has an effect only if cut windows are enabled.

globillum_flag2.1is the default globillum flag for objects. The default value is 3, making all objects globillum generators and receivers.

approx overrides all base surface approximations in objects, both free-form surfaces and polygonal, if the approximation style is not `miAPPROX_STYLE_NONE`. This style is the default, and all other fields are 0. Use the `miAPPROX_DEFAULT` macro to activate this approximation. See the `miApprox` data structure description above.

approx_displace is the same thing for displacement approximations.

finalgather enables final gathering. The default is off.

finalgather_rays is the number of rays shot in each final gather. The default is 1000.

finalgather_maxradius is the maximum radius in which a final gather result can be used for interpolation or extrapolation. If this radius is 0.0 then an estimate based on the scene extent will be used.

finalgather_minradius indicates that a final gather result must be used for interpolation or extrapolation if it is within this distance. If this radius is 0.0, it will be set to 10% of finalgather_maxradius.

## 4.4.27 Images

Element type: | miSCENE_IMAGE
Data type: | miImg_image
Sizes: | --
Defaults: | all nulls

    typedef struct miImg_image {
            miBoolean       filter;         /* caller wants filtered lookups */
            int             dirsize;        /* valid # of filter levels */
            int             dir[miIMG_DIRSIZE]; /* offs from this to other imgs */
            int             width, height;  /* width and height in pixels */
            int             bits;           /* requested bits per comp, 8/16/32 */
            int             comp;           /* requested components/pixel, 1..4 */
            miBoolean       local;          /* local texture, use image/mmap/path*/
            int             null[3];        /* unused */
            int             c[4];           /* local==miFALSE: */
                                            /*      indexed by miIMG_*; 4*height */
                                            /*      component indices follow, */
                                            /*      then component scanlines */
            miPointer       image;          /* local==miTRUE: */
            miImg_file      ifp;            /*      describes open file */
            miBoolean       mmapped;        /*      mmapped, not mi_mem_allocated*/
            char            path[4];        /*      local file name to open */
    } miImg_image;

A translator must provide: nothing.
A translator may provide: nothing.
Provided by mi_scene_create: all fields.

Images consist of three sections: the header (type `miImg_image`), a list of scanlines indices, and the actual uncompressed pixel data. There are height . 4 scanline indices, one set of comp (up to 4) indices for each scanline. They contain indices relative to the first pixel data byte. The pixel data is arranged in one-component scanlines of width component values each. All images are scanned bottom-up. For more details, see the documentation of the IMG module.

filter, if nonzero, enables pyramid texture mode.

dirsize and `dir` are used for internal purposes.

width is the number of pixels per scanline.

height is the number of scanlines.

bits is the number of bits per component pixel.

comp is the number of components per pixel.

local, if false, specifies a local image with scanline index list `c` followed by pixel data. If true, the image is local, which means there is no image data but a reference to an image file, which is loaded or mapped at runtime, once on each host. See the IMG documentation for details.

c is the first scanline index block. Only comp of the 4 available indices are used. It is unused if `local` is true.

image is used to cache the pointer to the local image. This and the remaining fields are used only if `local` is true.

host is the local host ID. The image pointer is valid only if the host ID matches the local host ID. This guards against network transfers.

ifp is used internally to save information about the open local texture file if memory-mapped.

mmapped is true if the local texture is memory-mapped and needs to be unmapped when the texture is invalidated.

path is the path of the file where each host can find the texture when the image is accessed for the first time.

## 4.4.28 Strings

Element type: | miSCENE_STRING
Data type: | char[ ]
Sizes: | int no_chars
Defaults: | --

Strings hold standard null-terminated character strings. They are used for the `string` shader parameter type and for shadowmap file names in lights, and for other purposes. The number of characters passed when creating or resizing the string must include the trailing null byte.

## 4.4.29 Tag Lists

Element type: | miSCENE_TAG
Data type: | miTag[ ]
Sizes: | --
Defaults: | --

Tag lists are not currently used.

#### Footnotes

... vertices4.1
  The next generation of mental ray will remove the limit of 65536 vectors, vertices, and triangles, and all miIndex types will be replaced with miGeoIndex. miBox will be replaced with miGeoBox. Shaders using miBox will need to be changed.

Next: 5. Usage and Command Up: 4. Geometry Shaders Previous: 4.3 Geometry Shader API