ポート データのインデックス処理

 
 
 

カスタム ICENode の入力データのアクセスでは、CIndexSet および CIndexSet::Iterator クラスを推奨します。これらのクラスは、指定された評価スレッドのためにカスタム ICENode 入力ポートへアクセスする際に必要なインデックスをカプセル化します。 入力ポート データへのアクセスには、従来の配列インデックス(直接アクセス)を使用することもできますが、CIndexSet のように効率的ではありません。 これは特にマルチスレッド モードの場合にあてはまります。ICE はインデックスのサブセットを分割して個別のスレッドで実行するためです。 直接アクセスを代わりに使用した場合、すべてのスレッドは同じインデックスを使ってデータを繰り返し適用するため、パフォーマンスの低下を招きます。

マルチスレッド操作モードでは、CIndexSet オブジェクトは同じ評価コンテキストを共有する ICENode の入力ポートと出力ポートに関連付けられます。 シングルスレッド モードでは、入力ポートと出力ポートのコンテキストが異なる可能性があるため、CIndexSet オブジェクトはこれらのポートに関連付けられません。 したがって、シングルスレッド モードの場合は、CIndexSet オブジェクトを特定の入力ポートに対して作成する必要があります。

シングルスレッド モードで、特定のポートに対して CIndexSet を使用する:

CIndexSet indexSet( in_ctxt, ID_IN_PointPosition );
for ( CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next() )
{
	CVector3f& v3f = posArray[ it ];

	if ( v3fMin.GetX() >= v3f.GetX() && v3fMin.GetY() >= v3f.GetY() && v3fMin.GetZ() >= v3f.GetZ() )
	{
		v3fMin = v3f;
	}

	if ( v3fMax.GetX() <= v3f.GetX() && v3fMax.GetY() <= v3f.GetY() && v3fMax.GetZ() <= v3f.GetZ() )
	{
		v3fMax = v3f;
	}
}

マルチスレッド モードで CIndexSet を使用する:

CIndexSet indexSet( in_ctxt );
for(CIndexSet::Iterator it = indexSet.Begin(); it.HasNext(); it.Next())
{
	outData[it] = inputData[it].GetX();
}
注:

マルチフェーズ モード(siICENodeMultiEvaluationPhase)にカスタム ICENode をセットアップするときは、特定のポートに対して CIndexSet オブジェクトを作成する必要があります。これらのオブジェクトは常にシングルスレッドで実行されるため、この処理は中間フェーズでのみ必要です。

入力ポート データと異なり、CIndexSet によって外部公開されたインデックスは固定ではなく、サブセットから削除できます。 この処理は、「エレメント フィルタリング」と呼ばれます。 サブセットからインデックスをフィルタリングして除外すると、除外されたインデックスがグラフ内の他の ICENode で非表示になります。 エレメント フィルタリングは重要な概念であり、ICE グラフで発生する可能性のある条件ベースの最適化を有効にします。 サブセットからインデックスを削除しても入力データの内容は変わらず、常に同じサイズに設定されます。 CIndexSet::Iterator クラスは、サブセットのフィルタリングされたエレメントを自動的にスキップすることを目的としています。これこそ、CIndexSet::Iterator クラスでは入力データを常に繰り返し適用することが非常に重要である理由です。