Using ICE to do UV remapping on instances


I was playing around with Softimage, trying to set up a puzzle:
uvremap_puzzle
At first, I was using actual geometry and snapping to put together the puzzle, but then (after watching a Cinema4D tutorial that used the Cloner to assemble the pieces) I decided to use ICE to position the puzzle pieces. Halfway through that, I realized that the texturing was going to be a problem. There doesn’t seem to be an easy way to apply a texture to multiple ICE instances, and then make the texture stick when the instances fly away.

After trying a bunch of stuff (and crashing a lot), I took a look at the UV Remap parameters on the Image node:
uvremap_example

Then I created a 8×8 grid of 64 instances, and put all the possible min/max values in an array:
uvremap_show_values
If you look at the point IDs, and the array, the pattern is pretty obvious, and it allows you to use modulo and integer division to index into the array and get the right min/max values for each instance.

Here it is in ICE:
uvremap_ice_tree

Finally, the shader tree that gets the UV remap values and plugs them into the Image node:
uvremap_shader_tree

[ICE] Converting integers to strings


Thanks to Mootzoid emTools, it’s easy to convert an integer to a string:
int2str_emtools
Note that you get padding too, so it’s easy to do things like generating replacements for the [Frame] token.
int2str_emtools_ntoa
The emTools string compounds are convenience compounds:
int2str_emtools_ntoa

For fun, I tried to create my own integer-to-string converter using the stock nodes. I did by dividing by 10 until the quotient (the result) was zero; with each division, I take the remainder and stick it at the front of the string. And by setting Max Repeat to 4, I get padding on my strings (so for integer 45 I get “0045”).
int2str_intdiv
Note the use of Delay Set Data. The integer division compound uses Modulo and Division by Scalar. The 2char compound simply uses a Select Case to map a single digit to a string:
int2str_2char

It did occur to me that I could do it all with a single Select Case 🙂
int2str_selectcase
The catch is that the Select Case node has ten thousand cases.
int2str_selectcase_ppg
That’s really slow when you create that node in an ICE tree (for example, by importing a compound that uses it). It also takes a long time to create ten thousand cases, even with a script.

case_node = Application.AddICENode("$XSI_DSPRESETS\\ICENodes\\SelectCaseNode.Preset", "pointcloud1.pointcloud.ICETree")
string_node = Application.AddICENode("$XSI_DSPRESETS\\ICENodes\\StringNode.Preset", "pointcloud1.pointcloud.ICETree")

Application.ConnectICENodes("{0}.case0".format( case_node.FullName ), "{0}.result".format( string_node.FullName ) )
Application.DeleteObj( string_node.FullName )
Application.SetValue("{0}.case{1}_string".format( case_node.FullName, 0), "{0:0>4}".format(0), "")
Application.SetValue("{0}.default_string".format( case_node.FullName, "9999", "")

for i in range(1,10000):
	Application.AddPortToICENode("{0}.case{1}".format( case_node.FullName, i-1), "siNodePortDataInsertionLocationAfter")
	Application.SetValue("{0}.case{1}_string".format( case_node.FullName, i), "{0:0>4}".format(i), "")

Emitting particles from instances


Suppose you want to emit particles from the instances in a point cloud. For example, suppose you have a point cloud of instances of a BigFish model, and you want to emit little fish from each BigFish instance.

emit_from_instance1

One simple approach is to set up a point cloud on your master BigFish instance, and do the emitting there.

emit_from_instance2

Then when you emit the point cloud of BigFish instances, use InstanceShape instead of Set Instance Geometry.

emit_from_instance3

ICE: Getting the edge index of the longest edge


For each polygon, I want to get the EdgeIndex of the longest edge (ultimately, I want to get the midpoint of the longest edge for each polygon).

Being literal-minded, I started by getting the length of the longest edge for each polygon:
edgelength_max
Here’s a Show Values to show it works:
edgelength_max_showvalues

From there, I hacked my way to the edge index:
edgelength_max_index_1
The Show Values:
edgelength_max_index_1_showvalues

For my second try at getting the index of the longest edge, I stopped trying to go from the length back to the index. I think this is a little better approach:
edgelength_max_index_2

edgelength_max_index_2_showvalues