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 an ICE tree that removes all duplicate elements from an array. It uses Generate Sample Set, so there’s no repeat nodes. But it relies on the fact that you can feed in an array of indices into Remove from Array, and Remove from Array doesn’t care if that array of indices itself contains duplicate. So, if you plug the array [1,1,1,2,2,2,3,3,3] in the Index port, Remove from Array will nicely remove elements 1, 2, and 3 with no complaints.
Unlike some other methods, this works with scalars too:
Hat tip to Oleg who posted this tip on the mailing list some time ago.
The basic ideas is that instead of looping over an array with a Repeat with Counter, you use Generate Sample Set to get a data set, and you do everything in a per-generated element context.
As an example, let’s revisit the problem of taking one array and creating a new array where each element is the sum of the elements before it.
The old way, with a Repeat with Counter node, looks like this:
Using Generate Sample Set, you can work with a data set and use that to access the array elements:
Generate Sample Set is set up to give an exact number of samples:
In ICE, how would you generate an array like [1, 10, 100, 1000, 10000, 100000, …] without using a Repeat node ?
It might help to look at it this way:
Once you recognize that you are looking at powers of 10, and recall that the basic Math nodes can handle arrays just as well as single values, the rest follows easily:
This post is based on the recent xsibase thread Golden Section Spiral in ICE, which in turn is based on Patrick Boucher’s 2006 article Points on a sphere.
So…here’s an ICE version of the Golden section spiral algorithm for evenly distributing points on a sphere. It’s a typical example of basic “thinking in ICE”: when you see a for loop in the alogrithm/pseudocode, you should see “in ICE” an array (or data set) flowing through a graph.
Here’s my GoldenSectionSpiral compound (although if you’ve never converted a scripted alogithm to ICE, you should do it yourself just for the exercise ;-) I thought the spiral effect was interesting, so I put in an option to not convert radians to degrees (which is necessary to get the real evenly distributed points).
Here’s a simple parametric point cloud that shows the two techniques for using arrays instead of Repeats that I blogged about earlier:
Using arrays to avoid Repeat part I
Using arrays to avoid Repeat part II
I used this set of parametric equations to get a cylinder point cloud:
x = sin(u)
y = cos(u)
z = v
0 <= u <= 2*PI
-2 <= v <= 2
For this exercise, I simply used Build Interpolated Array to build arrays of U and V values, but I probably should use something like the XYZ_Grid_Generator technique described by Daniel Brassard on si-community.
Here’s a version of the ICE tree with some Show Values.
I use the Modulo technique to build an array of the XY values for all points in the cloud.
Then I use the Divide by Scalar technique (the integer result is truncated) to build an array of the Z values.
Finally, I add XY vectors to the Z vectors to get the final point positions.
Part I is here
Another building block for using arrays instead of Repeat loops: an array that looks like [0,0,0,0, 1,1,1,1, 2,2,2,2, …].
Again, the trick is to use this array as the indices for Select in Array.
Here’s how to build this kind of array:
Here’s a simple example. I get the positions of the objects in a group, and then use those positions to add points in a point cloud. Basically, I have a group of objects, and an array of vectors (the interpolated array). When I add a point, I take an object position and add a vector to it to get the point position.
For each object in group
for each vector in array
Point Position = vector + object position
If that ICE tree is hard to follow, then it may help to use some attributes to store intermediate values(arrays). That way you can separate out some branches of the tree: