Finding and deleting ICETrees on an object


Here’s a JScript snippet for deleting ICE trees from the objects in a group.

Note that the Primitive.ICETrees property returns all ICE trees that write to the object, including ICE trees on different objects (such as the italicized ICE tree in the screenshot below).

var o = Selection(0);
delICETrees(o, false );

function delICETrees( oGroup, bDelAll )
{

	var bFlag = ( bDelAll == null ) ? false : bDelAll;
	logmessage(bFlag);

	if ( oGroup != null && oGroup.type == "#Group" )
	{
		oGroupEnum = new Enumerator( oGroup.Members ) ;
		for (;!oGroupEnum.atEnd();oGroupEnum.moveNext() )
		{
			var o = oGroupEnum.item() ;
			var p = o.ActivePrimitive;

			oICETreeEnum = new Enumerator( p.ICETrees ) ;
			for (;!oICETreeEnum.atEnd();oICETreeEnum.moveNext() )
			{
				var oICETree = oICETreeEnum.item() ;
				if ( bFlag || oICETree.Parent3DObject.IsEqualTo( o ) )
				{
					LogMessage( oICETree.fullname );
					// DeleteObj( oICETree );
				}
			}
		}
	}
	else
	{
		LogMessage("Select a group" );
	}
}

Finding closest point with boolean flag equal True


Here’s an example (from a question posted on the XSI list back in 2009) that illustrates some aspects of using arrays in ICE.

  • Get Closest Points returns a sorted array of locations, with the closest locations coming first in the array.
  • Find in Array finds the index of the first (and hence closest) point with the psFlag attribute set to True.
  • With that index, you use Select in Array to get the location of the closest point with psFlag=True.

Tip: Use compounds to organize your ICE trees


Compounds are useful for organizing your ICE trees. Even if you don’t intend to reuse or distribute your compounds, using compounds can help make your ICE trees readable and understandable. Kinda like paragaraphs in written text. Use compounds to separate blocks of functionality, and give your compounds meaningful names. It’ll help later when you come back to an ICE tree you haven’t worked on for awhile.

Consider this basic emission. Looks pretty simple, right? You can tell at a glance what’s happening, and what scene references are used in this ICE tree.

If you explode all the compounds in a Basic Emission, you get something a lot more complicated looking:

Without any compounding, you’re looking at a 195 total nodes (and 46 different nodes).

Using Delay Set Data to set attributes that depend on each other


Here’s the screenshots to illustrate the example described on the Delay Set Data reference page.

“For example, if you want to swap values of A and B, just using two Get Data nodes and two Set Data nodes (A=B and B=A) would result in both attributes having the same value.”

“However, if you connect the Set Data nodes in the Delay Set Data node, the Set Data operations will be executed at the same time, thus setting the values before any of the Set Data nodes are executed. ”

Understanding how and when to use Delay Set Data


I never really looked into Delay Set Data, so I never really understood what it did. I just assumed that it delayed setting data until something else happened. What it really does is handle situations where a multi-output port is connected to multiple Set Data ports.

Consider this ICE tree. You might think that X and Y are set to the same value (10), but that’s not what happens. You end up with X=10, and Y=15.

That’s because each Set Data forces an evaluation of the branch connected to the Set Data port. So in a tree like this, where the Add output port is plugged into two Set Data ports, you get two evaluations. First when you set X, and second time when you set Y. Consequently, X is first set to 5, and then to 10, and that all happens before the value of Y is set.

What happens with this ICE tree is like what happens in this Python snippet.

X = 5
Y = 5
X = X + Y
Y = X + Y
print X
print Y
# 10
# 10

Not like this:

X = 5
Y = 5
Y = X = X + Y
print X
print Y
# 10
# 10

To get the expected results and eliminate the extra evaluation, you could change the ICE tree so that the Add node has only one connection to the Set Data. This tree will run faster, because it has one less evaluation of the Add branch.

The Delay Set Data node addresses this issue by caching (for each Set Data port connection) the values from the first evaluation of the branch, and then setting the values all at once.