Softimage オブジェクトの参照: CRef

 
 
 

C++ API は CRef クラスを使用して Softimage オブジェクトを参照します。CBase クラスは、すべての API クラスの基本クラスです。 CRef オブジェクトのベースとなるオブジェクト クラス タイプを取得すれば、そのオブジェクトが指定された API クラスと互換性があるかどうかを判別できます。

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

CBase は、API クラスが、指定された Softimage オブジェクト タイプまたは特定の CRef インスタンスと互換性があるかどうかを判別するメソッドを実行します。

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

CRef オブジェクトは Softimage オブジェクト タイプを 1 つだけ持つことができ、API クラスは API クラス タイプを 1 つだけ持つことができます。 ただし、CRef オブジェクトは多くの API クラスと互換性があります。 この互換性モデルは階層クラスに準拠しているため、siPolygonMeshID 型の CRef オブジェクトは、PolygonMeshGeometry、および SIObject の各クラスと互換性があります。

次の例で、RTTI システムの使い方を示します。 この例では、オブジェクトのリストで処理を反復し、各プリミティブのジオメトリを取得します。

例: Softimage でオブジェクトを作成する

この例では、Softimage に接続して立方体、円錐を作成し、Phong シェーダを円錐に追加する方法を示します。 その後、これらのアイテムを指定の配列に追加します。 GetSomeObjects 関数は、次の複数の例でも使用されます。

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());
}

例: 3D オブジェクトのジオメトリにアクセスする(型指定)

この例は、「例: Softimage でオブジェクトを作成する」で定義されている GetSomeObjects()関数を使用してリファレンス配列を登録した後、その中をループさせます。そのときに各アイテムをテストし、アイテムの名前とジオメトリ上のポイントの数を出力します。

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() );
	}
}

例: 3D オブジェクトのパラメータにアクセスする

この例は、「例: Softimage でオブジェクトを作成する」で定義されている GetSomeObjects()関数を使用してリファレンス配列を登録した後、シーン内に検出された任意のオブジェクトおよび新しいグリッドのパラメータを配列に追加します。 その後、配列内をループさせ、各アイテムをテストし、クラスのタイプとタイプ固有の情報を出力します。

	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 クラスは、オブジェクトの操作方法を知らなくても、あらゆる種類のオブジェクトを受け入れることができます。 SetObject に渡されたリファレンス オブジェクトが互換性を持たない場合、API クラスは無効な状態になり、そのすべてのメソッドはエラーを返します。 次のコードは、リファレンス オブジェクトが互換性を持たない場合でも処理を継続します。

例: 3D オブジェクトのジオメトリにアクセスする(汎用)

この例は、「例: Softimage でオブジェクトを作成する」で定義されている GetSomeObjects()関数を使用してリファレンス配列を登録した後、その中をループさせます。そのときに、各アイテムの名前とジオメトリ上のポイントの数を出力します。 これは、「例: 3D オブジェクトのジオメトリにアクセスする(型指定)」の例に似ていますが、特定の Primitive クラスや Geometry クラスではなく、汎用の SIObject クラスを使用します。

	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() );
	}
注:

この例は、最初の例よりも効率的ではありません。 最初の例のようなオブジェクトの型を指定する方法を使用した処理は、この例のような不要な操作を実行しないため、はるかに効率的です。