Keywords: main

Next: 5. Upgrading Up: 4. Geometry Shaders Previous: 4.2 Geometry Shader API
Subsections

- 4.3.1 Instances
- 4.3.2 Groups
- 4.3.3 Cameras
- 4.3.4 Lights
- 4.3.5 Functions
- 4.3.6 User Data
- 4.3.7 Function Declarations
- 4.3.8 Boxes
- 4.3.9 Objects
- 4.3.10 Approximations
- 4.3.11 Polygon Lists
- 4.3.12 Polygon Indices
- 4.3.13 Polygon Vertices
- 4.3.14 Polygon Vectors
- 4.3.15 Surfaces: Face List
- 4.3.16 Surfaces: Surface List
- 4.3.17 Surfaces: Curve Segment List
- 4.3.18 Surfaces: Scalar Lists
- 4.3.19 Surfaces: Curve Point Lists
- 4.3.20 Surfaces: Basis Lists
- 4.3.21 Space Curves
- 4.3.22 Books and Pages
- 4.3.23 Materials
- 4.3.24 Rendering Options
- 4.3.25 Images
- 4.3.26 Strings
- 4.3.27 Tag Lists

# 4.3 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 3.x. The data structures for mental ray 2.1 are similar, but lack a number of fields. These fields are marked ``3.x''.

## 4.3.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 */
            miTag           light_obj_ring;         /* SCENE: obj-light links */
            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 */
            miUint1         select;                 /* selectable when picking? */
            miCBoolean      mtl_override;           /* inst mtl overrides obj mtl*/
            miUshort        history_size;           /* leaf inst: # of hist tags */
            miUint1         spare2[8];              /* 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, or functions can be referenced. If a function (or function list) is supplied, mental ray will call them during scene preprocessing as geometry shader. They must return a single object tag, which may (and often should) be a placeholder object.

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. (The mtl_override3.xflag modifies the inheritance rules, see below.)

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 by mental ray internally to store tessellation results in leaf instances created during preprocessing.

next and prev are used by mental ray internally to chain leaf instances created during preprocessing.

light_obj_ring3.1 is used internally by mental ray to keep track of geometry area light sources3.1.

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

n_boxes2.1 was the number of boxes attached to boxes.

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. It implements the `hide` flag in the .mi grammar.

gen_motion specifies that motion blur should be generated 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 gen_motion is set to `miGM_INHERIT` here.

visible, shadow, trace, caustic, globillum, and select3.x flags 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 globillum bitmap 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 function sets one or more of the material fields in its material argument, to implement Catia aspect inheritance.

mtl_override3.x changes the inheritance rules for the material or material list stored in this instance. If true, and materials exist, this instance will override materials in instances lower in the DAG and in the object, instead of allowing lower materials to override higher ones. This is useful for implementing highlighting selections.

history_size3.x is set in leaf instances, so that the inheritance function or traversal function3.1 can use the `miLEAFHISTORY`3.x macro to access the inheritance history, beginning at the scene root group (0), followed by the instance in the root group that led to the current location in the DAG (1), all the way to the current instance (history_size - 1). The macro accepts one integer argument (0 for root group etc.) and returns a tag. This is useful in inheritance functions to compare to a selection list and setting a highlight material and mtl_override on a match, for example.

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.3.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 */
            int             spare0[2];      /* not used */
            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, `userdata`, `label`.

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`.

boxes2.1 and n_boxes were used by mental ray 2.x to cache tessellation results. mental ray 3.x only has spare0 fields here and caches geometry in separate data structures.

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.

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

label is a numeric value assigned by applications.

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

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.3.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 */
            miTag           pass;                   /* opt. pass function chain */
            int             spare[14];              /* 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.

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

pass3.1 (default `miNULLTAG`) is the optional first pass statement for multipass rendering.

## 4.3.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,
            miLIGHT_OBJECT,
            miLIGHT_USER
    };

    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;
                    struct miLight_object       object;
            }               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;
    };

    struct miLight_object {
            miTag           object;
    };

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`, `miLIGHT_CYLINDER`, `miLIGHT_OBJECT`3.1, and `miLIGHT_USER`3.1.

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_photons is 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_photons is 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. For geometry area light sources3.1, primitive - > object.object must be an instance that references an object (not an object group).

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.

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

label is a numeric value assigned by applications.

## 4.3.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 */
            miFUNCTION_PASS_SAVE,                   /* write pass file */
            miFUNCTION_PASS_PREP,                   /* pass file preprocessor */
            miFUNCTION_PASS_MERGE,                  /* pass file merge function */
            miFUNCTION_PASS_DELETE                  /* pass file delete */
    };

    typedef struct miFunction {
            miPointer       sparep1[7];
            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       spare0;                 /* 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 */
            miTag           pass_read;              /* pass: infile, infile list */
            miTag           pass_write;             /* pass: outfile or 0 */
            miSint1         pass_maxsamples;        /* pass: max samples or ~0 */
            miCBoolean      spare2[3];              /* not used */
            miCBoolean      no_expl_params;         /* candidate for indirect par*/
            miCBoolean      cloned;                 /* is this a clone */
            miCBoolean      spare3[5];              /* not used */
            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`, `interfacephen`, `ghost_offs`, `no_expl_params`, `label`.

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.

user2.1, cached_address2.1, cached_result2.1, cached_ghost_ptr2.1, gcache_timestamp2.1, and lightlist2.1all assumed that preprocessing or shaders could write to the scene DAG, which is not the case in mental ray 3.0 so these fields were retired. The only field of interest to shaders was user, which could be used to store shader user data, typically in init shaders. New shaders must use mi_query in `miQ_FUNC_USERPTR` mode to access the user pointer.

type is one of the `miFUNCTION_*` values. Note that some types such as `miFUNCTION_OUTFILE` do not actually describe procedural functions; using a `miFunction` here allows convenient chaining of output statements or pass statements3.1 in the camera.

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. In the future, this will also be used for pass functions3.1.

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. `miFunction`s that do not have procedural functions, such as type `miFUNCTION_OUTFILE`, have a null tag here.

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.

parameter_indirect contains the tag of the shader where the parameters should be picked up. It is possible to put a parameterless shadow shader and/or photon shader into a material, that will use the parameters of the material shaders. This avoids redundant parameter lists but creates interdependencies, so it is rarely used.

has_init_shader2.1 and the other three flags have been removed in mental ray 3.0 as well.

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. In mental ray 3.0, it is important to set this field correctly for contour store shaders; this was unnecessary in mental ray 2.1.

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.

pass_read3.1 is the tag of a string (type `miSCENE_STRING`) for pass prep functions attached to the pass chain of the camera; or the tag of a tag list (type `miSCENE_TAG`) containing string tags followed by a null tag, for pass merge functions. The strings are pass file names. Non-pass functions do not use this field.

pass_write3.1 is the tag of a string (type `miSCENE_STRING`) for pass save, pass prep, and pass delete functions attached to the pass chain of the camera. The strings is a pass file name. Non-pass functions do not use this field.

pass_maxsamples3.1 is the max sampling density for the written pass file. The default is `00`, which uses the rendering max sampling value from the options. This field is not currently used.

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

no_expl_params is set if the function has no parameters, and should pick up the parameters from parameter_indirect.

cloned is an internal flag used by mental ray to identify functions that were created during preprocessing to construct new shader chains from Phenomenon roots, for example if a Phenomenon adds a lens shader to the camera lens shader list.

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.3.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.3.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         volume_level;           /* optional volume level */
            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 */
            miCBoolean      cloned;                 /* delete decl when del. shd */
    } miPhen_decl;

    typedef struct miFunction_decl {
            miPointer       sparep[2];
            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      spareb[4];
            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`.

lock2.1 is a lock shared by all instances of a shader.

cached_address2.1 was used internally.

type is one of `miFUNCTION_C` (shader), `miFUNCTION_PHEN` (Phenomenon), `miFUNCTION_OUTFILE` (output file, not a shader), or `miFUNCTION_DATA` (declaration of a user data block, not a shader).

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_shader2.1 and the other three flags were used for remembering inits and exits.

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
`miAPPLY_LIGHTMAP`3.x | light map shader in a material
`miAPPLY_PHOTONVOL`3.1 | photon volume shader
`miAPPLY_OTHER`3.x | general-purpose shader, such as base shader

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.3.8 Boxes

Element type: | miSCENE_GEOBOX
Data type: | miGeoBox
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 miGeoBox {
            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 */
            miUint1         select;         /* selectable when picking? */
            miCBoolean      spare[5];       /* not used */
            miTag           userdata;       /* optional user data blocks */
            miTag           facedata;       /* optional data for triangles */
            miBoolean       spare2;         /* not used */
            miTag           intersect;      /* intersection calculation */
            miVertex_content vert_info;     /* size  content of vertices */
            miVector_list   vect_info;      /* sections of vector array */
            miGeoIndex      no_vertices;    /* number of vertices */
            miGeoIndex      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;

    #define miBOX_GET_VERTICES(box)
    #define miBOX_GET_PRIMITIVES(box)
    #define miBOX_GET_CONTENTS(box,vertices)
    #define miBOX_PRIMITIVE_SIZE(box)

A translator must provide: `vectors`, `bbox_min`, `bbox_max`, vertices, primitives.
A translator may provide: `label`, `visible`, `shadow`, `trace`, `select`3.x, `caustic`, `globillum`, and `mtl_is_label`. Provided by mi_scene_create: `type`, `vert_info`, `vect_info`, `no_vertices`, and `no_primitives`

Boxes consists of a `miGeoBox`3.x 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. One object always creates a single box.

mental ray 2.x had a similar data structure `miBox`2.1. It allowed only 65535 vectors, vertices, and triangles (the corresponding counters were of type `miIndex`, and unsigned short). If an object required more, it had to use multiple boxes, chained with next_box2.1. Note that a future version of mental ray will change this data structure again to introduce vectors with fewer or more than three components.

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

next_box2.1 was used to chain boxes. mental ray 3.0 ignores this field.

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.

select3.x (default `miFALSE`) makes the triangles selectable by select-tracing.

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.

globillum is 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.

userdata allows 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 `miGeoIndex`3.x 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 */
            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         motion_offset;  /* when 0, not present */
            miUchar         no_motions;     /* number of motion vectors */
            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 `miGeoBox` 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 vectors, the surface derivative pair, the list of textures, the list of bump basis vectors, and the list of user vectors are all optional. Multiple motion vectors (up to 15 per vertex) are supported only in mental ray 3.1; mental ray 3.0 has the no_motions field but ignores it when rendering; mental ray 2.1 lacks this field.

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

    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;

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. mental ray 2.1 used a `miVector_list` structure in `miBox` structures with the same fields but `miIndex` types; this was changed in mental ray 3.0.

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, TRI_DEG };

    #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 */
            miUchar         spare[2];       /* not used */
            miGeoIndex      a;              /* vertex index */
            miGeoIndex      b;              /* vertex index */
            miGeoIndex      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`.

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. mental ray 2.1 used the type `miIndex` and allowed only 65535 vertices.

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.

## 4.3.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,
            miOBJECT_SUBDIVSURFS,
            miOBJECT_ALGEBRAICS,                    /* for future use */
            miOBJECT_PLACEHOLDER,                   /* read geometry on demand */
            miOBJECT_HAIR
    };

    typedef struct miObject {
            int                     spare_0[3];     /* not used */
            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 */
            miUint1                 select;         /* selectable when picking? */
            miCBoolean              fine;           /* API: has "fine" miApprox */
            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 */
            miVector                bbox_min_m;     /* bbox shift at T==1.0 (low)*/
            miVector                bbox_max_m;     /* bbox shift at T==1.0 (hi)*/
            miTag                   functions;      /* SCENE: material req list */
            unsigned int            n_functions;    /* SCENE: # tags in functions*/
            miCBoolean              mbox_explicit;  /* motion box given by user */
            miSint1                 min_samples;    /* per-object oversampling, */
            miSint1                 max_samples;    /* defaults -128 and 127 */
            miUchar                 spare_3[13];    /* not used */
            union {
                miPolygon_list      polygon_list;
                miFace_list         face_list;
                miTag               box_list;
                miSpacecurve_list   spacecurve_list;
                miSubdivsurf_list   subdivsurf_list;
                miPlaceholder_list  placeholder_list;
                miHair_list         hair_list;
            }                       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;

    typedef struct miSubdivsurf_list {
            miGeoIndex      no_subdivsurfs;
            miTag           subdivsurfs;
    } miSubdivsurf_list;

    typedef struct miPlaceholder_list {
            miTag           object;                 /* the real object with geom.*/
            miTag           filename;               /* file name to read */
    } miPlaceholder_list;

    typedef struct miHair_list {
            miGeoIndex      no_hairs;               /* number of hairs */
            miGeoIndex      no_scalars;             /* number of vectors */
            miHair_content  hair_info;              /* data attached to hairs */
            miHair_content  vert_info;              /* data attached to vertices,*/
                                                    /* bump vars used for radius */
            miTag           hairs;                  /* 1st hair vec: miInteger[] */
            miTag           scalars;                /* control points: miScalar[]*/
            miInteger       approx;                 /* quality control of approx */
            miTag           material;               /* material for all hairs */
            miScalar        radius;                 /* hair radius, default 1 */
            int             degree;                 /* Bezier degree 1..3, def. 1*/
            int             space_max_size;         /* space subdiv. leaf size */
            int             space_max_depth;        /* space subdiv. tree depth */
    } miHair_list;

A translator must provide: `type`, `fine`, `geo`.

boxes2.1, n_boxes2.1, and geogroup2.1 were used by mental ray 2.1 for caching tessellation and geometry shader results, and have been replaced with spare_0 in mental ray 3.x.

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`, `miOBJECT_SUBDIVSURF`, `miOBJECT_PLACEHOLDER`3.x, or `miOBJECT_HAIR`3.1. This field determines which member of the union is used. Algebraics are not 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.

fine3.1 must be set if the object contains any approximation with the fine3.1 flag set. It is set automatically by API. This field is redundant but allows mental ray to detect very quickly whether the object needs special treatment without scanning its contents.

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.

globillum is 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.

select3.x (default `miFALSE`) makes the object subject to select tracing.

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.

maxdisplace3.x specifies the maximum allowed displacement applied to object control points in local object space in normal direction.

userdata allows 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.

bbox_min3.x and bbox_max3.x are a bounding box that encloses all triangles resulting from tessellating this object, without taking motion blur or displacement into account. For polygons this is the convex hull of all point-in-space vectors, but for other object types better bounding boxes should be found to make rendering more efficient.

bbox_min_m3.x and bbox_max_m3.x are a bounding box of all motion vectors, if there are any. bbox_min_m is composed of all the smalles X, Y, and Z components of all motion vectors, and bbox_max_m is composed of all the greatest components. If setting these fields, set `mbox_explicit`3.1 to `miTRUE`.

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.

mbox_explicit3.1 specifies that the `bbox_min_m` and `bbox_max_m` were specified by the user, and do not represent defaults computed by mental ray.

min_samples3.1 specifies that this object should be oversampled no less than this value. The default is -128, which makes the object default to the minimum sampling value in the options.

max_samples3.1 specifies that this object should be oversampled no more than this value. The default is 127, which makes the object default to the maximum sampling value in the options.

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.

An object of type `miOBJECT_PLACEHOLDER`3.x contains a reference to the actual object containing the geometry, which is created on demand. A placeholder object must have a bounding box, and motion bounding box and maximum displacement fields if applicable, and may contain only a single object group.

geo.placeholder_list.object3.x is the tag of the object that holds the actual geometry. This must be a demand-loaded tag, not a regular tag. The only way to construct such a tag is the mi_api_object_file function. Do not assign or access this field directly.

geo.placeholder_list.filename3.x is the tag of a string containing the .mi scene file name that defines the object. This is only used for placeholder objects defined with mi_api_object_file.

An object of type `miOBJECT_HAIR`3.1 defines an object with a different type of geometry that is not based on triangles but hairs. Since there is typically a very large number of hairs, this is far more efficient in terms of both memory usage and rendering performance. The description is very compact:

Hair Geometry Storage

Hairs are stored in a scalar list. Each hair has some data that is shared by all points of that hair, and some data that is separate for each point of the hair. All hairs share the exact same layout, except that they may have different numbers of points. In this example, each hair has two texel scalars (U and V) and a radius; and each point has a coordinate (X, Y, and Z; mandatory), one motion vector (X, Y, Z), and one texel scalar (T). The `hairs` list contains indices into the scalar list where the corresponding hair begins, plus one extra hair end marker at the end. Here there are two hairs, one with two points and one with three.

geo.hair_list.no_hairs3.1 is the number of hairs, 2 in the example. There is always one more index in the `hairs` list for the end marker. Each index must be greater than the previous by i + j . n, where i is the size of the header (3 in the example), j is the size of a point (7 in the example), and nis the number of points for this hair (2 and 3 in the example). API verifies this.

geo.hair_list.no_scalars3.1 is the number of scalars in the scalar list.

geo.hair_list.hair_info3.1 describes the size and layout of the hair headers in the scalar list. This structure and vert_info work like in objects and boxes (see page ), but count scalars, not vectors.

geo.hair_list.vert_info3.1 describes the size and layout of the points in the scalar list.

geo.hair_list.hairs3.1 is the tag of a database element containing the index integers.

geo.hair_list.scalars3.1 is the tag of a database element containing the scalars.

geo.hair_list.approx3.1 specifies the number of linear segments used to approximate a curve segment, if the degree is higher than 1.

geo.hair_list.material3.1 is the material shader shared by all hairs. If this is a null tag, the material is inherited from the instance.

geo.hair_list.radius3.1 specifies the radius of all hairs, if neither hair_info nor vert_info specify radius values.

geo.hair_list.degree3.1 is the degree of the Bézier curves that approximate the hair. It must be 1, 2, or 3. Each hair is defined by degree . n + 1 points, for some integer n > 0. The approximation will result in n . approx linear segments.

geo.hair_list.space_max_size3.1 specifies the maximum leaf size of the hair BSP tree that is used for intersection testing. If left at 0, mental ray chooses a default.

geo.hair_list.space_max_depth3.1 specifies the maximum depth of the hair BSP tree that is used for intersection testing. If left at 0, mental ray chooses a default.

## 4.3.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_STYLE_CONTOUR,         /* contour-based displacement */
            miAPPROX_STYLE_CONTOUR_NORM,    /* same but shader requires normals */
            miAPPROX_STYLE_FINE,            /* sub-object/subpixel tessellation */
            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 */
            miUint1              sharp;     /* 0=smooth normals, 255=faceted */
            miCBoolean           spare;     /* 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 */
            miScalar             grading;   /* min angle bound for graded meshing*/
    } miApprox;

    #define miAPPROX_MAX_SUBDIV 7
    #define miAPPROX_DEFAULT(A) do { \
            (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).max           = miHUGE_INT;         \
            (A).grading       = 0.0; } while (0)

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 which are now considered obsolete.

style is the approximation style, and must be one of `miAPPROX_NONE`, `miAPPROX_GRID`, `miAPPROX_TREE`, and `miAPPROX_STYLE_FINE`3.1. 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. The fine approximation style3.1 only works with parametric and edge length criteria; the recommended mode is view-dependent edge length with a subpixel diagonal constant. If any approximation in an object uses fine approximation, the miObject should have the `fine` flag set. (See page for more details about fine approximation.)

sharp3.1 controls the normal vector interpolation. If set to 0, mental ray uses the interpolated normal as specified by the base surface, modified by displacement if available. If set to 255 (which corresponds to 1.0 in the .mi scene file), mental ray will use the geometric normal for a faceted look. This is primarily useful in `miAPPROX_STYLE_FINE`3.1 mode. Future version will be able to blend between these two modes.

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.

subdiv specifies the minimum and maximum number of subdivision recursion levels.

grading is used for Delaunay tessellation only, and specifies how gradually the triangle mesh should become finer.

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.3.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.3.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.3.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.3.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.3.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.3.16 Surfaces: Surface List

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

    enum miSurface_type {
            miSURFACE_GEOMETRIC,
            miSURFACE_GEOMOTION,            /* geometric + motion vectors */
            miSURFACE_TEXTURE_2D,           /* texture with/without seam compens */
            miSURFACE_TEXTURE_3D,
            miSURFACE_BUMP,                 /* bump */
            miSURFACE_TEXBUMP_2D,           /* texture + bump */
            miSURFACE_TEXBUMP_3D
    };

    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 `miSURFACE_` constants. 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. (Future versions may have a larger maximum, up to 255.)

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.3.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 */
            enum miCurve_type type;
            int             pad;            /* not used */
    } 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.

type describes what the curve is used for: trimming, hole, special, or space curve.

## 4.3.18 Surfaces: Scalar Lists

Element type: | miSCENE_GEOSCALAR
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.3.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.3.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.3.21 Space Curves

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.3.22 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      first_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 */
            miGeoIndex      last_used_line; /* index of last used 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.

first_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.

last_used_line3.x helps mental ray to manage books more efficiently.

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 call interface function to create books etc., there are a number of extra functions to manage books:

         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.3.23 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 */
            miTag           lightmap;               /* used for lightmaps */
            int             spare[1];               /* 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.

lightmap3.x is the tag of an optional lightmap shader function.

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

    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*/
            short           grid_res[3];            /* grid resolution */
            short           grid_max_size;          /* max obj. in grid cell */
            short           grid_max_depth;         /* max grid nesting */
            miSint1         def_min_samples;        /* min/max samples for objs */
            miSint1         def_max_samples;        /* without min/max, -128 127 */
            int             space_max_size;         /* space subdiv. leaf size: 4*/
            int             space_max_depth;        /* space subdiv. depth : 25*/
            float           shutter_delay;          /* shutter open time: 0 */
            int             no_images;              /* # images : 1 */
            miImg_type      image_types[miRC_MAX_IMAGES]; /* image types */
            miUint4         write_image[miRC_MAX_IMAGES]; /* what to do with it */
            miBoolean       interp_image[miRC_MAX_IMAGES]; /* interpolate image? */
            miTag           finalgather_file;       /* finalgather map file: 0 */
            miCBoolean      space_shadow_separate;  /* space subdiv shadow struct */
            char            spare2[3];              /* not used */
            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      finalgather_rebuild;    /* rebuild FG ?: on*/
            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      samplelock;             /* steady samples?: on */
            miCBoolean      autovolume;             /* internal volumes? */
            miCBoolean      finalgather_view;       /* radii in raster pixels ? */
            miCBoolean      no_hair;                /* disable hair rendering */
            miUint1         n_motion_vectors;       /* global number of motions */
            miCBoolean      no_pass;                /* disable multipass render *
            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 */
            miBoolean       desaturate;             /* for IMG: fade to white? */
            miBoolean       dither;                 /* for IMG: LSB dithering? */
            miBoolean       nopremult;              /* for IMG: A < RGB ok? */
            int             colorclip;              /* for IMG: miIMG_COLORCLIP* */
            float           gamma;                  /* for IMG: gamma, default 1 */
            miTag           inh_funcdecl;           /* inheritance function */
            miColor         luminance_weight;       /* weights to calc intensity */
            int             split_obj_no_triangs;   /* max no_triangs for split */
            int             split_obj_no_faces;     /* max no_faces for split */
            miCBoolean      inh_is_traversal;       /* inh_funcdecl is traversal */
            miUint1         spare4[3];              /* not used */
            float           maxdisplace;            /* override if !=0: default 0*/
    } 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.

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 each direction in recursive oversampling mode. At least 2min_samples samples in each direction will be taken.

max_samples (default 0) specifies the maximum number of samples in each direction in recursive oversampling mode. At most 2max_samples samples in each direction 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.

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

globillum_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.

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, subdivision_2d, and subdivision_memory are obsolete.

grid_res3.1 (default 0 0 0) controls the voxel grid resolution in X, Y, and Z directions, if acceleration is set to 'g' (grid). If all three are 0, mental ray uses a default computed from the scene.

grid_max_size3.1 (default 128) controls the maximum size of each grid voxel, if acceleration is set to 'g' (grid).

grid_max_depth3.1 (default 2) controls the maximum nesting depth of grids, if acceleration is set to 'g' (grid).

min_def_samples3.1 (default -128) applies to all samples (eye rays including all their secondaries) that have not hit any objects with a min_samples field. It specifies the minimum oversampling for such samples. Effectively, it acts as the default in per-object oversampling mode. Like object min/max parameters, it must stay in the overall sampling range specified by min_samples ... max_samples. -128 turns it off; min_samples will be used.

max_def_samples3.1 (default 127) applies to all samples (eye rays including all their secondaries) that have not hit any objects with a max_samples field. It specifies the maximum oversampling for such samples. Effectively, it acts as the default in per-object oversampling mode. Like object min/max parameters, it must stay in the overall sampling range specified by min_samples ... max_samples. 127 turns it off; max_samples will be used.

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

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

shutter_delay3.1 (default 0) allows starting the shutter open interval late. It ranges from t = shutter_delay ro shutter. This is useful for shifting the evaluation time to the center of the frame by setting shutter_delay and shutter to the same value, such as 0.5, and then doing bidirectional postprocessing motion blur.

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

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 3) specifies for each image whether it is sampled (if bit 0 is 1) and written to a file (if bit 1 is 1) after rendering completes. mental ray 2.1 combined both bits into a single boolean.

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.

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

space_shadow_separate3.1 turns on separate BSP trees for traceable and shadow geometry. The trace and shadow flags are attributes of geometric objects. Objects that have both flags go into both BSP trees, which is less efficient.

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).

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.

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

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

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

face (default `'a'`) enables backface culling, one of `'f'` (front-facing only), `'b'` (back-facing only), and `'a'` (both). During rendering, mental ray 3.x copies the face flag to the shader state to make it controllable by shaders.

field is not used.

smethod is not used.

render_space is 'o' for object space (recommended) or 'c' for camera space (default for backwards compatibility).

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_windows2.1 enables rendering every image as n `x` n cut windows if set greater than zero.

cut_expand2.1 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_flag is the default globillum flag for objects. The default value is 3, making all objects globillum generators and receivers.

samplelock (default `miTRUE`) uses the same sampling sequences for every frame, causing sampling noise to remain unchanged in unchanged parts of the scene. If set to `miFALSE`, the sequences are initialized with the frame number to cause moving noise.

autovolume (default `miFALSE` enables automatic volume tracking by mental ray. This allows managing overlapping volumes and a camera that is inside one or more volumes, to always call the correct volume shaders.

finalgather_view (default `miFALSE`) switches the final gather radius parameters from world space to projected raster space.

no_hair3.1, if set, disables hair rendering.

n_motion_vectors3.1 specifies the number of curve segments into which motion transformations should be subdivided to create a smooth curved motion path. This must be a number in the range 1..15. The default is 1. The scene language equivalent is `motion steps`.

no_pass3.1 disables multipass rendering. All pass statements in the camera will be ignored.

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.

diag_photon_density3.x scales the diagnostic photon density mode by defining the density where the diagnostic color range peaks.

diag_grid_size3.x defines the grid width of the diagnostic grid mode.

desaturate3.x used to be set with mi_img_mode2.1. If enabled, colors exceeding the 0..1 range will not be clipped per component, but the whole color is faded to white. This has an effect only when storing colors in 8-bit or 16-bit color frame buffers.

dither3.x was also handled by mi_img_mode2.1. It enables LSB dithering when storing colors in 8-bit or 16-bit color frame buffers, to avoid color banding.

nopremult3.x was also handled by mi_img_mode2.1. It turns off premultiplication when storing colors in the frame buffer.

colorclip3.x was also handled by mi_img_mode2.1. Sets the color clipping when storing colors in 8-bit or 16-bit color frame buffers to `miIMG_COLORCLIP_RGB` (preserve RGB and adjust alpha), `miIMG_COLORCLIP_ALPHA` (preserve alpha and adjust RGB), or `miIMG_COLORCLIP_RAW` (disable color clipping).

gamma3.x was also handled by mi_img_mode2.1. It applies gamma correction if gamma is less than or greater than 1.0, when storing colors in 8-bit or 16-bit color frame buffers.

inh_funcdecl3.x contains the inheritance function.

luminance_weight3.x (default ,,) controls the weights that mi_luminance will assign to R, G, and B, respectively, to compute the luminance value.

split_obj_no_triangs3.x is not used.

split_obj_no_faces3.x is not used.

inh_is_traversal3.1 (mental ray 3.1.2), if true, switches the inheritance function described by inh_funcdecl to a traversal shader. It works the same way but gets a different argument set that is more powerful. New projects should rely on traversal functions instead of inheritance functions.

maxdisplace3.2, if set to a value other than zero, overrides the maxdisplace values when approximating a displaced object. This is useful if an old scene without object maxdisplace values must be rendered without truncating all displacement to zero.

## 4.3.25 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 */
            miCBoolean      local;          /* local texture, use image/mmap/path*/
            miCBoolean      writable;       /* writable texture (eg. light map) */
            miCBoolean      cacheable;      /* cache in parts */
            miCBoolean      spare;          /* unused */
            int             type;           /* requested miIMG_TYPE_* */
            miTag           real_name;      /* (local) file name to open */
            int             null[1];        /* unused */
            int             c[4];           /*      indexed by miIMG_*; 4*height */
                                            /*      component indices follow, */
                                            /*      then component scanlines */
    } 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.

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.

writable3.x, if true, specifies a writable texture. Such textures are created by shaders, usually lightmap shaders3.x, and then written to disk.

cacheable3.1, if true, is used internally to mark images that are paged into a texture cache. Do not set.

local, if true, specifies a local image that each slave on the network must read locally, instead of fetching it across the network from the master.

type is the data type of the image.

real_name2.1 is the tag of a database item of type string (contains a null-terminated ASCII string) that is the full path of the file to open. This name is used for local images, where the file is opened when first accessed (after the usual filename rewriting). For this purpose, the path is not sufficient because it may be truncated. mental ray 3.0 accesses a symbol table to find the name specified with mi_api_texture_file_def instead of relying on real_name, because the file may be demand-loaded or memory-mapped, so that real_name may be unavailable or incorrect.

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

## 4.3.26 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.3.27 Tag Lists

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

Tag lists are used for various purposes, such as material lists stored in the material field of instances.

Next: 5. Upgrading Up: 4. Geometry Shaders Previous: 4.2 Geometry Shader API