Semantic Layer Code Examples

This section contains examples of how to use the Semantic Layer to extract information from the dotXSI file format. These examples answer the questions, “How do I...”:

• Find out how many materials are present in the scene

• Iterate over all the models in the scene

• Create a scene object

• Read a file

• Get information from the scene

• Navigate the list of children and identify the primitive type

• Find the template type for a given primitive and cast the pointer to the appropriate type

• Use Triangles list & Strips and iterate through all the lists and vertices

• Find all sub-operators in an Fx Tree

• Find all parameters of an operator in an Fx Tree

• Get the value of a parameter in an Fx Tree

• Find the CustomParamInfo

• Build a triangle strip converter

Find out how many materials are present in the scene

    #include "stdafx.h"
    #include "SemanticLayer.h"

    main()
    {
       CSLScene Scene;

       if (Scene.Open( "c:\\example.xsi" ) == SI_SUCCESS)
       {
           Scene.Read();
       }
       ULONG l_ulNumMaterial = Scene.GetMaterialLibrary()->GetMaterialCount();
       // Now you have the number of Materials in your material library
       // Regardless of where you have the template, whether it is the first, or the last.
    }

Iterate over all the models in the scene

    #include "stdafx.h"
    #include "SemanticLayer.h"

    void Recurse( CSLModel* in_child )
    {
       //
       // Do what you want with the child,
       //

       printf( "%s\n", in_child->GetName() );

       //
       // Now recurse its children
       //

       CSLModel* *l_childrenList = in_child->GetChildrenList();

       //
       // Loop through all children
       //

       for (int i = 0; i < in_child->GetChildrenCount(); i++ )
       {
           Recurse( l_childrenList[i] );
       }
       return;
    }

    main()
    {
       CSLScene Scene;

       if (Scene.Open( "c:\\example.xsi" ) == SI_SUCCESS)
       {
           Scene.Read();
           Recurse( Scene.Root() );
       }
    }

Create a scene object

    CSLScene l_scene;

Read a file

    if (l_scene.Open( "C:\\example.xsi" ) == SI_SUCCESS)
    {
           l_scene.Read();
    }

Get information from the scene

    EtimingType l_Timing = l_scene.GetTimingType();
    SI_Float l_Start = l_scene.GetStart();
    SI_Float l_End = l_scene.GetEnd();
    SI_Float l_FrameRate = l_scene.GetFrameRate();

Navigate the list of children and identify the primitive type

    void Recurse( CSLModel* in_child )
    {
           switch (in_child->GetPrimitiveType() ) {
           case CSLTemplate::SI_MESH:
              {
                  CSLMesh* left_primitive = (CSLMesh*) in_child->Primitive();
                  break;
              }
           case CSLTemplate::SI_CAMERA:
              {
                  CSLCamera* left_prim  = (CSLCamera*) in_child ->Primitive();
                  break;
              }
           case CSLTemplate::SI_DIRECTIONAL_LIGHT:
           case CSLTemplate::SI_INFINITE_LIGHT:
           case CSLTemplate::SI_POINT_LIGHT:
           case CSLTemplate::SI_SPOT_LIGHT:
              {
                  CSLLight* left_prim  = (CSLLight*) in_child ->Primitive();
                  break;
              }
           case CSLTemplate::SI_IK_ROOT:
              {
                  CSLIKRoot* left_prim  = (CSLIKRoot*) in_child ->Primitive();
                  break;
              }
           case CSLTemplate::SI_IK_JOINT:
              {
                  CSLIKJoint* left_prim  = (CSLIKJoint*) in_child ->Primitive();
                  break;
              }
           case CSLTemplate::SI_IK_EFFECTOR:
              {
                  CSLIKEffector* left_prim  = (CSLIKEffector*) in_child->Primitive();
                  break;
              }
           case CSLTemplate::SI_NURBS_SURFACE:
              {
                  CSLNurbsSurface* left_prim  = (CSLNurbsSurface*) in_child->Primitive();
                  break;
              }
           case CSLTemplate::SI_NURBS_CURVE:
              {
                  CSLNurbsCurve* left_prim  = (CSLNurbsCurve*) in_child->Primitive();
                  break;
              }
           case CSLTemplate::SI_INSTANCE:
              {
                  CSLInstance* left_prim  = (CSLInstance*) in_child->Primitive();
                  break;
              }
           case CSLTemplate::SI_NULL_OBJECT:
              {
              }
           }

Find the template type for a given primitive and cast the pointer to the appropriate type

    if (model->GetPrimitiveType() == CSLTemplate::SI_IK_ROOT)
           CSLIKRoot* primitive = model->GetPrimitive();

Use Triangles list & Strips and iterate through all the lists and vertices

    CSLTriangleList* in_left;
    SI_Int* vertex_ptr = in_left->GetVertexIndicesPtr();
    for (unsigned int i = 0; i < num_triangles; i++)
       {
           printf("Triangle [%d] vertices are [%d,%d,%d]\n", i,
              vertex_ptr[i*3+0],
              vertex_ptr[i*3+1],
              vertex_ptr[i*3+2]);
       }

Find all sub-operators in an Fx Tree

    CSLFXTree* in_left;
    CSLFXOperator** left  =  in_left->GetFXOperatorList();
       for (int i = 0; i < in_left->GetFXOperatorCount(); i++)
           printf("Operator [%s] has [%d] Parameters\n",
              left[i]->GetName(),
              left[i]->GetParameterCount());

Find all parameters of an operator in an Fx Tree

       CSLFXOperator* in_left;
       CSLVariantParameter* param_list = in_left->GetParameterList();
       for (int i=0;i<in_left->GetParameterCount();i++)
           printf("Operator [%s] has Parameter [%s]\n",
              in_left->GetName(),
              param_list[i]->GetName());

Get the value of a parameter in an Fx Tree

    SI_TinyVariant value = parameter->GetValue();

Find the CustomParamInfo

    CSLXSICustomParamInfo* custom_info = in_parameter->CustomParamInfo();
    if (custom_info)
    {
       SI_TinyVariant max, min;
       custom_info->GetMinValue( min );
       custom_info->GetMaxValue( max );
       printf("Capabilities are [%d]\n", custom_info->GetCapabilities() );
    }

Build a triangle strip converter

    #include "stdafx.h"
    #include <SemanticLayer.h>
    #include <windows.h>
    #include "nvstrip\NVTriStrip.h"

    char l_buf[512];

    int StripTriangleList( CSLTriangleList* in_left, CSLMesh* in_mesh )
    {
       //
       // Now we will get the values from the Triangle List and
       // be ready to convert into a Triangle Strip
       //
       SI_Int* vertex_ptr = in_left->GetVertexIndicesPtr();
       SI_Int* nrm_ptr = in_left->GetNormalIndicesPtr();
       SI_Int* col_ptr = in_left->GetColorIndicesPtr();
       SI_Int number_of_uv = in_left->GetUVArrayCount();
       //
       // Prepare the data for stripification
       //
       PrimitiveGroup* result;
       unsigned short num_groups;
       //
       // Get the number of triangle in the triangle list.
       //
       unsigned long num_triangles = in_left->GetTriangleCount();
       //
       // Allocate the data for the indices in unsigned format.
       //
       unsigned short *indices = new unsigned short [ num_triangles * 3 ];
       //
       // Allocate the array for remapping  of the Normals, Vertex Colors,
       // & UV coordinates...
       //
       unsigned short *remap = new unsigned short [ num_triangles * 3];
       for (unsigned int i = 0; i < num_triangles * 3; i++)
       {
           indices[i] = vertex_ptr[i];
       }
       //
       // Set the cache size for the initial size based on the number of triangles.
       //
       SetCacheSize( num_triangles * 3 );
       //
       // Generate the strips based on the indices passed in.
       //
       ::GenerateStrips( indices, num_triangles * 3,  &result, &num_groups );
       for (i = 0; i < result->numIndices; i++)
       {
           sprintf( l_buf, "Value[%d] = %d\n", i, result->indices[i] );
           OutputDebugString( l_buf );
       }
       //
       // Build a remap table
       //
       {
           for (i = num_triangles * 3; i > 0; i--)
           {
              remap[vertex_ptr[i-1]] = i-1;
           }
       }
       //
       // Remap the normals
       //

       {
           for (i = 0; i < result->numIndices; i++)
           {
              sprintf( l_buf, "Normal[%i] = %i\n", i, remap[nrm_ptr[result->indices[i]]] );
              OutputDebugString( l_buf );
           }
       }
       //
       // Adds a new triangle strip list
       //
       CSLTriangleStripList* sl = in_mesh->AddTriangleStripList();
       //
       // Set its material based on what was the material of the triangle list
       //
       sl->SetMaterial( in_left->GetMaterial() );
       //
       // Adds a new strip to the triangle strip
       //
       CSLTriangleStrip* ts = sl->AddTriangleStrip();
       //
       // Transfer the data to the vertex array of the triangle strip.
       //
       CSLTriangleStrip::CSLIntArray* vertex_array = ts->GetVertexIndices();
       for (i = 0; i < result->numIndices; i++)
       {
           vertex_array->Add( result->indices[i] );
       }
       //
       // Now deal with the normal data...
       //
       CSLTriangleStrip::CSLIntArray* normal_array = ts->CreateNormalIndices();
       for (i = 0; i < result->numIndices; i++)
       {
           normal_array->Add(remap[nrm_ptr[result->indices[i]]]);
       }
       if (col_ptr)
       {
           //
           // Now deal with the vertex colors
           //
           CSLTriangleStrip::CSLIntArray* color_array = ts->CreateColorIndices();
           for (i = 0; i < result->numIndices; i++)
           {
              color_array->Add(remap[col_ptr[result->indices[i]]]);
           }
       }
       for (i = 0; i < (unsigned int) number_of_uv; i++)
       {
           //
           // Now deal with the vertex colors
           //
           SI_Int* uv_ptr = in_left->GetUVIndicesPtr(i);

           CSLTriangleStrip::CSLIntArray* uv_array = ts->CreateColorIndices();
           for (i = 0; i < result->numIndices; i++)
           {
              uv_array->Add(remap[uv_ptr[result->indices[i]]]);
           }
       }

       delete [] indices;
       delete [] remap;
       delete [] result;
       //
       // Remove the triangle list...
       //
       in_mesh->RemoveTriangleList( in_left );
       return num_groups;
    }

    //
    // Strips one mesh by processing all its triangle lists it has.
    //
    int StripMesh( CSLMesh* in_left )
    {
       int l_lIndex = 0;
       CSLTriangleList** left;
       left = in_left->TriangleLists();

       for (l_lIndex = 0; l_lIndex < in_left->GetTriangleListCount(); l_lIndex++)
       {
           StripTriangleList( left[l_lIndex], in_left);
       }
       return 0;
    }

    //
    // Strips a model, but will delegate to StripMesh if the primitive is a mesh.
    //
    int Strip( CSLModel* in_left )
    {
       if (in_left->GetPrimitiveType() == CSLTemplate::SI_MESH)
       {
           CSLMesh*  left_primitive = (CSLMesh*) in_left->Primitive();
           StripMesh( left_primitive );
       }
       return 0;
    }

    void Recurse( CSLModel* in_child )
    {
       //
       // Strip the child if need be.
       //
       Strip ( in_child );
       //
       // Now recurse its children
       //
       CSLModel* *l_childrenList = in_child->GetChildrenList();
       //
       // Loop through all children
       //
       for (int i = 0 ; i < in_child->GetChildrenCount(); i++ )
       {
           Recurse( l_childrenList[i] );
       }
       return;
    }
    int Stripify( SI_Char* in_left, SI_Char* in_right )

    {
       CSLScene Scene;

       if (Scene.Open( in_left ) == SI_SUCCESS)
       {
           Scene.Read();
           Recurse( Scene.Root() );
       }

       Scene.Write( in_right );

       Scene.Close();

       return 0;
    }

Autodesk Softimage v7.5