SubComponent フィルタの記述

 
 
 

サブコンポーネント(エッジ、ポイント、またはポリゴン)の選択をフィルタするには、Softimage では Match コールバックよりも Subset コールバックが優先されます。 つまり、ユーザが一部のサブコンポーネントを選択したときに呼び出されるのは、Match コールバックでなく Subset コールバックです。 サブコンポーネント フィルタに対しては、常に Subset コールバックを指定する必要があります。

Subset

Softimage で Subset が呼び出されると、コールバック コンテキストの Input 属性に XSICollection が格納されます。 このコレクションは、選択されたサブコンポーネントを持つ各 3D オブジェクト用の CollectionItem を 1 つずつ含んでいます。 コールバック関数では、選択されたサブコンポーネントが CollectionItem.SubComponent.ComponentCollection プロパティから取得されます。

サブコンポーネント フィルタ用サブセット コールバックの典型的な構造体を、次の例に示します。 最初に、コールバックによって新規の XSICollection が作成されます。この XSICollection は、コールバックの出力を保持する目的に使用されます。 次に、Subset によって各 3D オブジェクトに適合するポリゴンが検索され、それらのポリゴンを使用して新規の SubComponent オブジェクトが作成されます。 新規の SubComponent オブジェクトが出力コレクションに追加され、コールバック コンテキストの Output 属性にコレクションが格納されます。

function MyPolygonFilter_Subset( oContext )
{
	var oFilter = oContext.Source;
	logmessage( oFilter.Name + "_Subset");

	// Create a new XSICollection to hold the output
	var cloSubset = new ActiveXObject( "XSI.Collection" );

	// Get the XSI.Collection from the context
	// The collection contains one CollectionItem for each object with selected polygons
	var cloObjects = oContext.GetAttribute( "Input" );

	for (var objEnumerator = new Enumerator(cloObjects) ; !objEnumerator.atEnd(); objEnumerator.moveNext())
	{
		// Get the CollectionItem
		var oItem = objEnumerator.item();

		// Get the SubComponent object
		var oPolySubComponent = oItem.SubComponent;

		if ( !( (classname(oPolySubComponent) == "SubComponent") && ( oPolySubComponent.type == "polySubComponent" ) ) )
			continue;

		// This array will hold the indices of the polygons that match the filter conditions
		var aIndices = new Array();

		// Enumerate the selected polygons; if a polygon matches, put its index in the array
		for (var polyEnumerator = new Enumerator(oPolySubComponent.ComponentCollection) ; !polyEnumerator.atEnd(); polyEnumerator.moveNext())
		{
			var oPoly = polyEnumerator.item();
			if ( polygon_isamatch( oPoly ) )
			{
				aIndices.push( oPoly.index );
			}
		}

		// Create a SubComponent from the subset of polygons that match, and add the SubComponent to the output
		if ( aIndices.length > 0 )
		{
			var oSubComponent = oPolySubComponent.Parent3DObject.ActivePrimitive.Geometry.CreateSubComponent(siPolygonCluster, aIndices );
			cloSubset.Add( oSubComponent );
		}
	}

	// You always set the Output attribute, even if the subset is empty
	oContext.SetAttribute( "Output", cloSubset );

	// Return True if the subset is non-empty
	return (cloSubset.Count > 0);
}


// Select only polygons with more than 3 points
function polygon_isamatch( oPoly )
{
	return ( oPoly.NbPoints != 3 )
}

Subset コールバックを実装するには、それ以外に、Softimage が渡した SubComponent オブジェクトを直接処理する方法もあります。 この方法では、SubComponent.RemoveElement を使用して、適合しないポリゴンを除去し、変更された SubComponent を出力コレクションに格納します。

function MyPolygonFilter_Subset( oContext )
{
	var cloSubset = new ActiveXObject( "XSI.Collection" );

	var cloObjects = oContext.GetAttribute( "Input" );

	for (var objEnumerator = new Enumerator(cloObjects) ; !objEnumerator.atEnd(); objEnumerator.moveNext())
	{
		var oItem = objEnumerator.item();

		var oPolySubComponent = oItem.SubComponent;

		if ( !( (classname(oPolySubComponent) == "SubComponent") && ( oPolySubComponent.type == "polySubComponent" ) ) )
			continue;

		// Get a copy of the PolygonFaceCollection; 
		// We'll enumerate cloTmpCopy, and modify oPolySubComponent.ComponentCollection 
		var cloTmpCopy = oPolySubComponent.ComponentCollection;

		// Enumerate the selected polygons; if a polygon doesn't match, remove it from oPolySubComponent
		for (var polyEnumerator = new Enumerator(cloTmpCopy) ; !polyEnumerator.atEnd(); polyEnumerator.moveNext())
		{
			var oPoly = polyEnumerator.item();
			if ( !polygon_isamatch( oPoly ) )
			{
				oPolySubComponent.RemoveElement( oPoly.index );
			}
		}

		// Add the modified SubComponent the output collection
		if ( aIndices.length > 0 )
		{
			cloSubset.Add( oPolySubComponent );
		}
	}

	oContext.SetAttribute( "Output", cloSubset );

	return (cloSubset.Count > 0);
}

Match

サブコンポーネント フィルタ用の最も重要なコールバックは、Subset です。 フィルタにサブセット コールバックが存在しない限り、Softimage では Match が呼び出されません。 ただし、Match は必要であるため、実装は必須指定です。 一般的には、フィルタ条件を適合しないサブコンポーネントが見つかるとすぐに、Match が false を返します。

サブコンポーネント フィルタ用に Match が呼び出されると、コールバック コンテキストに SubComponent オブジェクトが格納されます。 Match コールバック用の典型的な構造体を、次の例に示します。

function MyPolygonFilter_Match( oContext )
{
	// Get the SubComponent object from the context
	var oPolySubComponent = oContext.GetAttribute( "Input" );

	// Return false if we don't have a SubComponent, or we don't have polygons
	if ( !( (classname(oPolySubComponent) == "SubComponent") && ( oPolySubComponent.type == "polySubComponent" ) ) )
	{
		return false;
	}

	// Enumerate the selected polygons; Return false as soon as we find a polygon that doesn't match
	for (var polyEnumerator = new Enumerator(oPolySubComponent.ComponentCollection) ; !polyEnumerator.atEnd(); polyEnumerator.moveNext())
	{
		var oPoly = polyEnumerator.item();
		if ( !polygon_isamatch( oPoly ) )
		{
			return false;
		}
	}

	// If we make it here, all the polygons match
	return true;
}