Retiming Houdini caches with changing point counts

Hey all there,

when it comes to do fluid simulations in Houdini it is often necessary to be able to re-time the caches after the simulation. In principle that is not a big deal – just an interpolation between two frames. It gets a little harder if we have a constant emission which leads to a changing point count. In this case we have to build a setup like this.

First we start with a Null that gets three float Parameters as a input (Current Frame, Frame A and Frame B). The Current Frame should have an Animation on it, and the two others get a nice little Python snippet:

Frame A

import math
FrameA = ch(“CurrentFrame”)
return math.floor(FrameA)

Frame B

import math
FrameB = ch(“CurrentFrame”)
return math.ceil(FrameB)

Next lay down two File nodes and input the simulation.



With this done we’ll always get the Current Frame and the next frame as inputs. An example would be: Current Frame 55.8 => Would be Frame A = 55 and Frame B = 56. Since the Frame A always has the lower point count we need to make an detail attribute “nptA”, that holds the point count of Frame A. With the help of an attribute transfer we can copy the detail attribute to the Frame B stream. In the delete sop that follows the attrib transfer we throw away all the new points of Frame B, so that we can interpolate the Points of Frame A with Frame B. There for use this little expression $PT >= @nptA.

The logic happens now in the pointvop. Connect the two streams and create two parameters: A velocity mulitply and a attribute blend float. On sop level the attribute blend parameter gets this expression: ch(“../Time/CurrentFrame”) – ch(“../Time/FrameA”) the result is always a blend value between 0-1, that we can use for mixing values in the point vop. The velocity muliply parameter gets this expression: chf(“../Time/CurrentFrame”, $F + 1) – ch(“../Time/CurrentFrame”) the result is a the difference between the Current Frame  (of the Time Null) and the next Value on the fcurve of this parameter. I do that to make sure that the velocity scales proportional to the retiming curve. The nodes of the pointvop are just some mixing and binding. Note: If you have other attributes that you want to interpolate just also import them for the two streams and blend them. Yeah!

When this is done we have to care about the other new points that will be born on Frame B. Because I have no information when the Particles where born between the two frames I add them randomly over the animation time with the now expression. @randomDEL > ch(“../Time/CurrentFrame”) – ch(“../Time/FrameA”) Check my post if you want to now more about how you do a “Test Random Propability in Houdini)

The rest is just merging and cleanup. A last quick node. If you use the fluid compress node in combination with a compressed bgeo file it can happen, that the point index changes from frame to frame. This leads to an improper blending.

I hope you like my solution. If you have questions or acknowledgements, please drop me a line.

Spherify in Houdini

Hey there,

today I had the case that I wanted to spherify a cube in Houdini. So far no problem – a box, for loop, smooth and a ray node. ready. Cool! Max users have this feature since decades, in Softimage I was always used to a great deformer called ooSpherify, that deforms any object into a sphere. But in Houdini there is no slick way to do that. As a result I transferred the logic of the ICE compound to Houdini.

There are three big sections: 1. Calculating the center 2. Measure the length to the center 3. Add values to the point position. Now we have just a singe point vop in place of a loop network. Further more, we need no extra Sphere to shrink wrap the cube to.


Here you can download the example hip file.

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.