Emitting points from polygons


Here’s an ICE tree that emits points from the polygons on the emitter, using their PolygonPosition attributes.

Emit_points_from_polygons

As an exercise, I went to the trouble of using the PolygonNormal as the direction vector. That was slightly complicated, because I couldn’t use the EmitLocation attribute to get at the PolygonNormal. I had to use Get Closest Location with the new PointPosition instead. That’s because when you use positions instead of locations with Add Point (which is inside Emit from Position), then the EmitLocation attribute is “meaningless”, to quote the documentation.

There’s no such thing as PolygonLocation, so I had to use the PolygonPosition attribute.

Note also that I filtered out some polygons, so that I emitted points only from the faces of the soccer ball.

Emit_points_from_polygons_ex

Creating points on a group of meshes


From the docs:

Getting Scene data on Groups
When getting per-component data, such as PointPosition, the results are correct only when all objects in the group have the same number of components. As a workaround, one possible way to get, for example, all point locations is to plug the Get Data (group) node’s value into the Geometry port of a Generate Sample Set node with Emission Type set to Point and Rate Type set to All Points.

Here’s a screenshot of that workaround:
Group.GenerateSampleSet.PointPosition

Compare with: Getting point positions from a group

Copying colors from point cloud to polygonizer mesh


To get the colors from the point cloud onto the polygonizer mesh, you need to do something like this:

  1. On the polygonizer mesh, create an ICE Tree.
  2. Use Get Closest Location to get a location on the point cloud, get the color from that location.
  3. Store that color somewhere (eg in an attribute on the polygonizer mesh, or in a vertex color map).

Here I’m storing the colors in a CAV:
colors_to_polygonizer_CAV

And here I’m sticking the colors in a per-point Color attribute:
colors_to_polygonizer_Color

Copying StrandColors from cached strands to a point cloud


Suppose you had to load a cached strand simulation, and convert that to a point cloud of plain old points. Part of the job would be to copy the stand colors over to the new points, so let’s take a look at that.

First, and I didn’t know this, when you cache strands the StrandColor attribute isn’t cached, just a single Color per strand. So let’s rebuild the StrandColors:
rebuild-strandcolor
Now we have a per-point StrandColor array on the point cloud that reads the cached simulation. After spending awhile trying to avoid doing this, I found that this (the StrandColor array) was the easiest way.

Add Point is a pretty friendly ICE node, because it lets you take per-point data (StrandPosition) from some other point cloud and just plug it in, with no context problems.

copy-strandcolors-to-points

It’s not so simple with the StrandColors. StrandColor is a per-point array on a different point cloud, and you can’t just plug it into Set Particle Color. Set Particle Color wants a color, not an array of colors. And it doesn’t want colors from some other point cloud either ;)

To get around that, I use Build Array from Set, which gives me a per-object array in the context of the current point cloud. Then I index into that array with Point ID, and I’ve transferred over the strand colors to the points.

strands-points

ICE element-wise addition of two arrays of different sizes


For example, given the arrays [1,2] and [1,2,3,4], produce this array: [2,3,4,5,3,4,5,6].

In Python, this would look like this:

a = [1,2]
b = [1,2,3,4]
c = []
for x in a:
	for y in b:
		c.append( x + y )
		
print c
#  [2, 3, 4, 5, 3, 4, 5, 6]

In ICE, one way to do this would be to add
[1,1,1,1,2,2,2,2]
to
[1,2,3,4,1,2,3,4]

Here’s an ICE tree that does just that:
add_arrays_diff_sizes
This ICE tree uses the modulo trick, and the scalar-to-integer truncation trick.

You can see a variation of this in this Softimage mailing list post..

ICE: Doing an element-wise stretch on an array


I’m not sure “element-wise stretch” is the right terminology, but what I mean is suppose you want to build a new array by repeating the original elements N times. For example, suppose you have the array [1,2], and you want to turn it into [1,1,1,1,2,2,2,2].

Here’s a little ICE technique to do just that:

elmentwisestretch

This tree relies on Divide by Scalar truncating the scalar result to make it an integer.

Setting the DataArray2D attribute in scripting


Last time I tried this, I gave up on JScript (it seemed impossible) and got something to work in Python.

In JScript, I kept getting errors like “# WARNING : 3392 – Invalid offset specified while extracting data from this attributeÈ.

si = Application
from win32com.client import constants as C            # win32com.client.constants

oObj = si.Selection(0)
oICEAttrMats = oObj.ActivePrimitive.AddICEAttribute("MyString", C.siICENodeDataString, C.siICENodeStructureArray, C.siICENodeContextSingleton)
oICEAttrMats.DataArray2D = [["a", "b", "c", "d"]]

x = oICEAttrMats.DataArray2D
print x
print len(x)
print len(x[0])
print len(x[0][0])

for d in x[0][0]:
    print d


# (((u'a', u'b', u'c', u'd'),),)
# 1
# 1
# 4
# a
# b
# c
# d

See also this Getting DataArray2D attribute values post.

ICE: Storing vectors in a color at vertices property


The ICE trees for something suggested by Pooby in this Storing initial values thread on si-community. In this example, I’m trying to store per-point data into a per-sample attribute, so I have do a little extra work. I’m actually storing the point position multiple times for each vertex (one vertex had N samples), but I don’t know if it’s worth the effort to try and avoid that.
StoreVectorInCAV

Getting the stored vectors back out:
GetVectorFromCAV