Free-Form Surface Geometry

This example is similar to the previous, except that it creates a free-form surface object. The main function is unchanged, as are the beginning and end of create_scene function. Omitted parts are indicated by "..." and should be filled in from the previous example.

...
/*
 * the following code was generated from the cube .mi scene using the
 * mitoapi utility, and heavily cleaned up by hand.
 */

static miGeoVector cpoint[] = {
    { 0.500000, 0.500000, 0.000000 },
    { 1.000000, 0.500000, 0.000000 },
    { 1.000000, 1.000000, 0.000000 },
    { 0.500000, 1.000000, 0.000000 },
    { 0.000000, 1.000000, 0.000000 },
    { 0.000000, 0.500000, 0.000000 },
    { 0.000000, 0.000000, 0.000000 },
    { 0.500000, 0.000000, 0.000000 },
    { 1.000000, 0.000000, 0.000000 },
    { 1.000000, 0.500000, 0.500000 },
    { 1.000000, 1.000000, 0.500000 },
    { 0.500000, 1.000000, 0.500000 },
    { 0.000000, 1.000000, 0.500000 },
    { 0.000000, 0.500000, 0.500000 },
    { 0.000000, 0.000000, 0.500000 },
    { 0.500000, 0.000000, 0.500000 },
    { 1.000000, 0.000000, 0.500000 },
    { 1.000000, 0.500000, 1.000000 },
    { 1.000000, 1.000000, 1.000000 },
    { 0.500000, 1.000000, 1.000000 },
    { 0.000000, 1.000000, 1.000000 },
    { 0.000000, 0.500000, 1.000000 },
    { 0.000000, 0.000000, 1.000000 },
    { 0.500000, 0.000000, 1.000000 },
    { 1.000000, 0.000000, 1.000000 },
    { 0.500000, 0.500000, 1.000000 }
};

struct { int pointref; double weight; } paras[] = {
    {  0, 1.0 },    {  0, 1.0 },    {  0, 2.0 },    {  0, 1.0 },
    {  0, 1.0 },    {  0, 1.0 },    {  0, 2.0 },    {  0, 1.0 },
    {  0, 1.0 },    {  1, 1.0 },    {  2, 1.0 },    {  3, 2.0 },
    {  4, 1.0 },    {  5, 1.0 },    {  6, 1.0 },    {  7, 2.0 },
    {  8, 1.0 },    {  1, 1.0 },    {  9, 2.0 },    { 10, 2.0 },
    { 11, 4.0 },    { 12, 2.0 },    { 13, 2.0 },    { 14, 2.0 },
    { 15, 4.0 },    { 16, 2.0 },    {  9, 2.0 },    { 17, 1.0 },
    { 18, 1.0 },    { 19, 2.0 },    { 20, 1.0 },    { 21, 1.0 },
    { 22, 1.0 },    { 23, 2.0 },    { 24, 1.0 },    { 17, 1.0 },
    { 25, 1.0 },    { 25, 1.0 },    { 25, 2.0 },    { 25, 1.0 },
    { 25, 1.0 },    { 25, 1.0 },    { 25, 2.0 },    { 25, 1.0 },
    { 25, 1.0 }
};

static void create_scene(void)
{
    ...

    /*
     * create material
     */

    material = mi_api_material_begin(mi_mem_strdup("mtl"));
    material->opaque = miTRUE;
    material->shader = function;
    mi_api_material_end();

    /*
     * start surface object
     */

    {
    miDlist         *range;
    miGeoScalar     s;
    miApprox        approx;

    object = mi_api_object_begin(mi_mem_strdup("object1"));
    object->visible     = miTRUE;
    object->shadow      =
object->reflection  =
object->refraction  =
object->finalgather = 0x03;
    object->label       = 1;

    /*
     * add a rational Bezier basis with degree 2
     */

    mi_api_basis_add(mi_mem_strdup("bez2"), miTRUE, miBASIS_BEZIER, 2,0,0);

    /*
     * object group: define 26 vectors, then 26 vertices (control points)
     */

    mi_api_object_group_begin(0.0);
    for (i=0; i < 26; i++)
            mi_api_geovector_xyz_add(&cpoint[i]);
    for (i=0; i < 26; i++)
            mi_api_vertex_add(i);

    /*
     * define a surface "surf" with U and V parameter vectors (length 5
     * and 3, respectively), and 45 control points
     */

    mi_api_surface_begin(mi_mem_strdup("surf"), mi_mem_strdup("mtl"));

    range = mi_api_dlist_create(miDLIST_GEOSCALAR);
    for (i=0, s=0; i < 5; i++, s+=0.25)
            mi_api_dlist_add(range, &s);
    mi_api_surface_params(miU, mi_mem_strdup("bez2"),
                            0.0, 1.0, range, miFALSE);

    range = mi_api_dlist_create(miDLIST_GEOSCALAR);
    for (i=0, s=0; i < 3; i++, s+=0.5)
            mi_api_dlist_add(range, &s);
    mi_api_surface_params(miV, mi_mem_strdup("bez2"),
                            0.0, 1.0, range, miFALSE);
    for (i=0; i < 45; i++)
            mi_api_vertex_ref_add(paras[i].pointref, paras[i].weight);

    mi_api_surface_end();

    /*
     * set the approximation
     */

    miAPPROX_DEFAULT(approx);
    approx.method = miAPPROX_PARAMETRIC;
    approx.cnst[miCNST_UPARAM] = 6;
    approx.cnst[miCNST_VPARAM] = 6;
    approx.subdiv[miMIN]       = 0;
    approx.subdiv[miMAX]       = 5;
    approx.max                 = miHUGE_INT;
    mi_api_surface_approx(mi_mem_strdup("surf"), &approx);

    /*
     * finish object group and object
     */

    mi_api_object_group_end();
    mi_api_object_end();
    }

    /*
     * create object instance
     */

    if (instance = mi_api_instance_begin(mi_mem_strdup("object1_inst"))) {
            instance->tf.global_to_local[12] = 0.93;
            instance->tf.global_to_local[13] = 0.13;
            mi_matrix_invert(instance->tf.local_to_global,
                             instance->tf.global_to_local);
            mi_api_light_list_begin();
        mi_api_light_list_add(mi_mem_strdup("light1_inst"));
            instance->light_list = mi_api_light_list_end();
    }
    mi_api_instance_end(mi_mem_strdup("object1"), 0, (miTag)-1);

    /*
     * create root group containing all instances
     */

    ...
}

The create_scene fragment above is equivalent to the following .mi scene language fragment:

object "sphere1"
visible on
shadow 3
reflection 3
refraction 3
finalgather 3
tag 1
    basis "bez2" rational bezier 2
    group
            0.5  0.5  0.0   1.0  0.5  0.0   1.0  1.0  0.0
            0.5  1.0  0.0   0.0  1.0  0.0   0.0  0.5  0.0
            0.0  0.0  0.0   0.5  0.0  0.0   1.0  0.0  0.0
            1.0  0.5  0.5   1.0  1.0  0.5   0.5  1.0  0.5
            0.0  1.0  0.5   0.0  0.5  0.5   0.0  0.0  0.5
            0.5  0.0  0.5   1.0  0.0  0.5   1.0  0.5  1.0
            1.0  1.0  1.0   0.5  1.0  1.0   0.0  1.0  1.0
            0.0  0.5  1.0   0.0  0.0  1.0   0.5  0.0  1.0
            1.0  0.0  1.0   0.5  0.5  1.0

            v 0 v 1 v 2 v 3 v 4 v 5 v 6 v 7 v 8 v 9 v 10
            v 11 v 12 v 13 v 14 v 15 v 16 v 17 v 18 v 19
            v 20 v 21 v 22 v 23 v 24 v 25

            surface "surf" ""
                    "bez2" 0.0 1.0  0.0 0.25 0.5 0.75 1.0
                    "bez2" 0.0 1.0   0.0 0.5  1.0

                     0       0       0 w 2   0       0
                     0       0 w 2   0       0       1
                     2       3 w 2   4       5       6
                     7 w 2   8       1       9 w 2  10 w 2
                    11 w 4  12 w 2  13 w 2  14 w 2  15 w 4
                    16 w 2   9 w 2  17      18      19 w 2
                    20      21      22      23 w 2  24
                    17      25      25      25 w 2  25
                    25      25      25 w 2  25      25

            approximate surface parametric 6 6 "surf"
    end group
end object

instance "object1_inst" "object1"
    light [ "light1_inst" ]
    transform       1    0    0    0
                    0    1    0    0
                    0    0    1    0
                    0.93 0.13 0    1
end instance
Copyright © 1986, 2015 NVIDIA ARC GmbH. All rights reserved.