Scripting: Getting the StrandPosition arrays

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 ):
    import win32com.client.dynamic
    # Re-Wraps a bad dispatch into a working one:
    return win32com.client.dynamic.Dispatch(badDispatch)

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 );

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:
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.


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.