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.

$HIP/geo/SimulationTest.filecache1.`ch(“../Time/FrameA”)`.bgeo

$HIP/geo/SimulationTest.filecache1.`ch(“../Time/FrameB”)`.bgeo

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.

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:

 

Client
Product
Agency
Production
Post

Procter & Gamble
Dash 2 in 1
Grey
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.