スタティック オペレータとダイナミック オペレータ

 
 
 

大部分のカスタム オペレータの設計はシンプルで、ある一定の数の必須入力と 1 つの出力から構成されています。 このオペレータは「スタティック」と呼ばれます。これは、いったんオペレータが接続されると、その接続が変化しないためです。 スタティック オペレータの作成および接続方法として、2 つの手法(「自動」と「マニュアル」)がサポートされています。 スタティック オペレータに関してはポート グループを考慮する必要はまったくなく、ポートに関する最低限の知識があれば十分です。

2 つ目のタイプのオペレータはダイナミック オペレータです。 これはさらに進化したモデルで、オペレータが接続された後で、その接続が変化することが想定されています。 たとえば、オブジェクトとのオプションの接続や、無制限の数のオブジェクトへの接続がサポートされます。 よくある例はブレンド オペレータです。入力をいくつでも受けることができ、そのデータを 1 つの出力にブレンドするオペレータです。 API はこのタイプのオペレータをサポートしており、これらのオペレータを作成するには推奨される手法があります。

ポート グループを使用する

オペレータには多くのポートがある場合があり、これらのポートは、X3DObject または X3DObject の下にネストされた特定のデータに接続されています。X3DObject を取り、接続先の正確なノードを解決するネイティブの Softimage オペレータと異なり、カスタム オペレータを作成する場合は、プリミティブ、グローバル、またはローカル キネマティクス状態、特定のパラメータ、クラスタ プロパティなどの特定のノードに接続する必要があります。

一般的なガイドラインとして、カスタム オペレータの接続に問題がある場合は、ポートをさらに多くのグループに分割するとよいでしょう。いくつのグループに分けても、サイズに関する問題は発生しません。 実際、複数のポートをまとめてグループ化する唯一の理由は、複数インスタンス機能(または、ダイナミック接続)に基づいたものです。

ダイナミック接続を指定する

ポート グループは、同じタイプの不定数のオブジェクトに接続するオペレータを作成する場合に必要です。 たとえば、メッシュを好きなだけ設定でき、それらをブレンドして新しいメッシュを形成することができるオブジェクトが必要だとします。 最大不定数のオブジェクトに基づいて大量のポートを作成するよりも、グループの複数のインスタンスを使用する方が便利です。

グループ定義には、サポートされるインスタンスの数が含まれます。たとえば、オプションのグループの場合は 0 ~ 1 個、必須の単一インスタンスグループの場合は 1 ~ 1 個、最大 1000 個の接続オブジェクトをサポートする必須グループの場合は 1 ~ 1000 個などです。 1 つのグループで複数のインスタンスがアクティブになっている場合、各グループ インスタンスにグループ内の各ポートの個別のインスタンスがあるため、オペレータはすべてのオブジェクトから読み取りを行うことができます。

重要:

オペレータが接続されるまで、ポートおよびポート グループを動的に追加または削除することができます。 オペレータが接続されると、定義はフリーズされます。

ウィザードを使用してダイナミック オペレータを作成する

ウィザードではスタティック コードしか生成できませんが、いくつかの簡単な変更を加えるだけでダイナミックにレンダリング可能な、基本オペレータ コードを生成することもできます。 たとえば、可変数の入力を持つジェネレータ オペレータを作成する場合、ウィザードを使用して、次のような 2 つのオブジェクトを持つ 1 つのスタティック オペレータ用のコードを生成することができます。

// This is the implementation for the command to apply the operator, which is
// is where you set up the ports and hook up the operator for static operators
function ApplyMyOp_Execute(  )
{
	Application.LogMessage("ApplyMyOp_Execute called");
	// TODO: This generated code works by hardcoding the exact names of the
	// input and output objects.
	// If you want to operator to be applied to objects with different names
	// you way want to generalise this code to determine the objects
	// based on the Selection or the arguments to this command
	// 
	// Note: The AddCustomOp command is an alternative way to build the operator
	var newOp = XSIFactory.CreateObject("MyOp");
	newOp.AddOutputPort("grid2.polymsh");
	newOp.AddInputPort("grid.polymsh");
	newOp.AddInputPort("grid1.polymsh");
	newOp.Connect();
	return newOp;
}

この基本コードを作成したら、いくつかの変更を加えるだけでダイナミック コードに変換することができます。

上の太字で強調表示されたコードは、次のように書き直すこともできます。

// ...
	var ingrp = newOp.AddPortGroup("MyDynPortGroup", 1, 1000);
	newOp.AddInputPortByClassID(siPrimitiveID, "inprim", ingrp.Index);
	// ...
	// Once the objects exist in the scene they can be hooked up
	newOp.ConnectToGroup(ingrp.Index, grid0.ActivePrimitive);
	newOp.ConnectToGroup(ingrp.Index, grid1.ActivePrimitive);
	// etc.
ヒント:

SDK ワークグループは、スタティック オペレータとダイナミック オペレータの相違点を示す多数のコンストレイントの例を用意しています。

  • CenterOp_Basic: ある一定の数の必須入力と 1 つの出力を使用します。

  • CenterOp_Simple: Basic と似ていますが、可変数の入力を使用します。

  • CenterOp_Dynamic: オペレータの作成後でも追加オブジェクトを接続する方法を示します。 それには複数インスタンスで単一ポートを使用します。