Convert Groups to Point Attributes

Hey – As a Houdini newbie, I’m still struggling a lot with groups and attributes. Today I wanted to do a circle of objects with the copy sop and give it a gradient color by polygon island. Good. Easy – I thought. BUT, the copy SOP creates just groups of objects. Now my question was, how to convert a bundle of object in an fresh point attribute from 0-1. My Approach was to convert the groups with the assemble SOP to a primitive attribute. After this I used an attribute promote to convert the primitive attribute to a point attribute. In the final step I created a fresh attribute and did a fit function to have a nice range from zero to one. fit(@island_index,0,ch(“../copy_copy360Deg/ncy”),0,1). Accordingly I was able the use this attribute in the color sop. the result, was the picture below.

To me it feels like a to involved process – I’m sure that the same process is also doable in one node e.g. in an attribute wrangle.

Rename Group Materials


A common workflow for us is to assign materials in softimage with the help of groups. All objects in a group share the same material, which makes material assigning and overriding easy. During the last days I had to select tons of meshes, to group them and to assign a new material to it. Lazy as I am, I have written a script that renames the group material with the groups name. This saves a lot of keyboard write work. Btw, this script works also with partitions – Some people prefer sorting Materials on the top level of SI’s hierarchy.

xsi = Application
collSel = xsi.Selection
log = xsi.LogMessage
for x in range(0,len(collSel)):
	oType = str(collSel(x).Type)
	oType2 = oType.replace("#","")
	if(oType2 == "Partition") or (oType2 == "Group"):
		log("Group Name: " + str(collSel(x).FullName) + " | Material: " + str(collSel(x).Material))
		if(collSel(x).Material == "None"):
			log("sftools.debug: There is no Material applied to the group")
			oObject = collSel(x).Name
			oObjectPath = collSel(x).FullName
			oMaterial = collSel(x).Material
			oMatLib = collSel(x).Material.Library
			oMat = oMaterial.Name
			xsi.SetValue(str(oMatLib) + "." + str(oMat) + ".Name", str(collSel(x).Name) , "")

Delete random polyislands

Hey there,


yesterday I had the case that I had to delete random polygon islands in ICE. I thought, ok no problem. But the solution was unexpected tricky. Here is the ICE tree I ended up with.

I’m sure, that there should be a faster and easier solution for this problem. If I’m thinking in Houdini – the approach is much more simple. Just use a connectivity SOP, create an float Variable, randomize the connectivity class and filter the new attribute with a delete sop. That’s it 😉

What’s also nice about the Houdini way, it’s easier and mmuuuch faster than in XSI.

Animating objects along curves

Hi again,

in this small tutorial I try to explain a workflow I’m using frequently, when I have to animate streams of objects. Here is a example for what I’m talking about:



Procter & Gamble
Dash 2 in 1
Saga Film
The Marmalade

As you can see different instances of flowers move along an curve. To get this working I make use of the u coordinate of curves and map it to an point array I’m generating. Next I guide you through how you do this in Houdini.

First hit tab do generate a new geometry, dive in add an add sop to generate the fist point. Next add a duplicate sop to duplicate the point as often as you want. With this done let’s create some attributes. We need Shape, Orientation and Scale. Give the Shape a integer, the Orientation a vector and the Scale a float type. To randomize the Orientation randomize the different channels with this function “fit(rand($PT),0,1,-360,360)” – this will give us a rotation between -360 to 360 in the different channels. For the expression of the shape we will add a function later. Optional we can create a fourth node to randomize the color. Just generate a Attribute Randomize node give it the Cd attribute and connect it to the stream. Great, that’s the fist one of the three base streams.


Let’s create the second stream. This will be the curve our points will fly on. Draw and curve, resample it and add a polyframe sop to get a Normal (N) and TangentU (tangentu) attribute.

Now we’ll do the fun part – Create a Point VOP to combine the two streams. Dive in and wire everything as shown on the picture below. As you can see see, our network got three inputs: Start, End and add. As the names of the parameters say, they will define the start and end point of our flying points. The add parameter is there to animate the points. The range will be between 0-1, which is a great range to remap with the u coordinate.

At this point it should look like this:

Ok so following build the third stream! Add a sphere, box, torus and connect them to a switch. Connect the switch to a transform node an take this as the primitives to copy input of a copy sop. Now take a Attribute Delete sop, connect the Point VOP to it and delete the point attribute N, tangentu and tangentv. This is impotent when working with the copy sop because it tracks the N attribute. I personally like to transfer the real rotation through the copy sop – so deleting is just fine. From this follows a OUT Null to keep things organized and to have always the same node to grap attributes from. Connect the null to the copy sop and do some stamping.

particleShape point(“../OUT_Values”, $PT, Shape,0)

OrientationX point(“../OUT_Values”, $PT, Orientation,0)

OrientationY point(“../OUT_Values”, $PT, Orientation,1)

OrientationZ point(“../OUT_Values”, $PT, Orientation,2)

Scale point(“../OUT_Values”, $PT, Scale,0)

Afterwards stamp the variables in the transform sop. To do so we can use this functions.

RotateX stamp(“../copy_ObjectsToPoints”, “OrientationX”, 0)

RotateY stamp(“../copy_ObjectsToPoints”, “OrientationY”, 0)

RotateZ stamp(“../copy_ObjectsToPoints”, “OrientationZ”, 0)

Unifrom Scale stamp(“../copy_ObjectsToPoints”, “Scale”, 0)

For the correct setup we need to streamline the switch and the shape variable. First get the Shape attribute in place. fit01(rand($PT),0,(opninputs(“../switch1”))) gets the number of imputs of the switch sop. In the switch sop set the item selector to stamp(“../copy_ObjectsToPoints”, “particleShape”, 2). To understand what’s going on go to the geometry spreadsheet. There should be a Shape variable that goes from 0-2, which is the number of elements that are connected to the switch. The switch knows from the copy sops particleShape variable which element to pick.

With all this done we got this result. It is already what I wanted. Control over the object movement and shape. The next step will be the variation of the different channels, to get a more irregular shape.

Before starting to randomize the position we need to store the pointpostion on the curve, as reference point for the rotation manipulation that will follow later. Create an attribute wrangle right after the Point VOP on the right side. type in this code:

vector @PCrv;
@PCrv = @P;

 This will generate a Variable PCrv what represents the curve postion. Following we need a Randomize Attribute VOP to give the points an initial position variance. This looks like this:

Fine. Lets randomize the point position along the u coordinate. There for add a Point VOP after the Randomize Attribute SOP. Dive in and build the setup like this. The setup shown below is just a random vector per point that will be ramped trough the u coordinate of the curve. I have promoted the add2 (Seed), multyply2 (random multiply), mix1 (effect blend) and the ramp.

That’s it for the position. Now let’s create another Point VOP for the rotation. Don’t become scarred it’s not as hard as it seems. We see three sections. A align orientation to curve tangentu section. Here I crate a euler rotation of the tangent vector that can be blended with the original rotation we set in the beginning. The lower part is to set the amount of rotation along the u variable. It is working exactly as in the last Point VOP. In the “Roate_along_CrvP” section I’m rotating the Points and orientations around the curve position point I’ve stored in the Attrib Wrangle earlier. I have promoted degtorad1 (the degrees to rotate), mix1 (blending between tangent vector and init roation), mix2 (effect blend) and the ramp.

Last but not least I have done the same thing for the scaling of the objects. Lay down another Point VOP and setup the network as shown below. I have promoted parm1(Seed), fit1 (size range), mix1 (effect blend) and a ramp

To finish, it is always nice to remove some more attributes that are not used. In the Attribute Delete SOP type in this list “N tangentu u PCrv tangentv”. At the end my tree looked like this.

With the final setup, a movement of many objects would look like this.

As a resume – We saw how to animate objects along a path and control effectively all parameters. For real production purposes it would be necessary to customize everything just a little bit more, depending on the requests of the job.


If you are interested in the setup. Here is a HIP file for Houdini 15. Thanks for reading.

Retime ICE caches


here is a little compound I made to retime ICE caches. The general approach can be found here: It is working so well, that I use this little compound every time I’m doing simulations. Thanks to Andy for this great method!

Download the compound here, import it to ICE, explode it and load the caches. When connecting it to a port on a pointcloud it should work as expected, but if you connect the tree on a polymesh the “Retime Particles Part B” will stay red. This is because there is no changing point count in the cache. So simply dive in and disconnect the delete point node.

Match transfroms in Maya

Currently we are switching our workflows from Softimage to Maya. One small, but essential feature we miss, is the good old match all transforms functionality. This function matches the translation, rotation and transforms from one object to another.

Read More

Make Reset-Nulls


How many times a day do you make reset nulls, to zero out the local values? To me it fells that I’m doing it >30 times a day – So automating this process is essential to speed-up working. Here is a small python script, that makes your day more comfortable.

Usage: Select a Object and run the script. The code will generate a new parent of the object you have selected. With this approach you have zero out all local transforms.

Read More

Getting your cameras right


when we’re animating cameras it’s most of the time needed to change the timing of the camera-move without changing it’s movement. So our approach is to link curves to others. In Softimage this is called link-with, in Maya set-driven-key and in Houdini we can use the function chf. In this tutorial I’ll explain the concept of animating cameras with this principle and how to setup the cameras in the different DCC.

Read More