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
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… 😉
Thats a great idea 🙂
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!)
You can put “Log Values” node before setting data and python will see the attribute