オペレータの適用には、以下の 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 ではなく KinematicState、KinematicState、Primitive、または Primitive)である必要があります。
newOp.ConnectToGroup( 0, mySphere.Kinematics.Local );
以下の例では、カスタム オペレータの適用に関して、さまざまなアプローチを紹介します。
この例は、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();
このコード断片は、「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");
この例では、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 );
この例は、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.