Finding degenerate polygons by area

Degenerate polygons are usually zero-area polygons.

Here’s a script that uses the ICE attribute PolygonArea to find polygons with area less than a specified epsilon:

si = Application
epsilon = 0.00001

# Get PolygonArea DataArray (which is a tuple)
attr = si.Selection(0).ActivePrimitive.GetICEAttributeFromName( "PolygonArea" )
areaData = attr.DataArray

# Find the indices of the bad polys
bad = [ x for x,y in enumerate( areaData ) if y < epsilon]

# Select the degenerates with a string like 'cube.poly[112,114,155]'
si.SelectGeometryComponents( 'cube.poly[%s]' % ','.join(str(i) for i in bad) )

### OR ###

# Get the actual Polygon objects
polys = si.Selection(0).ActivePrimitive.Geometry.Polygons
bad = []
for i in range( len(areaData) ):
	if areaData[i] < epsilon:
		bad.append( polys(i) )

si.SelectObj( polys )

Saturday Snippet: Selecting a range of polygons by polygon index

Given a selected polygon, add the next 5 polygons to the selection. For example, if polygon 22 is selected, then add polygons 23,24,25,26, and 27 to the selection.

You can do this without using any loops, by using a string expression for the polygon components.

Here’s some JScript that shows two ways to do it. Method 1 uses a string expression. Method 2 is a loop, which can either use the Polygons collection or a string expression.

var o = Selection(0).SubComponent.Parent3DObject
var p = Selection(0).SubComponent.ComponentCollection(0)
var LAST = o.ActivePrimitive.Geometry.Polygons.Count;

// Method 1
// SelectGeometryComponents("grid.poly[22-27]", null, null);

var sPoly = ".poly["+p.Index+"-"+Math.min( p.Index+5,LAST-1 )+"]"
//SelectGeometryComponents( o.FullName + sPoly );
//Selection.SetAsText( o.FullName + sPoly  );

// Method 2
//for ( var i = p.Index+1 ; i < Math.min( p.Index+5,LAST ) ; i++ )
//	ToggleSelection( o.ActivePrimitive.Geometry.Polygons(i) );
// -or-
//	ToggleSelection( o.FullName + ".poly["+i+"]" )

Here’s some Python that does something similar but different:

si = Application
o = si.Selection(0).SubComponent.Parent3DObject
p = si.Selection(0).SubComponent.ComponentCollection(0)
LAST = o.ActivePrimitive.Geometry.Polygons.Count

s = ".poly[%s-%s]" % ( p.Index, min( p.Index+5,LAST-1 ) )
si.SelectGeometryComponents( s )

Scripting – How to get the active objects for component selection

When you’re in a component selection mode (such as Edge, Polygon, or Point), the active objects are highlighted in orange. The “active objects” are the objects that are “active for component selection”.

When Softimage is in a component selection mode, the Selection will either by empty or it will contain CollectionItems (one for each object with selected components).

So, how do you get the active objects? Here’s one way, using the little known, magical “.[obj].”:

# Python
import win32com.client
oActiveObjects = win32com.client.Dispatch( "XSI.Collection" )
oActiveObjects.Items = ".[obj]."
// JScript
var oActiveObjects = new ActiveXObject( "XSI.Collection" );
oActiveObjects.Items = ".[obj].";

Extruding random polygons with random lengths and random insets

Last month, Guillaume Laforge posted a Random Extrusion compound that can extrude polygons with random lengths and insets.

Guillaume noted that this compound was for Softimage 2013 only, but it appears that [with a tweak] you can get it to work in 2012 SAP.

When you import the compound into 2012, you’ll see a warning in the status bar/script history:

// WARNING : 3000-EDIT-AddICECompoundNode - Could not find node : BuildArrayFromSetNode

All you have to do is put back the missing Build Array from Set node, then the compound appears to work in 2012 SAP.

ICE Modeling – Extruding a random polygon

All you have to do is plug a Random Value node into the Polygon Index port, and then set the Mean Value and Variance. If you then play around with the ID (of the Random Value), you’ll get a different polygon extrusion.

Most of this tree is for setting the Mean and Variance. If I have an odd number of polygons, say 81, then a mean of 40 and a variance of 40 will cover the range of polygon indices (0-80). But if I have an even number of polygons, say 80, then a mean of 40 and variance of 40 might give me an index of 80, which is out of range.

To randomly extrude more than one polygon, just feed a bunch of IDs into the Random Value node, like this:

I increased the number of polygons to avoid getting the same random number multiple times.