Thursday, 18 July 2013

Faster Polygon Islands

Eric Mootz's emTools  has a suite  of compounds to manipulate polygon islands with a particle cloud. They require a pre-calculated index array mapping vertices to their island index. Doing this in ICE directly is relatively slow - quite a bit of work has been done to get these ICE compounds as fast as possible (see Guillaume Laforge's original blog post and this thread on but a C++ ice node can usually run orders of magnitude faster. In the case of the node provided here it has proved to be as much as 10-15x faster than the ICE implementations (depending on the scene). I'm sure there's scope for more optimal C++ coding to make it faster still.

You can use the node to feed data into Eric's vertex island tools (sample scene in the .rar file, remember to install emTools first) or as a standalone utility node if you're manipulating islands in your own way. It takes geometry and point positions as inputs and can output the index array of points and their island index, a per point island index and an array of island centres.  It's been compiled against 2013 SP1 64bit. Source code is included with the addon.

jj_Island_Indexer 1.0.0

Tuesday, 2 July 2013

Dart Throw Multiple Size

Dart Throw has been updated to support an input array of multiple sizes (as well as continuing to support a single input size). You can now instance a group of differently-sized objects onto your particles by creating an array of the sizes of the objects in the group. Numerous other tweaks and upgrades have been added:
  • Input an array containing multiple sizes and darts will match those sizes
  • Weight map based size adjustment now supports either absolute or scaled size
  • Randomising now supports negative variance and either absolute or scaled size
  • A new 'min size' parameter lets you control/limit the minimum size
  • Size adjustments via weights and/or randomisations can be applied to the array of input sizes
  • source code is now included in the src directory of the addon
  • Illustrative sample scenes are included in the archive
The new version of Dart Throw (2013 SP1+, 64bit)  can be downloaded here.

ICE Node Inputs

Usage Summary

This controls how many attempts are made to position a dart on the geometry. The more attempts you make the denser the packing becomes up to the point where it becomes virtually impossible for a dart to land on an empty space with sufficient room for its size.

If you look in the history log, Dart Throw reports something like the following: "Max iterations is: 41 at: 49990" (assuming an iterations setting of 50,000). This tells you that the maximum number of attempts it took to get a successful dart inserted was 41 and that happened at iteration 49990.

In a scenario where you get something like "Max iterations is: 101000 at: 899012" (assuming an iterations setting of 1m) you can see that it's taking over 100,000 attempts just to get one dart positioned. It's probably not worth waiting for that 1 extra dart and so you could reduce your iterations to 899011. In the Misc section you can use an 'Iterations Abort Threshold' parameter to set a value for how many unsuccessful dart throwing attempts the node should make before abandoning automatically. See that section below for detailed instructions.

You can input either an array or a single value here and Dart Throw will generate 'darts' that only use those size(s). The size array does not need to be in any particular order which means you can put your objects into your instance group any way you see fit.

Size Adjustment

Two different instance types with sizes adjusted by weightmap.

If you plug a weight map into the size map port you can control the size of your particles using the values in the map as an interpolant. What that means is that the weight map value between 0-1 will interpolate between the Basic::Size parameter you entered above and the Size Adjustment::Adjusted Size parameter you enter in this section.

The Adjusted Size parameter can be set as either a scaling factor for your size or as an absolute value. Depending on the weight map value your particle size will then interpolate between Size and Adjusted Size.

If you plug a weightmap into the Erase Map port then darts will only land on areas with a weightmap value on or above the threshold. All other darts will be deleted.


A single instance whose size is randomised using a variance. Version 3 supports negative variance.

The randomise option enables you to add a variance to your sizes either as an absolute value or a scaled value. Randomise assumes a variance around 0 so you'll get both negative and positive variance. This is where setting 'min size' (see below) can help ensure your smallest particles are not pushed into negative territory if you use the scaled option.


Iteration Abort Threshold
This parameter lets you specify what fraction of the total iterations have to occur without a successful dart before the node automatically stops iterating. For example if you have set 1,000,000 iterations and set this parameter to 0.1 it means that if there are 100,000 iterations without a successful dart the node will stop iterating.

Min Size
Now that the randomise feature (above) supports both absolute and scaled variances it's possible, using scaled, to scale your particles by a negative amount i.e. if your variance is set to, say, 0.5 then you will get scaling values between -0.5 and +0.5. Min Size simply sets a minimum for your particles. (If you use absolute in this scenario it means you can subtract negative values from your particle size which won't necessarily push the size into negative territory).


Position Array
This is the array of successful dart positions.

Size Array/Size Per Point
This is the array/per point output of sizes associated with those output positions. Be aware that the size output needs to be treated differently depending on whether you're using intrinsic ice objects like sphere, cube, cone etc. or geometry instances. In the case of intrinsic ice objects you should use this output directly to control the size. In the case of instances you need to divide the output size by the input size to work out a scaling factor for your instances. See the sample scenes for examples.

Size Index Array/Size Index Per Point
If you're using an input array of sizes this is either an array or per point output specifying the index into the input size array for each position. For example, your input size array will match the sequence of sizes in your instance group. When Dart Throw allocates a size to a point you will need to know for each point which size it has selected. This output tells you the index of that size so that you can pick the correct instance from the instance group.