サブコンポーネント(エッジ、ポイント、またはポリゴン)の選択をフィルタするには、Softimage では Match コールバックよりも Subset コールバックが優先されます。 つまり、ユーザが一部のサブコンポーネントを選択したときに呼び出されるのは、Match コールバックでなく 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); }
サブコンポーネント フィルタ用の最も重要なコールバックは、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; }