Beware of ICE optimizations


It seemed like such a nice, simple way to filter polygons:

  • Use ICE to check the polygon area and then set a boolean attribute.
  • Write a custom subcomponent filter to filter based on that ICE attribute.

With ICE, it’s pretty easy to check if the PolygonArea is within a certain range:

But, beware of ICE optimizations!

Because that ICE attribute isn’t used anywhere else in the scene, ICE doesn’t evaluate that tree, so my boolean attribute is never defined, and my custom filter therefore fails. I have to do something like Show Values to force evaluation:

Note: In Show Values, I used Show Values for Tagged Components Only to cut down the visual clutter.

FWIW, here’s a Python example of a custom subcomponent filter:

# psCustomFilter Plug-in
# Initial code generated by Softimage SDK Wizard
# Executed Wed Nov 23 11:31:56 EST 2011 by blairs
# 
# Tip: To add a command to this plug-in, right-click in the 
# script editor and choose Tools > Add Command.
import win32com.client
from win32com.client import constants

from siutils import si		# Application
from siutils import sidesk	# Desktop
from siutils import sidict	# Dictionary
from siutils import sifact	# XSIFactory
from siutils import simath	# XSIMath
from siutils import siproj	# ActiveProject2
from siutils import sisel	# Selection
from siutils import siuitk	# XSIUIToolkit
from siutils import siut	# XSIUtils
from siutils import log		# LogMessage
from siutils import disp	# win32com.client.Dispatch
from siutils import C		# win32com.client.constants


null = None
false = 0
true = 1

def XSILoadPlugin( in_reg ):
	in_reg.Author = "blairs"
	in_reg.Name = "psCustomFilter Plug-in"
	in_reg.Major = 1
	in_reg.Minor = 0

	in_reg.RegisterFilter("psCustomFilter",constants.siFilterSubComponentPolygon)
	#RegistrationInsertionPoint - do not remove this line

	return true

def XSIUnloadPlugin( in_reg ):
	strPluginName = in_reg.Name
	Application.LogMessage(str(strPluginName) + str(" has been unloaded."),constants.siVerbose)
	return true

# Match callback for the psCustomFilter custom filter.
def psCustomFilter_Match( in_ctxt ):
	Application.LogMessage("psCustomFilter_Match called",constants.siVerbose)

# 	Return value indicates if the input object matches the filter criterias.
	return true

# Subset callback for the psCustomFilter custom filter.
def psCustomFilter_Subset( in_ctxt ):
	log("psCustomFilter_Subset called",constants.siVerbose)

	out_coll = disp( "XSI.Collection" )
	
	in_coll = in_ctxt.GetAttribute( "Input" )
	for item in in_coll:
		log( item )
		polys = []
		for p in item.SubComponent.ComponentCollection:
			log( p.Index )

			attr = p.Parent.ICEAttributes("psCustomPolyFilter")
			if not attr.IsDefined:
				log( "Cannot apply filter. psCustomPolyFilter attribute is not defined" )
			if attr.IsDefined and attr.DataArray[ p.Index ] == -1:
				#log( "%d : %s" % ( p.Index, attr.DataArray[ p.Index ] ) )
				polys.append( p.Index )

		if len(polys) > 0:
			out_coll.Add( item.SubComponent.Parent3DObject.ActivePrimitive.Geometry.CreateSubComponent(C.siPolygonCluster, polys ) )


	in_ctxt.SetAttribute( "Output", out_coll )

# 	Return value indicates if a subset of the input objects matches the filter criterias.
	return true

4 thoughts on “Beware of ICE optimizations

  1. Maybe someone “in the know” could one of these days write an “exhaustive, definitive guide to ICE optimization (& the construction stack)”, not just with the does and don’ts, but also with more background info on the how and also important why… Having this info all in one place (dare I say the User’s Guide or even the Wiki) might help some tremendously…
    I know it would help me… 😉

  2. A good example. Thanks.

    Surely this is a good reason why we need a way in the SDK to force evaluation of certain attributes. It would solve this issue, as well as many issues to do with caching.

    Put it another way. Creating an “Attribute Display” property causes the data to be pulled correctly, so there’s definitely some sort of mechanism in there to allow for this. Any reason that this can’t be extended to the SDK so that whenever we make a call to the “DataArray” property of an instance of the ICEAttribute class, it evaluates the tree and pulls the updated data through correctly? (We’d love you forever if it could!)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s