Softimage SDK Programmer's Guide > Customizing Softimage using the SDK > Custom Filters >

# Writing 3D Object Filters

3D object filters are used to filter objects, such as polygon meshes, surfaces, curves, implicit primitives, control objects, models, nulls, cameras, and lights, that belong to the 3D object family.

When a user activates a 3D object selection filter, Softimage calls Match for each 3D object the user tries to select in a 3D view, the object view, or in the schematic. Softimage does not call Match for non-3D objects, such as Material and ParticleType objects in the schematic. Clicking on those types of objects while a 3D object filter is active triggers a Deselect All command.

Similarly, when a user applies a 3D object filter to an explorer view, Softimage calls Match for each 3D object currently listed in the view (unless Subset is defined, in which case Softimage calls Subset on the list of 3D objects).

## Match

When Softimage calls Match, it puts a 3D object in the Input attribute of the context. To get the input object, you use the Context.GetAttribute() method. The following example shows how to get the input object and check whether it has less than 50 points.

    function MySmallMesh_Match( oContext )
    {
    	// Get the object from the Input attribute of the context
    	var o3DObject = oContext.GetAttribute( "Input" );

    	// Check if the object matches the filter conditions
    	var bMatch = ( classname( o3DObject ) == "X3DObject" ) &&
    		( o3DObject.ActivePrimitive.Geometry != undefined ) &&
    		( o3DObject.ActivePrimitive.Geometry.Points.Count <= 50 );

    	// Return true to keep the object, false to filter the object out
    	return ( bMatch );
    }

After the filter gets the 3D object from the context, it checks that the object is an X3DObject. Other members of the 3D object family, such as nulls, cameras, and lights are filtered out, because they don't have points like polygon meshes, surfaces, and curves.

Then the filter makes sure the 3D object has geometry before trying to access Points.Count, because some 3D objects, such as implicit primitives, control objects, and geometry shader primitives, do not have a Geometry property.

## Subset

Softimage calls the Subset callback when a user applies the 3D object filter to an explorer view. If you don't provide a Subset callback, Softimage calls Match on each object and builds the subset collection itself.

When Softimage calls Subset, it puts an XSICollection in the Input attribute of the context. The collection contains 3D objects, such as X3DObject, Camera, Light, Null, Model, and ChainEffector. The job of the Subset callback is to build a new collection (the subset) that holds only the objects that match the filter conditions, and to put this new collection in the Output attribute of the context.

For example, the following Subset callback builds a collection of 3D objects that have less than 50 points. Note that you need to set the Output attribute even if the subset is empty. The return value tells Softimage whether or not the subset is empty.

    function MySmallMesh_Subset( oContext )
    {
    	// Get a new collection to hold the output subset
    	var cloOutput = new ActiveXObject( "XSI.Collection" );

    	// Get the collection of objects to filter
    	var cloInput = oContext.GetAttribute( "Input" );

    	// Enumerate the objects. If an object matches, add it to the output subset
    	for (var enumerator = new Enumerator(cloInput) ; !enumerator.atEnd(); enumerator.moveNext())
    	{
    		var o3DObject = enumerator.item();
    		if ( object_isamatch( o3DObject ) )
    		{
    			cloOutput.Add( o3DObject );
    		}

    	}

    	// Put the subset in the Output attribute
    	oContext.SetAttribute( "Output", cloOutput );

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

    // Helper function that checks if a 3D object matches the filter conditions
    function object_isamatch( o )
    {
    	return	(
    		classname( o ) == "X3DObject" &&
    		o.ActivePrimitive.Geometry != undefined &&
    		o.ActivePrimitive.Geometry.Points.Count <= 50
    		) ;
    }