Wednesday, 4 March 2009

Scope and Breaking Down The Walls Between Data

In a traditional scripting environment using the Softimage SDK it would be a relatively simple task to peform operations on individual vertices and cross-reference those vertices with others on the geometry. You have full and unimpeded access to the vertex arrays and associated data. However deep you burrow into the data there's always a mechanism available to access some completely unrelated data elsewhere. Your data network can be as arbitrarily complex as you like.

In ICE the situation is different - access to data is carefully marshalled. The more you dig down into the different element contexts (point, edge, sample etc), the less you can see of the rest of the geometry data. If you're in per point context, for example, you can't see any information related to non-adjacent points, edges, uvs etc. To get at any data at this level you usually have to use a Geometry Query. This is a huge difference. Effectively, the more you dig down the blinder you become - the only chink of light visible is data at the object level back where you came from. Everything else is invisible.

Let's illustrate this whole thing with an example. You need to store the lengths to adjacent points on a linear curve's points i.e. you need some mechanism to say: 'at this point the length to the point to my left is x and the length to the point on my right is y' and store those x, y values on each point of the curve for later processing (see image below).

There is no native attribute in ICE for finding the neighbouring points of a curve's individual points when you're in Per Point context. It's a great example of how the further you dig down into the granular levels of data in ICE the more 'locked out' you are from other pieces of data. A Geometry Query might give you the two closest points but who's to say these are the closest connected points?

So, how do you break down these walls? The most elegant way I've seen so far is Ahmidou
Lyazidi's compound on the community site. But his mechanism, which uses the fact that linear curve points have an even distribution of U doesn't really help illustrate our point. So I'll explore another route. In this scenario you need to somehow prepare your data in Object context since it's the only other context visible. And yet, on the surface there's simply no mechanism in ICE to allow you to access the whole array of Point Positions in one go as a single array - to get at point positions you usually need to be in Per Point context where you only have access at any one time to the position of the point you're working on. Thanks to a trick by Raffaele Fragapane, however, you can get the whole array of Point Locations in one go in an Object context - by using the Get Closest Points node.

Armed with an unordered list of Point Locations corresponding to each point on the curve you can then extract the PointU of each location which is a normalised value between 0 and 1 corresponding to the position along the curve the point sits. A sort of this array will give you an array of all the PointUs on the curve corresponding to each point in index order.

Because of the hierarchical nature of the scope in ICE, as you burrow down into data you can still see data back at a higher level e.g. when you're in per point context it is still possible to see any data in object context. So, in our example, if we now switch to per point context and get the PointU for each point we still have access to an array at the object level which can tell us the PointU for the points adjacent to us (the array we've just created using Closest Points). By using Get Element ID as we traverse the PointUs at a per point level we can index into the PointU array at object level and can then construct data at a per point level which pulls data from outside the scope of the individual point. The image below illustrates the tree for doing just that...

So, even though ICE marshalls data very strictly and enforces pre-defined routes for collecting data, it's still possible in some cases to break out of the constraints that the different contexts enforce. In this case, by storing the locations of the 'neighbours' in a per point context it's possible to get ICE to 'see' data that would not normally be within an individual point's scope.

1 comment:

  1. Just realised I was sitting behind this guy at work. Hey Julian, I like your blog. ;)