Happy 2012 !

Very long time since my last post ! Too busy I guess :P .

I’m starting this new year sharing with you a custom ICE node that was on my hard drive since last year… It generates the polygonal description to build a 3D Convex Hull.

 

You can download it here. It includes two scene files and the win64 dll.
The C++ sources are also there if you need to compile it for an other platform.

I used the Gift wrapping algorithm and  added a mode to generate NGones when several triangles are coplanars (just un-check “Triangulate Coplanar” to use it) but, be careful, this mode is buggy !

An artist using Softimage ICE

My friend Olivier Jeannel showed me its last film and I really liked it ! So I decided to invite its work on my blog :) .

Olivier is one of those talented guy used to be the director, the 3d artist and the compositor of some motion design works since several years. The first time I met him (some… years ago now…) he was doing a fantastic job for some Eurosport billboards using Lightwave and After effect (I was also using LW at this time). We started to exchange ideas about ways to “make things” in 3D. I was not yet so dedictated to the technical side of 3D, and I really think that those discussions with Oliver pushed me in this direction. It was obvious that its artistic vision was way beyond my limited talents in this area, and it was obvious that I was enjoying giving him technical advices for his various projects.

But lets speak about his new film. This is a command from the “Club des directeurs artistiques”. It is a french club of artistic directors making an awards ceremony every years for the best commercials. He was in charge of the official film. He used Softimage for all the 3D and I think it is a very good illustration of what an artist can do with ICE. Olivier never learned programming languages and his education background is not really oriented on math but rather on art as he did the “Ecole nationale supérieure des beaux-arts” in France. He often try various ICE compounds found on the web and modify them using its own logic without writting a single line of code ! He told me that without an internet connexion, ICE would not be so useful to him :) . The nice thing about ICE is that it is really interactive. No need to always understand what you are doing, if the instantaneous feedback in the 3D viewport is looking nice ;) .

Finally, here is the film. Pump up the volume and enjoy this one man work :

ICE Modeling : A Procedural Bullet Shattered Glass Compound

A bullet  shattering glass effect got a very characteristic pattern (and very different from the well known voronoi one).
As in Softimage 2012 we can build some polygon meshes using ICE, it was a good exercise to illustrate the flexibility of this new Softimage weapon :) .

My first test was trying to slice an existing mesh using a radial design. It was not so bad but rather complex. I needed something more simple. We’ve got sphere or torus primitives, and I wanted a shattered glass primitive, nothing more.

Looking at the some pictures and videos of glass shattering I noticed that the  radial cracks and  rings starting at the center of the impact  could be simplified to an “un-wrapped cylindrical extrusion”. As I’ve got already an ICE compound to build such extrusion (and as I am lazy), I choosed this solution.

Re-factoring this compound, it was easy to generate the good polygonal description (the array describing the vertices of each polygons). Then the job was to set the position of this extrusion in a radial pattern with some randomness scaled by the distance from the center. The first tests were not so bad. Here is a little demo :

And here is the ICE compound . To use it, just create an empty polygon mesh, add an ICETree in the modeling region and connect the compound.

At least here is a little rendered animation using Momentum for the simulation (a Softimage open source plugin using the Bullet Physics library) and Arnold for the rendering (using the Softimage to Arnold plugin) :

Thats all for this first public ICE modeling compound ! If I find some time, maybe other ones will follow…

ICE Cache Explorer

Before Christmas, I was speaking around a coffee with Marc-André Belzile (Mr Softimage SDK and many more) about a little viewer to see our ICE particles simulation without opening Softimage and then he created this nice open source project ! : http://code.google.com/p/ice-cache-explorer/

A Python viewer to scrub your icecache, Nice :) .

And feel free to contribute !

Happy 2011 !

I just saw those great news tonight. Softimage is #5 and Lagoa from Thiago Costa is #1 in the CGSociety 2010 retrospective !

2010 was all Softimage for me too as I joined this incredible team in april :) .

I wish you all the very best for 2011 !

Guillaume Laforge

2010

Lagoa Multiphysics 1.0 – Teaser

A Multiphysics framework for Softimage ICE by Thiago Costa.

Enjoy !

me, myself and I

Tired to type “Get Da” and then “Self” ?
Here is an advanced ICE node for advanced ICE users ;) :

(windows user can drag n drop the icon on an ICETree graph)

Polygon Islands : Using Arrays

From the last post, our points now own the “__LowestPointIndexInIsland” attribute set to the exactly lowest point index in the polygon island.

"__LowestPointIndexInIsland" per point attribute

Our goal now is to build a polygon island index attribute like this : Once again, we need to think in which context we can see our data. If we stay in the “per point context”, we will only see one point at a time. It would be harder to build an algorithm to get our polygon island index this way.
But if we could build just an array (in per object context) of all our “__LowestPointIndexInIsland” attribute it would be easier to deal with (we will see latter how).

“Build Array from Per Point Data” :

In Softimage 2011, you just need to use a “Build Array from Per Point Data” compound. But you can easily build a similar one in any versions (and it will be an other excuse to learn something new !).

Build array from per point data

First we create an array with the same size as the number of points in our object.
Then we build an other array from the first one using its sub indices. Here is an example :

  • Index :  0 .  Array A data : a value  >  Array B data  is Index 0.
  • Index :  1 .   Array A data : a value  >  Array B data is Index 1.
  • Index :  n.   Array A data : a value  >  Array B data is Index n.

If we feed an “ID to Location” node with this array, it will return an array of locations.

From this array, we can get all our “__LowestPointIndexInIsland” attributes in one go !

The “zipped” array :

Or how to create an array B [n, n+3, n+6] from an array A  [n, n, n,  n+3, n+3, n+3,  n+6, n+6, n+6].
We need to iterate through array A values and push the value to array B only if it doesn’t exist in Array B.
The way you iterate along an array in ICE is using a Repeat node with the number of repeats set to the array size. We will need to build a repeat counter attribute to be able to select the “current value” in our Array A  inside the repeat execution. As it is a common setup in ICE, I built my own compound some time ago to deal with this kind of executions.

zipped array graph

I usually name the iterator attribute “__ITERATOR_my_name”. This way it is easy to know from a get data that we are dealing with this kind of variable.  It is always nice to be able to figure out a graph without zooming on each nodes. From the “zipped array graph” with can easily read that we get four attributes from the object  istself (blue nodes) and that we set one attribute (the light blue one). In fact we also set the itterator attribute at each repeat execution but we already know that from its name. I’m hiding the iterator attributes from the explorer using “__” (as in ICE there is only one global name space).
Once you are comfortable with the Repeat node workflow, if your are using Softimage 2011, you can directly use the “Repeat with Counter” compound !

The index array :

Now from the array B [n, n+3, n+6] we can build an array C[n, n+1, n+2]. We will use again a Repeat node, an itterator and some Array nodes.

We are doing a very similar graph and finally get our Polygon Islands Index. If you haven’t download those compound from the first Polygon Islands post, here is the link again. Once the addon installed, you could dive inside the “Create Polygon Island Index” compound and figure out how it works.

Cheers !

Polygon Islands : Getting the Lowest Point Index Part 2

Warning : This is not really a step by step tutorial on how to build this compound but rather an attempt to show how you can translate an idea in “ICE language” .

_____

So now that we can easily get our point index, it is time to see the concept of “Location” :

From a location you can get all the attributes of the context (of this location). The attributes will be interpolated between the context attributes around the location. …well, lets take a more explicit example.
In real life, a location is more than just a position. For example, if I’m located in Paris, I can see the Eiffel tower, I can hear people speaking french, I can also know my latitude/longitude position and so one. If you think of the ability to see the Eiffel tower or to hear french as the values of  “monument” and “language” attributes for this location, then you get the picture. Location in ICE is a  very similar concept ( so you can easily know if your point is near the Eiffel tower…), but instead of being on earth, an ICE location is on the surface of your geometry (so I could be wrong as you probably can’t see Eiffel tower from your geometry …).

From the doc, we can read that the “PointNeighbors” attribute  is “an array containing the locations of the vertices that are connected to a vertex by edges.If you get this attribute at a surface location, it returns the neighbors of the vertex closest to the location.”.
As those location are in per point context (a vertice is a polymesh point in Softimage) we can get our “__LowestPointIndexInIsland” (see previous post) without problem from those locations. Now we just need to find the lowest value in the array and compare it to the current point value. I won’t go into detail here as you just need to look at the ICE graph of the “Get Lowest Point Index By Islands” compound :P .

So now that we know if our point index is smaller or not than its neighbors, we need to repeat this operation several time to get the very lowest index in the island. If you remember my little “doodle graph” from the first post (or if you just look below) : We see that for those 3 points, we need to repeat the neighbor comparison two times.  A basic approach would be to use a repeat node with a rather large number of repeat iterations. In fact you should built such setup. This way you would see that increasing the iteration slider would give you better and better result (using the “show value” feature of the ICE graph) until all the points would be set to the lowest index. But the Repeat node … repeat the same amount of time the comparison for all the poly islands. If an island is made of only one triangle and the Repeat node is set to 100 (for example), the poor little triangle’s points would be compared too many time (and it couldn’t be tolerated !). So we need to know if all the points of this triangle are still updating their lowest index attribute at each iteration. Using a While node with the condition “is my index still changed” is a better option. It will give us the opportunity to see how we can initialize an attribute in ICE !

“Initializing Data” :

ICE handle very well undefined custom data. It will always try to guess the data type from upstream or downstream connected nodes. In the example below, to create the “__IndexIsNotChanged” attribute, we don’t need to first use a Set Data. Once familiar with this workflow, you will discover that it speed up your graph construction. If your data need to be create with a default value like 0.0 or false or 0.0, 0.0, 0.0 (for a vector) then you don’t need to set it :) . It will find its type latter in the graph !

We can see that first, the “__IndexIsNotChanged” attribute is a value but ICE doesn’t know its type. Then we ask for the minimum in the set for this unknown attribute and ICE is still confortable with this abstraction :) .
As soon as we plug the Get Minimum in Set in the Not node (a node always returning a boolean value), our attribute is set as a boolean attribute. It will be a per object context attribute until we start to use it in an other context.

I’m stopping here for tonight. Stay tuned, in the next post we will have fun with ICE array.

Cheers !