Search form

'The Magic of Houdini': Reuse and Recycle -- Use the POP Solver

In VFXWorld's latest excerpt from The Magic of Houdini, Will Cunningham helps readers solve the mystery of using solver tools.

All images from The Magic of Houdini by Will Cunningham. Reprinted with permission.

This is the next in a series of excerpts from the Thomson Course Technology book The Magic of Houdini by Will Cunningham. In the next few months, VFXWorld readers will learn the basics of the dominant tool that has been used in the creation of some of the most awe-inspiring animation and cinematic effects ever made.

Behold! You have just scratched the surface of the solver iceberg for there are numerous other options available. Things can start to get a little abstract from this point forward, but you've made it this far so you should be fine. At this point, the concept of a solver gets broadened a bit. They no longer strictly refer to a completely contained system designed to emulate physics. A solver now becomes a tool to run against objects to which it is bound. Some of the following solvers are merely frameworks in which you can build your own simulations. Some of these solvers have very light demands upon the system and they don't require or care much about the subdata that gets acquired in a system.

You have invested a goodly bit of time in coming to grok the various tools available in POPs. If it ever seemed redundant to have two simulation contexts with similar, but different, ranges of operators, you will be happy to know that you can reuse and recycle all the utility of POPs inside of DOPs using the POP solver. The POP solver will execute a selected POP network for any dobject to which it is applied. This will let you generate particles during the DOPs simulation and use them for collisions against dobjects.

1. Start up a new session of Houdini and drop a Geometry object. Jump into it and drop a Grid and change the Orientation to XY. At this level, drop a DOP network and jump into it.

2. Bring in the grid using a Cloth Object DOP.

3. Append the diligent duo of Gravity and then a Cloth Solver DOP.

4. Let's pin down the top two corners. Append a Cloth Constraint DOP and set the Object Location to 0.5, 0.5, 0. Append another to constraint and set it to -0.5, 0.5, 0.

5. Play the simulation and you have a hanging piece of cloth.

6. At this level, drop a POP network and jump into it. Create a Location POP and set the Coordinates to 0, 0, 2. Go to the Attribute tab and set Velocity to 0, 0, -2 and set Variance to 0.1, 0.1, 0.1. This creates a stream of spewing particles.

7. Jump back up to DOPs and create an unconnected POP Object DOP. This creates an empty dobject into which the POP solver can dump its particles. The reason for not just using a regular Empty Object DOP is the same reason why you use one for the RBD, cloth or wire dobjects. The POP Object operator will initialize and add some very useful subdata. It can also help you set up some useful physical parameters for when the particles are causing collisions against other DOPs entities.

8. Append a POP Solver to the popobject node and point it to the popnet you just created.

9. Use a Merge to bring in the popsolver first, followed by the last clothconstraint node. The network should look like Figure 1. Play the simulation and the particles fly across and collide with the cloth dobject causing it to sway, as shown in Figure 2. It's the same kind of feel as using a water hose to spray the laundry on the line in the backyard.

[Figures 1 and 2] The DOP network using particles (left). Spray that stinky shirt down (right).

The Power of Feedback -- The SOP Solver

The SOP Solver is designed to let you run off to SOPs and modify each object to which this solver subdata is bound at every time-step of the simulation. What is so terribly special and exciting about that? The cloth and wire solvers push geometry around, but this one allows you to do whatever you like to the input geometry and feed it back into the simulation loop. For example, you could deform or decimate objects progressively through time. And that truly is, terribly cool.

1. Start up a new session of Houdini and drop a Geometry object. Drop a spanky new Grid. Drop a DOP network next to it and jump inside.

2. Import the grid with an RBD Object DOP.

3. Append a SOP Solver DOP. It wants a SOP Path so that it can execute whichever node is pointed to and it does this for every object you've attached this Solver to. If it points to a SOP network, it will execute whichever node has the Display flag set, in the usual manner you have seen in other fields referencing SOPs.

4. Create a SOP network and drop it off to the side. In the sopsolver node, point the SOP Path to the new network.

  • 5. Jump into sopnet1. This is where you are going to manipulate the geometry for each object in DOPs. Hmmm, now where do you get that geometry from? How do you usually fetch geometry from other networks? Yes, the Object Merge SOP is the answer. Create one of these and prepare for a little kung fu hustle, which will become clearer as you explore the freedom of data within DOPs. For now, close your eyes and enter '"../..:"+stamp("..", "OBJID", 0)+"/Geometry"' in the Object 1 field. The grid geometry should appear. What have you done? Basically, you have pointed the Object Merge to the Geometry subdata of a certain object in the parent DOP network, which you referred to by its ID instead of its name. Note that you can indeed refer to a name, but it's easier to extract the ID. Some information owned by the DOP network (referred to by the ../..) is able to be yanked out using the stamp() and stamps() expressions and so here you are just grabbing the OBJID from the dopnet. The plus operators merge the different string parts of the expression together. This string concatenation, common in many programming languages, is borrowed nicely in Houdini expressions.

6. Append a SoftPeak SOP and you are going to set it up so that one random point get pushed a little bit along the normal of the surface. To grab a random point, enter 'int(rand($T)*npoints("../"+opinput(".",0)))" in the Group field of this node. This translates to "Generate an integer from a random number (based on time), which can be as high as the number of points that exist in the SOP that's wired into my (first) input." The backticks are needed to evaluate the expression inside a string field. Enter 0.1 in the Distance field and jump back up to the DOP network.

7. To be thorough, bypass and un-bypass the sopsolver node. This will force a re-cook because with some of the more delicate DOPs can be overly cautious in cooking in order to avoid errant feedback. Forcing a re-cook like this becomes a bit of a ritual but it is much better than feedback DOPs being over-cooked and causing Houdini to explode into a zajillion bytes. Press Play and yee haa! Look at that there grid get'n all banged up! The sop network is being fed back into the simulation and is so getting dented over and over. See Figure 3.

[Figure 3] A grid getting progressively mangled by way of the SOP solver.

Notice how if you let it play for a while that the primitives get all horribly distended and it stops looking so interesting. Wouldn't it be a nice touch to further refine those areas that get too stretched? So how might you do this? You would want to find out the areas of the primitives and then subdivide those primitives that get larger than a certain size.

8. Jump back into the SOP network doing the damage, which is likely sopnet1.

9. Append a Measure SOP and set the Type to Area. This creates a primitive attribute that contains the value of a particular primitive's area.

10. Append a Group SOP and set the Group Name to be refineme. Enable the Number option and change the Operation to be Group By Expression. Enter $AREA > 0.015 in the Filter Expression field. This evaluates the expression for every primitive and asks whether each of their areas (as stored in the area primitive attribute) is greater than 0.015. If so, it evaluates to one and that primitive is part of the refineme group. If not, it evaluates to zero and that primitive is not a part of the group.

11. Append a Subdivide SOP and set the Group field to refineme. This should refine all primitive whose area is greater than 0.015.

[Figures 4 and 5] The grid getting mangled in more detail (left). The SOP network -- the madness behind the mangle (right).

12. Append a Group SOP and, if necessary, switch off the Enable toggle under the Number radio button. Switch to the Edit tab. At the bottom, enter the refineme group in the Delete Group field. Why do this? You must clean up after yourself not only to be polite but also because, at the next time-step, the Group SOP above that creates the refineme group will error out because it will find that the refineme group already exists. This is a very important thing to realize when you are creating a recursive system. You have to be very careful and be as "respectful" as possible to the geometry that you are going to hand over for recursion. Also, keep in mind that it is possible that some other solver could get a hold of the geometry and do something with it you that you have no control over. The phrase is "program defensively" and the same thing applies to any closed system you build.

13. Jump back up to DOPs and do the force re-cook trick at frame 1 and then play the simulation. The grid gets more detail as it goes on its merry way. The value of this system is evident as it could be used to modify geometry as RBD dobjects collide. Twist stuff, bend stuff, decimate stuff, your imagination is the limit.

14. There is one small improvement you could make before moving on. Jump back into the sopnet and move the softpeak node to the bottom of the chain. The reason is that you will get slightly softer and nicer bulges by pushing the point after the subdivision. Figure 4 shows the result of this smoother deformation. The SOP network should look like Figure 5.

Find out more about how to apply each of Houdini's features to your projects as you take on modeling, character animation, particle effects animation, dynamic simulation animation, shading, digital asset creation and rendering. The Magic of Houdini by Will Cunninham. Boston, MA: Thomson Course Technology, 2006. 355 pages with illustrations. ISBN: 1-59863-082-2 ($49.95). Check back to VFXWorld frequently to read new excerpts.

Will Cunningham began his trek by studying both traditional art subjects and 3D computer software at the Academy of Entertainment and Technology. After his studies, he was hired as a Houdini technical intern by Side Effects, the developers of the Houdini software package. Eager to create effects for the big screen, he then jumped into production with BlackBox Digital on the feature,

The Prince and Me. Shortly thereafter, he also began teaching Introduction to Houdini at the Academy and has since taught both the introductory and intermediate Houdini courses. In the fall of 2004, he was awarded a fellowship grant by Santa Monica College to support his efforts in creating this book. Over the years, he has worked for a number of production studios on a variety of projects, including The Chronicles of Narnia: The Lion, the Witch and the Wardrobe, Open Season and Ghost Rider. Currently, he is enjoying effects challenges and learning opportunities at Sony Pictures Imageworks.