Softimage でのオペレータの適用

 
 
 

オペレータの適用には、以下の 3 つのプロセスが含まれています。

構築しているオペレータの種類(スタティックとダイナミック)と接続プロセスに必要な制御の度合いによってカスタム オペレータの適用にはいくつかの方法あります。

ウィザードを使用してオペレータを作成している場合は、オペレータをインスタンス化し、ポート接続を確立するコードが生成されます(デフォルトで[オペレータを適用するコマンドの生成](Generate Command to Apply the Operator)オプションが選択されています)。

自動スタティック

これはある一定の数のポート接続を持つスタティック オペレータという最も単純なケースであり、接続されるオブジェクトがまだ作成されていない場合もあります。 オペレータのインスタンス化、接続するポートの指定、および接続の確立を行う [AddCustomOp] メソッドまたはコマンドを使用できます。

関連リンク

マニュアル スタティック

アプリケーション プロセスをコンポーネント部分に分割する場合は、各部分の実行に特定のオブジェクト モデルおよび C++ API 関数を使用することもできます。 この方法で、ウィザードはコードを生成します。

オペレータをインスタンス化する

CreateObject 関数を使用してオペレータをインスタンス化することができます。PluginRegistrar.RegisterOperator または PluginRegistrar::RegisterOperator でオペレータの登録に使用する PluginItem 名を指定します。CreateObject 関数は、ポート接続を定義し、オブジェクトをポートに接続するために必要な、インスタンス化されたオペレータへのポインタを返します。

// JScript
var op = XSIFactory.CreateObject( "MyCustomOperator" );

// C++
Factory factory = Application().GetFactory();
CustomOperator op( factory.CreateObject(L"MyCustomOperator") );

関連リンク

ポート接続を定義する

スタティック オペレータの場合、接続されるオブジェクトが存在することを要求するメソッドと関数のセットを使用して、ポート接続を定義できます。 入力ポート(AddInputPort)、出力ポート(AddOutputPort)、または同時に両方(たとえば、デフォーマ オペレータの場合、AddIOPort)を定義できます。

// JScript
op.AddInputPort( "sphere.polymsh.cls.Point" );

// C++ API
CRef obj;
obj.Set( "sphere.polymsh.cls.Point" );
op.AddIOPort( obj );

ポートへオブジェクトを接続する

Connect メソッドを使用して、ポート接続を終了させることができます。 スタティック オペレータの場合は、通常、接続指定(オブジェクトや接続セットなど)のために引数を渡す必要はありません。これは、ポート接続が定義されたときに、必要とされる明示的なオブジェクトが指定されたためです。

関連リンク

ダイナミック

ダイナミック オペレータの適用は手動によるスタティック オペレータの適用とよく似ていますが、ポート接続を宣言する前にポート グループも追加する必要があります。 さらに、接続オブジェクトがまだ存在していない場合もあるため、明示的なオブジェクトではなくクラス ID を指定してポートを追加する必要があります。 最後に、ConnectToGroup メソッドを使用して、グループにポート オブジェクトのインスタンスを追加します。これによって、真に動的な方法で接続することができます。

ポート グループを追加する

AddPortGroup メソッドを使用すると、このポート グループ内で接続先にできるオブジェクトの数を指定できます。 デフォルトでは 1 つの接続しか許可されていませんが、最低 2 個、最大でも 10 個の入力の平均を取るオペレータの場合のように、有効な範囲を指定することができます。

myOp.AddPortGroup( "Inputs", 2, 10, "MyPolygonFilter" );

このメソッドでは、グループに接続する任意の入力オブジェクトを検証するためのフィルタを指定することもできます。

関連リンク

可能なポート接続を宣言する

手動でスタティック ポート接続を定義するために使用されるメソッドは、既存のオブジェクトへの明示的なパスを必要とします。一方、ダイナミック接続は、より仮想的な方法で宣言する必要があります。 この理由から、CustomOperator または CustomOperator は、クラス ID でポートを追加できるメソッドにもなります。

myOp.AddInputPortByClassID( siPrimitiveID, "inputprim", 1 /* index of input port group */ );

グループへ動的に接続する

ConnectToGroup メソッドを使用すると、ポート グループの定義後、いつでもオブジェクトをポート グループに追加できます。 ただしこのメソッドは、単一のポートが含まれているポート グループでのみ使用でき、Object 引数で渡されたオブジェクトは、特定のノード(つまり、X3DObject または X3DObject ではなく KinematicStateKinematicStatePrimitive、または Primitive)である必要があります。

newOp.ConnectToGroup( 0, mySphere.Kinematics.Local );

関連リンク

カスタム オペレータ適用の例

以下の例では、カスタム オペレータの適用に関して、さまざまなアプローチを紹介します。

JScript の例: スタティック オペレータの適用(マニュアル)

この例は、SDK オペレータ ウィザードで生成されたコードの一部を抜き出したものです。 ポートは明示的に指定されるため、Operator.Connect または Operator::Connect メソッドに渡す必要のあるパラメータはありません(この例の自動バージョンについては、「C++ の例: スタティック オペレータの適用(自動)」を参照してください)。

// Instantiate the operator
var newOp = XSIFactory.CreateObject("MyOp");

// Specify the ports to hook up
newOp.AddOutputPort("sphere.polymsh");
newOp.AddInputPort("sphere.polymsh");

// Connect the operator
newOp.Connect();

C++ の例: スタティック オペレータの適用(自動)

このコード断片は、「JScript の例: スタティック オペレータの適用(マニュアル)」のウィザードで生成されたコードに似ていますが、3 つのステップ(インスタンス化、ポートの宣言、接続)を 1 つにまとめる AddCustomOp 関数を使用しています。 これと JScript バージョンは、スタティック オペレータの例です。このため、ポート接続が存在している必要があります。

// Output of the operator will be this mesh
CRef obj;
obj.Set(L"sphere.polymsh");
Primitive prim(obj);

// AddCustomOp takes an array of inputs
CRefArray inputs(3);

// Get the objects to which the operator will be connected
inputs[0].Set(L"grid.polymsh");
inputs[1].Set(L"null.kine.global");
inputs[2].Set(L"null2.kine.global");

// Apply the custom operator
prim.AddCustomOp("MyOp", inputs);

AddCustomOp コマンドを使用する JScript の同等のコードは、次のように 1 行のみです。

AddCustomOp("MyOp", "sphere.polymsh", 
"grid.polymsh,null.kine.global,null2.kine.global");

JScript の例: ポート ターゲットが存在する前のオペレータの適用

この例では、AddIOPortByClassID メソッドによって、一致するオブジェクトが実際にシーンに存在する前にオペレータ ポートが宣言されています。このメソッドは、オブジェクトそのものではなく、ポートに接続することが予期されるオブジェクトの種類を宣言するだけです。

// Instantiate the operator
var newOp = XSIFactory.CreateObject( "MyOp" );

// Specify the ports to hook up, this time using AddXXXPortByClassID which
// allows you to add the port without specifying an existing object to connect
newOp.AddIOPortByClassID( siKinematicStateID );

// ...

// The operator connections are set up before the target object exists
var sph = Application.ActiveSceneRoot.AddGeometry( "Sphere", "MeshSurface" );
newOp.ConnectToGroup( 0, sph.Kinematics.Local );

C++ の例: ダイナミック オペレータの適用

この例は、2~10 個の接続を受け入れるポート グループを追加し、クラス ID のみを使用してポートを定義することによって、可変数のオブジェクトを持つオペレータを適用する方法を示したものです。

// Instantiate the operator
CustomOperator newOp = Application().GetFactory().CreateObject( L"MyOp" );

// Define an input port group that can accept at least 2 and up to 10 connections
newOp.AddPortGroup( L"Output" );
newOp.AddPortGroup( L"Inputs", 2, 10 );

// Specify the ports to hook up, using AddXXXPortByClassID which allows you to
// add the port without specifying an existing object to connect
newOp.AddOutputPortByClassID( siClusterPropertyID, L"", 0 /* output port group */ );
newOp.AddInputPortByClassID( siClusterPropertyID, L"", 1 /* input port group */ );

// ...
// When it's time to connect a new port instance to the operator
CRef wp; CRef out_instance;
wp.Set( L"sphere.polymsh.cls.Point.Weight_Map" );
newOp.ConnectToGroup( 1, wp, out_instance );

// etc.