Given an array like
[0, 3, 7, 22, 6, 71, 1, 0, 9]
how do you sum up the first group of three elements (0+3+7), the second group of three elements (22+6+71), the third group (1+0+9), and so on and so on, without using a Repeat node?
Well, you could write your own custom ICE node. Or you could use Generate Sample Set like this:
Here’s a couple of examples to illustrate how to use Sort Array with Key.
This ICE tree sorts points by their Y position.
And this tree sorts points by their brightness.
Here’s a couple of examples of how to use a geometry query to modify certain points in a point cloud. The geometry queries return locations, and you can’t plug locations into Set Data nodes, so you need to take a different approach.
The interesting part (to me) is generating the sequence of indices. It’s too bad I have to create a second array to do it, but I keep the size down to an Nth of the original.
StrandPosition is an array of arrays: one array of positions for each strand.
Here’s a Python snippet:
from win32com.client import constants
xsi = Application
def dispFix( badDispatch ):
# Re-Wraps a bad dispatch into a working one:
attr = xsi.Selection(0).ActivePrimitive.Geometry.ICEAttributes( "StrandPosition" )
dataType = attr.DataType
data2D = attr.DataArray2D
for data in data2D:
for elem in data:
elem = dispFix(elem)
xsi.LogMessage( "Vector3: " + str(elem.X) + ":" + str(elem.Y) + ":" + str(elem.Z) )
And here’s a JScript snippet:
a = Selection(0).ActivePrimitive.Geometry.ICEAttributes( "StrandPosition" );
LogMessage( ClassName(a) );
x = a.DataArray2D.toArray();
LogMessage( x.length );
for ( var i = 0; i < x.length; i++ )
y = x[i].toArray();
LogMessage( "=======================" );
for ( var j = 0; j < y.length; j++ )
LogMessage( y[j].X + ", " + y[j].Y + ", " + y[j].Z );
As I wrote yesterday, there surely was a better way to get the neighbors of a specific point than messing around with a bunch of arrays. Here it is.
Hat tip to Eric Thivierge
There’s surely a better way, but this was a good little exercise in using ICE array nodes.
PointNeighbors is a set of per-point arrays, so when you feed that into Get Array Size, you get a set of per-point integers (the number of neighbors for each point). Get Set Size, in contrast, will give you a per-object integer (the number of per-point arrays in the set).
Here’s a recent array question from the mailing list: How do you build an array that looks like this?
[0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, ...] ?
I didn’t check the other answers yet, because that would be cheating 😉
When I look at that array, I see a repeating sequence of four integers, so that naturally suggests doing something with the Modulo node.
Using the If node is nice for clarity, but I could simply take the Boolean output of the comparison node.
Suppose you have an animated scalar value, and you want to store its values as you play through a simulation. And suppose you also want to keep a running total of all the values up to the current frame.
My first try used two arrays: one to store the values at each step through the simulation, and one to hold the running total.
Calculating the array sum at every step seems wasteful. So, here’s my second try at keeping a running total of the values from the fcurve. I use just one attribute and one array. The attribute was necessary because if I plugged Pop from Array directly into Add, I got nothing.