ローカルリファレンスフレームの取得

 
 
 

現時点で、SDK にはローカル フレーム リファレンスの情報にアクセスする正式な方法がありません。 ただし、ポリゴン メッシュの頂点用にローカル フレームの便利な式が用意されているので、これを使用してポリゴン メッシュの頂点をユーザ自身で評価することは可能です。また、SDK オブジェクト モデルのいずれかの廃止されたインターフェイスを使った解決策を使用することもできます。

ヒント:

ポリゴン メッシュ頂点に便利な式だけが用意されているのは、この式がポリゴン メッシュのローカルに相対的なシェイプのディスプレイスメントを算出するためにしばしば使用されるからです。 その他のケースでは、次の解決策を使用してください。

非推奨の Geometry0DGeometry1D、および Geometry2D インタフェースとは、それぞれ PointEdge、および Facet インタフェースのオリジナル バージョンを意味します(つまり、オリジナル バージョンの v1.0 で実装されながらも、v1.5 で廃止が決定したものです)。これらのインターフェイスは、サブコンポーネントの指定したインデックスでローカルリファレンスの X、Y、Z 軸を戻す LocalReferenceFrame メソッドをそれぞれに実装します。

これらの廃止されたインタフェースは、CollectionItem.Obj プロパティを介して使用できる Geometry_V1 インタフェース(同じく非推奨)を使って取得できます。

それでは問題点を挙げてみます。LocalReferenceFrame メソッドは出力オブジェクトを使用するので、JScript と C++ API では使用できません(Python はメソッドの出力引数を簡単に処理できます。詳細は「戻り値および出力引数を使って操作する」を参照してください)。解決策として、これらの値の配列を戻すためにカスタム コマンド(VBScript)を実装できます。 このコマンドを使用すると、「JScript の例: VBS ラッパーを使用してローカル リファレンス フレームを取得する」および「C++ の例: VBS ラッパーを使用してローカル リファレンス フレームを取得する」に示すように、「VBScript の例: JScript 準拠バージョンの LocalReferenceFrame メソッドを実装する」または「VBScript の例: C++ API 準拠バージョンの LocalReferenceFrame メソッドを実装する」の例のように実装されたカスタム コマンドを使用して、JScript または C++ API でローカル リファレンス フレームを読み込むことができます。

VBScript の例: JScript 準拠バージョンの LocalReferenceFrame メソッドを実装する

このバージョンのカスタム コマンドは、LocalReferenceFrame メソッドの戻り値とまったく同じ出力引数を含む配列を戻します(つまり、SIVector3、Boolean、SIVector3、Boolean、SIVector3、Boolean というエレメントを含んだ SafeArray です)。

重要:

C++ API では SIVector3 インタフェースを読み取ることができないため、そのインタフェースを CVector3 クラスに変換することができません。そのため、このバージョンは C++ API では機能しません。C++ API 準拠バージョンについては、「VBScript の例: C++ API 準拠バージョンの LocalReferenceFrame メソッドを実装する」を参照してください。

'
' GetLocalReferenceFramePlugin
'

' Registration
function XSILoadPlugin( in_reg )
	in_reg.Author = "yourname"
	in_reg.Name = "GetLocalReferenceFramePlugin"
	in_reg.Email = "yourname@yourcompany.com"
	in_reg.URL = "www.yourcompany.com"
	in_reg.Major = 1
	in_reg.Minor = 0

	in_reg.RegisterCommand "GetLocalReferenceFrame","GetLocalReferenceFrame"

	XSILoadPlugin = true
end function

' De-registration
function XSIUnloadPlugin( in_reg )
	strPluginName = in_reg.Name
	Application.LogMessage strPluginName & " has been unloaded."
	XSIUnloadPlugin = true
end function

' Set up command arguments, return value and flags
function GetLocalReferenceFrame_Init( ctxt )
	dim oCmd
	set oCmd = ctxt.Source
	oCmd.Description = "Get Local Reference Frame"
	oCmd.SetFlag siNoLogging, true
	oCmd.ReturnValue = true

	dim oArgs
	set oArgs = oCmd.Arguments
	oArgs.AddWithHandler "InputObjs", siArgHandlerCollection
	oArgs.Add "Index",		siArgumentInput,	,		siInt4
	oArgs.Add "Dimension",	siArgumentInput,	"0",	siInt2
	
	GetLocalReferenceFrame_Init = true
end function

' Main implementation
function GetLocalReferenceFrame_Execute( InputObjs, Index, Dimension )
	dim oXDGeometry, aInfoCollection
	dim oXAxis, oYAxis, oZAxis 
	dim bXAxisValid, bYAxisValid, bZAxisValid
	
	set oXAxis = XSIMath.CreateVector3()
	set oYAxis = XSIMath.CreateVector3()
	set oZAxis = XSIMath.CreateVector3()
	
	' Make sure input object is valid
	if TypeName(InputObjs(0)) <> "X3DObject" then
		set GetLocalReferenceFrame_Execute = Nothing
		Application.LogMessage( "Input object is not a valid object: " & InputObj.Type )
		exit function
	end if
	
	' Decide which info to get
	if Dimension = 0 then
		set oXDGeometry = InputObjs(0).Obj.Geometry0D
	elseif Dimension = 1 then
		set oXDGeometry = InputObjs(0).Obj.Geometry1D
	else
		set oXDGeometry = InputObjs(0).Obj.Geometry2D
	end if
	
	' Call the correct method and then use the output arguments to populate the array to return
	oXDGeometry.LocalReferenceFrame i, oXAxis, bXAxisValid, oYAxis, bYAxisValid, oZAxis, bZAxisValid
	aInfoCollection = Array( oXAxis, bXAxisValid, oYAxis, bYAxisValid, oZAxis, bZAxisValid )
	 
	' The array returned will be a 1-dimensional SAFEARRAY
	GetLocalReferenceFrame_Execute = aInfoCollection 
end function

JScript の例: VBS ラッパーを使用してローカル リファレンス フレームを取得する

この例では、JScript を使って立方体のローカル リファレンス フレーム情報を取得する方法を示します。 JScript は Geometry0D、Geometry1D、および Geometry2D という廃止されたオブジェクトの LocalReferenceFrame メソッドが戻す出力引数を処理できないので、JScript で使用できるように情報を抽出し、再フォーマットするために、VBScript でカスタム コマンドを記述する必要があります。 この例では、予想される結果は 3 組の SIVector3 と Boolean エレメントを含んだ 1 次元 SafeArray になります(実装例については、「VBScript の例: JScript 準拠バージョンの LocalReferenceFrame メソッドを実装する」を参照)。

// Create a cube
var objItem = CreatePrim( "Cube", "MeshSurface" );

// Get number of vertices in the cube
var nbrPoints = objItem.ActivePrimitive.Geometry.Points.Count;

// Set up some storage for the local reference frame info
var vc3XAxis = XSIMath.CreateVector3(); var booXAxisValid;
var vc3YAxis = XSIMath.CreateVector3(); var booYAxisValid;
var vc3ZAxis = XSIMath.CreateVector3(); var booZAxisValid;

// Get the local reference frame for each point
for ( var i=0; i<nbrPoints; i++ ) {
	var aResults = GetLocalReferenceFrame( objItem, i, 0 ).toArray();
	vc3XAxis = aResults[0];
	booXAxisValid = aResults[1];
	vc3YAxis = aResults[2];
	booYAxisValid = aResults[3];
	vc3ZAxis = aResults[4];
	booZAxisValid = aResults[5];

	if ( booXAxisValid ) {
		Application.LogMessage ( "Component [" + i + "] X axis : " + vc3XAxis.x + " | " + vc3XAxis.y + " | " + vc3XAxis.z );
	} else {
		Application.LogMessage ( "Component [" + i + "] INVALID X axis" );
	}

	if ( booYAxisValid ) {
		Application.LogMessage ( "Component [" + i + "] Y axis : " + vc3YAxis.x + " | " + vc3YAxis.y + " | " + vc3YAxis.z );
	} else {
		Application.LogMessage ( "Component [" + i + "] INVALID Y axis" );
	}

	if ( booZAxisValid ) {
		Application.LogMessage ( "Component [" + i + "] Z axis : " + vc3ZAxis.x + " | " + vc3ZAxis.y + " | " + vc3ZAxis.z );
	} else {
		Application.LogMessage ( "Component [" + i + "] INVALID Z axis" );
	}
}

//INFO : Component [0] X axis : 0.408248290463863 | -0.816496580927726 | 0.408248290463863
//INFO : Component [0] Y axis : -0.577350269189626 | -0.577350269189626 | -0.577350269189626
//INFO : Component [0] Z axis : 0.707106781186547 | 0 | -0.707106781186547
//INFO : Component [1] X axis : -0.408248290463863 | 0.408248290463863 | -0.816496580927726
//INFO : Component [1] Y axis : 0.577350269189626 | -0.577350269189626 | -0.577350269189626
//INFO : Component [1] Z axis : -0.707106781186547 | -0.707106781186547 | 0
//INFO : Component [2] X axis : -0.816496580927726 | -0.408248290463863 | 0.408248290463863
//INFO : Component [2] Y axis : -0.577350269189626 | 0.577350269189626 | -0.577350269189626
//INFO : Component [2] Z axis : 0 | -0.707106781186547 | -0.707106781186547
//INFO : Component [3] X axis : -0.408248290463863 | -0.408248290463863 | -0.816496580927726
//INFO : Component [3] Y axis : 0.577350269189626 | 0.577350269189626 | -0.577350269189626
//INFO : Component [3] Z axis : 0.707106781186547 | -0.707106781186547 | 0
//INFO : Component [4] X axis : 0.408248290463863 | -0.816496580927726 | -0.408248290463863
//INFO : Component [4] Y axis : -0.577350269189626 | -0.577350269189626 | 0.577350269189626
//INFO : Component [4] Z axis : -0.707106781186547 | 0 | -0.707106781186547
//INFO : Component [5] X axis : 0.816496580927726 | 0.408248290463863 | -0.408248290463863
//INFO : Component [5] Y axis : 0.577350269189626 | -0.577350269189626 | 0.577350269189626
//INFO : Component [5] Z axis : 0 | -0.707106781186547 | -0.707106781186547
//INFO : Component [6] X axis : -0.816496580927726 | -0.408248290463863 | -0.408248290463863
//INFO : Component [6] Y axis : -0.577350269189626 | 0.577350269189626 | 0.577350269189626
//INFO : Component [6] Z axis : 0 | 0.707106781186547 | -0.707106781186547
//INFO : Component [7] X axis : -0.408248290463863 | 0.816496580927726 | -0.408248290463863
//INFO : Component [7] Y axis : 0.577350269189626 | 0.577350269189626 | 0.577350269189626
//INFO : Component [7] Z axis : 0.707106781186547 | 0 | -0.707106781186547

VBScript の例: C++ API 準拠バージョンの LocalReferenceFrame メソッドを実装する

C++ API では SIVector3 インタフェースを読み取ることができず、CVector3 クラスに変換することができないため、このバージョンのカスタム コマンドは、フラットにした(各 SIVector3 を規則的に x、y、z 値に展開した)出力引数から成る配列を戻します。

注:

このカスタム コマンドのその他の状況(宣言、初期化)はすべて同じままなので、ここでは実装のみを紹介します。 このコマンドのその他のコールバックを確認するには、「VBScript の例: JScript 準拠バージョンの LocalReferenceFrame メソッドを実装する」を参照してください。

' Main implementation
function GetLocalReferenceFrame_Execute( InputObjs, Index, Dimension )
	dim oXDGeometry, aInfoCollection
	dim oXAxis, oYAxis, oZAxis 
	dim bXAxisValid, bYAxisValid, bZAxisValid
	
	set oXAxis = XSIMath.CreateVector3()
	set oYAxis = XSIMath.CreateVector3()
	set oZAxis = XSIMath.CreateVector3()
	
	' Make sure input object is valid
	if TypeName(InputObjs(0)) <> "X3DObject" then
		set GetLocalReferenceFrame_Execute = Nothing
		Application.LogMessage( "Input object is not a valid object: " & InputObj.Type )
		exit function
	end if
	
	' Decide which info to get
	if Dimension = 0 then
		set oXDGeometry = InputObjs(0).Obj.Geometry0D
	elseif Dimension = 1 then
		set oXDGeometry = InputObjs(0).Obj.Geometry1D
	else
		set oXDGeometry = InputObjs(0).Obj.Geometry2D
	end if
	
	' Call the correct method and then use the output arguments to populate the array to return
	' In this case we want to return the actual values of the SIVector3, not the SIVector3 
	' itself. This is because the C++ API cannot handle the SIVector3 interface so we need to pass
	' the actual x,y,z values.
	oXDGeometry.LocalReferenceFrame i, oXAxis, bXAxisValid, oYAxis, bYAxisValid, oZAxis, bZAxisValid
	aInfoCollection = Array(	oXAxis.X, oXAxis.Y, oXAxis.Z, bXAxisValid, _
								oYAxis.X, oYAxis.Y, oYAxis.Z, bYAxisValid, _
								oZAxis.X, oZAxis.Y, oZAxis.Z, bZAxisValid )
	 
	' The array returned will be a 1-dimensional SAFEARRAY
	GetLocalReferenceFrame_Execute = aInfoCollection 
end function

C++ の例: VBS ラッパーを使用してローカル リファレンス フレームを取得する

この例では、C++ API を使って立方体のローカル リファレンス フレーム情報を取得する方法を示します。 C++ API では Geometry0D、Geometry1D、および Geometry2D という廃止されたオブジェクトの LocalReferenceFrame メソッドが戻す出力引数を処理できないので、C++ API で使用できるように情報を抽出して再フォーマットするように、VBScript でカスタム コマンドを記述する必要があります。 この例の場合、予想結果は 12 個のエレメントを持つフラットな配列になります(double、double、double、bool という 4 つのエレメントを 1 組とするものを合計 3 つ並べた配列です)。 各組は x.y.z 値と各軸の有効性を示すインジケータを表します(実装例については、「VBScript の例: C++ API 準拠バージョンの LocalReferenceFrame メソッドを実装する」を参照)。

	Application app;
	Model root = app.GetActiveSceneRoot();

	// Create a cube
	X3DObject objItem; root.AddGeometry( L"Cube", L"MeshSurface", L"MyCube", objItem );

	// Get number of vertices in the cube
	CPointRefArray refPoints = objItem.GetActivePrimitive().GetGeometry().GetPoints();
	LONG nbrPoints = refPoints.GetCount();

	// Set up the arguments for the custom command
	CValueArray ccArgs(3); CValue ccOut;
	ccArgs[0] = objItem;
	ccArgs[2] = CValue(0.0);

	// Get the local reference frame for each point
	for ( LONG i=0; i<nbrPoints; ++i ) 
	{
		// Run the command (you only need to change the index number for this example)
		ccArgs[1] = i;
		app.ExecuteCommand( L"GetLocalReferenceFrame", ccArgs, ccOut );
		
		// Grab the output arguments from the returned array
		if ( ccOut.m_t == CValue::siArray ) 
		{
			MATH::CVector3 vc3XAxis; MATH::CVector3 vc3YAxis; MATH::CVector3 vc3ZAxis;
			bool booXAxisValid; bool booYAxisValid; bool booZAxisValid;

			CValueArray aResults(ccOut);
			vc3XAxis.Set( aResults[0], aResults[1], aResults[2]  ); // XAxis 
			booXAxisValid = aResults[3];								// XAxisValid 
			vc3YAxis.Set( aResults[4], aResults[5], aResults[6]  ); // YAxis 
			booYAxisValid = aResults[7];								// YAxisValid 
			vc3ZAxis.Set( aResults[8], aResults[9], aResults[10]  ); // ZAxis 
			booZAxisValid = aResults[11];								// ZAxisValid 

			// Log the information in Softimage
			if ( booXAxisValid ) 
			{
				app.LogMessage ( L"Component [" + CString(i) + L"] X axis : " + CString(vc3XAxis.GetX()) + L" | " + CString(vc3XAxis.GetY()) + L" | " + CString(vc3XAxis.GetZ()) );
			} else {
				app.LogMessage ( L"Component [" + CString(i) + L"] INVALID X axis" );
			}

			if ( booYAxisValid ) 
			{
				app.LogMessage ( L"Component [" + CString(i) + L"] Y axis : " + CString(vc3YAxis.GetX()) + L" | " + CString(vc3YAxis.GetY()) + L" | " + CString(vc3YAxis.GetZ()) );
			} else {
				app.LogMessage ( L"Component [" + CString(i) + L"] INVALID Y axis" );
			}

			if ( booZAxisValid ) 
			{
				app.LogMessage ( L"Component [" + CString(i) + L"] Z axis : " + CString(vc3ZAxis.GetX()) + L" | " + CString(vc3ZAxis.GetY()) + L" | " + CString(vc3ZAxis.GetZ()) );
			} else {
				app.LogMessage ( L"Component [" + CString(i) + L"] INVALID Z axis" );
			}
		}

ローカル フレームの便利な式

ポリゴン メッシュ頂点のローカル リファレンス フレームは、次のようにオブジェクト空間で計算されます。

  • Y = 頂点の法線 これは Geometry0D.Normal または Point.Normal(C++ API の場合は Point::GetNormal)と同じです。頂点の法線をユーザ自身で算出するには、頂点を基点とする隣どうしの正規化エッジ ベクトルの外積をそれぞれすべて算出し、これらの外積の和を求め、その和を正規化することが必要です。

  • X = 最初のエッジ ベクトルの正規化投影(現在の頂点から始まり、法線面上に投影)。

  • Z = X と Y の外積