Instance/copy objects with nulls

Hey there,

when dealing with real commercial productions it is, at some point, necessary to place object instances by hand. There for you have four options in Softimage.

  1. A hard copy of the object
  2. A clone of the object
  3. Put it in a Model and use an model instance
  4. Use ICE to distribute instances in combination with Nulls that have an PPG with an integer attribute to detect the instance.

Point four is the workflow I like the most, because it is super flexible. After the placement it is possible to change all attributes e.g. with a random size or position. Now the question is, how do I adapt my known workflow to Houdini? Exact the same way I do it in SI. Fist we need to create a null object with an integer attribute “instNR” for instance number, some instances and a geometry that holds the geometry.

Lets dive into geometry level. First I have tried to build a setup the classical way. With maaaany attribute create sops. 

“Going from top to bottom you see that I create all attributes I need to transfer the data from the null objects: i@instNR, f@pscale, v@scale, v@euler_rot, 4f@orient. In the point vop I convert the euler rotation to a quaternion rotation. This is needed because the copy sop is using quaternions. With the path attribute of the object_merge sop we can access all attributes like this: ch(@objname + “/../instNR”). The only attribute we have to samp is the Instance Number. The syntax in the copy sop is like this: point(“../Input_GEO_OUT1”, $PT, “pinstNR”, 0). The switch node can now access this attribute like this: stamp(“../copy_InstancesToPoints”, “pinstNR”, 0). This is all we need to get it working.

Much slicker is to do all attribute manipulation in an attribute wrangle.

That’s all. Easy to setup and effective. The only thing to notice here is, that this is a copy NOT a instance workflow. To really instance objects I recommend this tutorial. https://vimeo.com/55292609 this workflows here can easily combined with this workflow. Here InstanceObjectsWithNulls you can download the example hip file.

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.

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.