Referencing Softimage Objects: CRef
 
 
 

The C++ API uses the CRef class to reference Softimage objects and the CBase class is the base class of all API classes. You can get the underlying object class type of a CRef object to determine if it is compatible with a given API class:

siClassID GetClassID() const;
bool IsA( siClassID in_classID ) const;

CBase provides methods to determine if an API class is compatible with a given Softimage object type or a specific CRef instance:

virtual bool IsA( siClassID in_ClassID ) const;
bool IsA( const CRef& in_ref ) const;

A CRef object can only have one Softimage object type, and a API class can have only one API class type. However, a CRef object can be compatible with many API classes. This compatibility model follows the hierarchy class, so that a CRef object with the siPolygonMeshID type is compatible with PolygonMesh, Geometry and SIObject classes.

The following example demonstrates the use of the RTTI system. The example iterates over a list of objects and gets the geometry of each primitive.

Example: Creating objects in Softimage

This example shows how to hook into Softimage to create a cube, a cone, and add a phong shader to the cone. Then these items are added to the array specified. This function (GetSomeObjects) is also used in the next few examples.

using namespace XSI;

// Fills an array with CRef objects
void GetSomeObjects( CRefArray& io_array, const Application& in_app )
{
		X3DObject myCube;
		X3DObject myCone;
		Material myPhong;

		Model root = in_app.GetActiveSceneRoot();

		root.AddGeometry( L"Cube", L"MeshSurface", L"", myCube );
		root.AddGeometry( L"Cone", L"MeshSurface", L"", myCone );
		myCone.AddMaterial(L"Phong", false, L"", myPhong );

		// add CRef items to the input array
		io_array.Add(myCube.GetActivePrimitive().GetRef());
		io_array.Add(myCone.GetActivePrimitive().GetRef());
		io_array.Add(myPhong.GetRef());
}

Example: Accessing the geometry of 3d objects (typed)

This example uses the GetSomeObjects() function defined in Example: Creating objects in Softimage to populate a reference array and then loop through it, testing each item and printing its name and the number of points on its geometry.

using namespace XSI;
Application app;

CRefArray array;
GetSomeObjects(array,app);

Geometry geom;
Primitive prim;
for (long i = 0; i < array.GetCount(); ++i )
{
	if (array[i].IsA( siPrimitiveID ) )
	{
		prim.SetObject(array[i]);
		geom = prim.GetGeometry();

		app.LogMessage( geom.GetName() + L" is a valid Geometry object: " 
				+ CValue(geom.IsValid()).GetAsText() );
		app.LogMessage( L"Number of points on " + geom.GetName() + L": " 
				+ CValue(geom.GetPoints().GetCount()).GetAsText() );
	}
}

Example: Accessing the parameters of 3d objects

This example uses the GetSomeObjects() function defined in Example: Creating objects in Softimage to populate a reference array and then adds any objects it finds in the scene and the parameters of a new grid to the array. Then it loops through the array, testing each item and printing its class type and some type-specific information.

	using namespace XSI;
	Application app;

	CRefArray array;
	GetSomeObjects(array,app);

	// Find all X3DObject in the scene and adds it to the ref array
	CStringArray emptyArray;
	Model root( app.GetActiveSceneRoot() );

	array += root.FindChildren( L"", L"", emptyArray, true );

	// add grid's parameters to ref array
	X3DObject grid;
	root.AddGeometry( L"Grid", L"MeshSurface", L"", grid );

	array += grid.GetParameters();

	for (long i = 0; i < array.GetCount(); ++i )
	{
		app.LogMessage(L"");

		CRef ref(array[i]);
		app.LogMessage( CString(L">>Reference object class type: ") 
								+ ref.GetClassName() );

		if ( ref.IsA( siSIObjectID ) )
		{
			SIObject siobj(ref);
			app.LogMessage( CString(L"\tObject name: ") + siobj.GetName() );
		}

		if ( ref.IsA( siX3DObjectID ) )
		{
			X3DObject xobj(ref);
			app.LogMessage( CString(L"\tNumber of children : ") + 
							CValue(xobj.GetChildren().GetCount()).GetAsText() );
		}

		if ( ref.IsA( siParameterID ) )
		{
			Parameter param(ref);
			app.LogMessage( CString(L"\tParameter's value : ") + 
							param.GetValue().GetAsText() );
		}
	}

API classes can also accept any kind of object without knowing how to operate on it. If the reference object passed to SetObject is incompatible then the API class is put in an invalid state and all its methods return errors. The code below continues working even though the reference object is incompatible:

Example: Accessing the geometry of 3d objects (not typed)

This example uses the GetSomeObjects() function defined in Example: Creating objects in Softimage to populate a reference array and then loop through it, printing each item's name and the number of points on its geometry. This is similar to the example in Example: Accessing the geometry of 3d objects (typed) but uses the generic SIObject class instead of the specific Primitive and Geometry classes.

	using namespace XSI;
	Application app;

	CRefArray array;	
	GetSomeObjects(array,app);

	Geometry geom;
	Primitive prim;	
	for (long i = 0; i < array.GetCount(); ++i )
	{
		prim.SetObject(array[i]);
		geom = prim.GetGeometry();

		SIObject obj(array[i]);
		app.LogMessage( obj.GetName() + L" is a valid Geometry object: " +
			CValue(geom.IsValid()).GetAsText() );
		app.LogMessage( L"Number of points on " + obj.GetName() + L": " +
			CValue(geom.GetPoints().GetCount()).GetAsText() );
	}
Note

This example is less efficient than the first example. Working in a typed manner like in the first example is much more efficient as it doesn't perform any unnecessary operations as in this example.