Using the PolygonArea ICE attribute to select similar polygons

After seeing this select similar post on xsibase, I wrote this Python example that uses the PolygonArea ICE attribute to find polygons with similar areas. I didn’t want to use a custom preference or any ppg, so this script looks for [more-or-less] equal areas rather than for a value range. It’d probably be more useful to look for areas within a certain range (but that would require user input).

To use this script, select a polygon and then run the script. It’ll select all polygons with the “same” area.

This ss_SelectSimilarPolys add-on uses a threshold to define an area range (and it uses PolygonArea too). RCTools also lets you specify an area range, along with a number of other things like number of edges and poly orientation, in its custom Polygon selection filter.

from siutils import si		# Application
from siutils import sidict	# Dictionary
from siutils import sisel	# Selection
from siutils import log		# LogMessage
from siutils import C		# win32com.client.constants

# Number of decimal places
# For example, do I match .776 or .78 ?
# With 2 decimal places, anything in the range (7.75, 7.85) will be caught by .78
gPrecision = 2

# Need this for .Polygons later...
def dispFix( badDispatch ):
	import win32com.client.dynamic
	# Re-Wraps a bad dispatch into a working one:
	return win32com.client.dynamic.Dispatch(badDispatch)

# Get selected polygons
polys = sisel(0).SubComponent.ComponentCollection

# Get index of first selected polygon
ix = polys(0).Index

# Get primitive of parent 3D object
prim = sisel(0).SubComponent.Parent3DObject.ActivePrimitive
prim = dispFix(prim)

# Get PolygonArea DataArray (which is a tuple)
attr = prim.GetICEAttributeFromName( "PolygonArea" )
areaData = attr.DataArray

# Round PolygonArea to the specified precision
roundedAreas = [round(x,gPrecision) for x in areaData]

# Get the area that you want to match
areaToMatch = roundedAreas[ ix ]

# Get all polys with a similar PolygonArea and select them
# Function findall from
def findall(L, value, start=0):
        # generator version
        i = start - 1
			while 1:
				i = L.index(value, i+1)
				yield i
        except ValueError:
for ix in findall(roundedAreas, areaToMatch ):
	sisel.Add( prim.Geometry.Polygons( ix ) )

5 thoughts on “Using the PolygonArea ICE attribute to select similar polygons

  1. You could do a generic selection tool using ICE for the logic !
    For example using an ICETree the user could set a rule (like “if polygon area > threshold”) that would set a boolean attribute (“IsSelectedPoly” for example). Then a python plugin would select the components based on this attribute ;).

    • I like this idea. But I got all the way down to writing the filter plugin before I realized that ICE was not evaluating my tree, and so the boolean attribute wasn’t defined.

      The boolean attribute wasn’t being used anywhere, so unless I Show Values or use it somewhere, the attribute isn’t available for the filter plugin.

  2. The only problem with using ICE is that the boolean attribute won’t be defined if you don’t use it somewhere. I got as far as writing the python filter plugin before I [re]discovered this…as soon as I turned off Show Values, the attribute was no longer defined and my filter failed 😦

Leave a Reply

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

You are commenting using your 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 )

Connecting to %s