大部分のカスタム オペレータの設計はシンプルで、ある一定の数の必須入力と 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; }
この基本コードを作成したら、いくつかの変更を加えるだけでダイナミック コードに変換することができます。
明示的に、可変数のポート オブジェクトを接続できるポート グループを作成します。 このためには、これらのより複雑なケースで明示的に呼び出す必要がある CustomOperator.AddPortGroup または CustomOperator::AddPortGroup メソッドを使用します。
CustomOperator.AddInputPort または CustomOperator::AddInputPort および CustomOperator.AddOutputPort または CustomOperator::AddOutputPort メソッドを使用するコードを書き換えて、より柔軟な CustomOperator.AddInputPortByClassID または CustomOperator::AddInputPortByClassID および CustomOperator.AddOutputPortByClassID または CustomOperator::AddOutputPortByClassID メソッドを使用するようにします。これによって、特定のオブジェクトが実際に存在するように要求することなく、ポートに接続する必要があるオブジェクトの種類を定義することができます。
Operator.Connect または Operator::Connect メソッドを Operator.ConnectToGroup または Operator::ConnectToGroup メソッドに置き換えます。両者の相違点は、Operator.Connect または Operator::Connect メソッドがすべての接続をまとめて行うのに対し、ConnectToGroup メソッドでは別々のタイミングでオブジェクトを個別に接続できることです。
上の太字で強調表示されたコードは、次のように書き直すこともできます。
// ... 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 ワークグループは、スタティック オペレータとダイナミック オペレータの相違点を示す多数のコンストレイントの例を用意しています。