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 Crosswalk v3.3