Houdini Stupid Questions
Sometimes I struggle with stupid stuff, I'll answer to my own questions here. If you're here, you were probably brought in by Google!
I'm still learning as I go so if you see something that's downright wrong or silly, email me! bernie at berniebernie.fr
Jeez I need to sort these
How do I slide a curve along a curve ?
Working on snakes ? If you use carve, you'll notice you end up with weird bits where the tips 'pop', what you would like is to slide the curve along another curve, but smoothly. In comes xyzdist and primuv (check out Toadstorm's page). The advantage is that you will get a real, smooth sliding.
//input 0 is the carved/small curve //input 1 is the full, longer curve i@prim; v@uv; //figure out where i am on the original curve xyzdist(1, @P, @prim,@uv); //animate the uv.x position, blissfully ignore what happens when we arrive at the end of curve @uv.x += (@Time*.1)%1; //move along @P = primuv(1,"P",i@prim,@uv);
How can I carve curves with an attribute ?
The carve sop works great, but afaik you can't use a local variable to carve multiple curves differently short of using a foreach loop.
Thankfully (in more recent versions of houdini?), you can use a prebuilt function found in $HFS/vex/include/groom.h: void adjustPrimLength(const int geo, prim; const float currentlength, targetlength)
In practice it's fairly easy to use!
#include <groom.h> float newperim = @perimeter*sin(@Time+@primnum/3.0)+1; //notice the 3.0 cause' i'm lazy to cast floats adjustPrimLength(0, @primnum, @perimeter, newperim);
Get the end/start points of primitive curves
You can use curveu and fetch 0.0 or 1.0 or use this one-liner
#in a point wrangle i@group_tip = vertexprimindex(0,@vtxnum) == 0; i@group_end = vertexprimindex(0,@vtxnum) == primvertexcount(0,vertexprim(0,@vtxnum))-1;
How do I snap objects to objects
Works in obj mode, not sop mode, use ';' (Orientatio Picking)
Great tutorial here (hipflask) https://www.youtube.com/watch?v=Zh6Q6r9LQlA
Shifting Keyframes in Animation Editor like in Maya
It's a small frustration but to shift frames to later you can write +10 frames But if you want to shift frames to an earlier time you have to use +-10 not -10
How do I scale a packed primitive without unpacking it ?
Code stolen from https://brendandawes.com/blog/scaling-packed-primitives-with-vex-in-houdini
vector scale = ch('newScale'); matrix3 trn = primintrinsic(0, "transform", @primnum); matrix scalem = maketransform(0, 0, {0,0,0}, {0,0,0}, scale, @P); trn *= matrix3(scalem); setprimintrinsic(0, "transform", @primnum, trn);
How do I embed textures in my Houdini .hip file ?
I don't really recommend it, as like the stash SOP it will increase your file size, but sometimes you want no dependencies. I know Rich Lord did something similar in his nifty example files.
Anyhow, the trick I used (there might be an easier method, IDK), is to add null Subnetwork node to my scene then right-click > Digital Asset > Create New but embed it in the current hip file instead of saving it externally.
I right click the asset : Type Properties > Extra Files > Add Textures Files
Then in my SOP nodes or other contexts (in my case a Network Image with a random cat), refer to the image by going to the internal HDA path; in the file browser I got to: opdef:/Object/myEmbeddedHdaName and it shows the images:
How can I rotate a velocity volume/VDB and have it work for advection ?
Thought it would work straight outta the box but I had an issue with a rotated volume, so here's how I fixed it before doing my transform:
(I'm not sure how it works with a normal volume), if you have a vdb you can either use the Primitive Properties then Volumes>VDB>Vector Type set to Displacement/Velocity/Acceleration, or if you're merging vel.* to a single vec3s volume using VDB Vector Merge make sure you set it to Displacement/Velocity/Acceleration here too. You can also use the Labs Transform Properties.
Then do your rotate (or scale) and you will have rotated and scaled velocites (in my example, I'm advecting particles with VDB).
edit: as usual Matt Estela touches on this topic (attribute types) on Tokeru:
How do I work on two objects that don't have the same number of points/prims
Happens to me a lot, you are used to using @ptnum or @elemnum to work on several streams of the same initial object, but in the process you've deleted faces or points and code doesn't work. Thankfully idtoprim and point are fast:
Prior to branching your nodes, set i@id=@elemnum
, then use idtroprim
In the screenshot above, I run code to color my faces if they've been deleted in the second incoming stream
if(idtoprim(1,@id)==-1){ @Cd *= 0; }
How do I export a tracked camera from After Effects to Houdini ?
edit: kinda broken, will try to work on something if i have time
Use this code by Howiem:
H > AE: https://gist.github.com/howiemnet/a3d7b9f283c9227f7fa2f355db89a5cf
AE > H: https://gist.github.com/howiemnet/8784cf04568c849271730965eaf35159
https://www.sidefx.com/forum/topic/53681/?page=1#post-241106
Where can I find all the Houdini Environment Variables ?
Help > About > Show Details
How do I extract the transforms of my rigid body simulation objects ?
Let's say I just want to grab the transforms of my simulation dop opbjects (using points), and reapply them to another object.
I use the intrinsic packedfulltransform
so that I don't have to bother with weird orientations
4@xform = primintrinsic(0, "packedfulltransform", i@ptnum);
Then use Transform By Attribute sop to apply the transform. Will provide screenshots !
How do I transform instance points ?
More than once have I had to copy and move around objects manually but felt that simply merging them was a waste of ressources as it could be a simple instance that is moved around.
It's a pain in the ass though because in SOPs transforms don't seem to apply orient and pscale attributes. So without too much packedtransform trickery à la Matt Estela there is a way to extract transform using, well, extracttransform.
It basically takes an object sitting straight and plump in the center of the world, a second object (sharing the same number of points and the same name attribute) moved and scaled around in the world, and returns a point with the @P, @orient,@pscale
attributes, all you need (with s@instance = "/obj/myPigHead"
)
How do you loop seamlessly using the Carve SOP ?
Using modulo 1, it's easy to keep values between 0 and 1 in the Carve sop, so you can have animation like ( @Time * 0.1 + 0.1) % 1
, however you often end up with a 'jump' when the first U or second U reach 0 or 1. The trick is to toggle on and off the bottom extract parameter so that it reverses the extraction when you have the 'jump':
I used a simple ch('domainu1')>ch('domainu2')
(and switch it around for the second toggle) in the 'Keep Inside' and 'Keep Outside' expressions.
How do I disable / remove pin to animation in Vellum ?
If you use SOP level Vellum, dive inside solver and since I'm not a super big fan of the "vellum constraint property", I use a geometry wrangle to remove the constraint prims:
- set wrangle to primitives
- in the data binding change Geometry to ConstraintGeometry
- add your code, in my example it deletes geometry if frame>35 and the name of the constraint (constraint_tag) corresponds to the one I named in SOPs: pinToAnimationCstr)
Adding a keyframe to a parameter with python
You need to create the keyframe, then set it (bind it) to your parm. The doc is kind of mysterious about it but the easiest way to understand how it works it to call the asCode()
on your parm. I wrote a little snippet to extract code here
Do that by simply dragging and dropping you parm into a python shell and adding asCode after it like so:
And it'll output something along the lines of:
hou_parm = hou_node.parm("camswitch") hou_parm.lock(False) hou_parm.deleteAllKeyframes() hou_parm.set(1) hou_parm.setAutoscope(True) ... ... hou_keyframe = hou.Keyframe() hou_keyframe.setTime(7.958333333333333) hou_keyframe.setValue(3) hou_keyframe.setSlope(0) hou_keyframe.setInSlope(0) hou_keyframe.useSlope(False) hou_keyframe.setAccel(0) hou_keyframe.useAccel(False) hou_keyframe.interpretAccelAsRatio(False) hou_keyframe.setExpression("constant()", hou.exprLanguage.Hscript) hou_parm.setKeyframe(hou_keyframe)
How do I detach a floating window for my parameters
It's a nice feature I like from maya, I can't seem to find it in the vanilla version of houdini however it is written in the docs: https://www.sidefx.com/docs/houdini/hom/hou/Desktop.html#createFloatingPaneTab
You can follow the instructions of Auto Add Frame Offset Parameter to add a custom menu to your gear button (edit parameter interface), but instead of using PARMmenu.xml
you'll have to add it to ParmGearMenu.xml
. I've also noticed that the hscript command menurefresh
doesn't work with refreshing when you are editing your interface. FYI
Frame offset of a file sequence with padding
You need padzero to match the padding of your image sequence like so:
D:/path/to/filesequence.`padzero(4, $F + 10)`.png # at frame 1, returns D:/path/to/filesequence.0011.png
However, having it done so many times, I added a small tool to my inventory: Auto Add Frame Offset Parameter
How do I view all Houdini icons ?
19.5 update: broken ? Will investigate later.
So you want a pretty icon for your awesome HDA ? You can open up the help file and replace whatever is there by /icons. It will load page with all available .svg icons.
It is super slow to load though (extracting from a zip ? using a raspberry pi to host the help server?) so if you plan to do it more than once I recommend opening it up in your browser and saving the page locally.
Once you've found your icon hover over it to find the name and you can put it in the icon field of your HDA by using CATEGORY_iconname
so in my screenshot it would be BUTTONS_bundle_set_selected
How do I add a custom OTL/HDA directory
I like to keep experimental HDAs in a folder that I can share across using google drive / dropbox/ whatever. I'm not super fond of the packages/env handling as I feel it's confusing for now but anyhow.
This adds to $HOUDINI_OTLSCAN_PATH
add to a json file in your packages folder
{ "env": [ { "HOUDINI_OTLSCAN_PATH": "G:/My Drive/OTL" }, ] }
Solo toggling a light in the IPR View ?
#place in a shelf with a shortcut, I chose Ctrl-Alt-s as it was free. Works with Arnold #hit it a second time to remove the solo light ipr = next(x for x in hou.ui.currentPaneTabs() if x.type().name() == 'IPRViewer') soloParm = ipr.ropNode().parm('sololight') if soloParm.eval() != '': soloParm.set('') else: soloParm.set(" ".join([n.path() for n in hou.selectedNodes()]))
How do I layout nodes nicely ?
- A + drag in a direction with mouse: align nodes
- shift + drag node: move all nodes above current selected one
- ctrl + drag node: move nodes below
How do I change a transforms rotation axis easily in the viewport?
Can't be done 'easily' AFAIK, you can however right click the manipulator tool to change axis pivots
How do i bake cameras in houdini
If you need keyframes, i recommend doing the easier bakeanimation way. Create a ropnet, add a bake animation, fetch source and target and hit render
But using CHOPs
- in a chop network, drop down an object node, grab your object that has parents or whatever as target object, nothing as reference object, and full transform or rotation and scale
- connect to the output an export node, choose your object to bake to, and in the path add t[xyz] r[xyz]
- click the 2nd button of export node (orange 'export' button) and it will connect the chop to your target object (channels will be orange)
- or use `chop('path/to/chop/channelx')` to fetch chop
- Right click your parm,
Keyframes>Bake Keyframes
(I almost always useOverride Range from Selected Segments
andBake, Disable Export Flags
)
How do I copy 'stamp' different objects with Copy to Points
I kind of brute-forced each time with a foreach loop but I'm a big dummy apparently all you need to do is have the same variable (a random int from 0
to number of objects - 1
) on your 2nd input as it is on the copy to points Sop 'Piece Attribute' which defaults to @name
.
How do I rotate around an axis when using copy to points
Matt Estela has thorough explanations which I need to read each time I do this. Olivier Jeannel has video where he does it in VOPs
For simple stuff you can often use @N and @up, but there's more control in using a quaternion @orient attribute:
Setting up the orient to match what you would do with @N and @up:
@orient = quaternion(maketransform(@N,@up));
Rotating around an axis at a certain angle (in degrees):
vector axis = chv('axis'); float angle = radians(ch('angle')); vector4 q = quaternion(angle, axis); @orient = qmultiply(@orient,q);
You can cumulate orient transforms:
TBD: doing it by moving @P (ie without copytopoints)
How do I pin an object to an another in Geometry/SOP context ?
- (use point deform with a single point?)
- probably xyzdistance i'll write about it later: http://www.toadstorm.com/blog/?p=465
How do I get the start/end frame of an alembic read in python?
from _alembic_hom_extensions import alembicTimeRange as abctr startFrame,endFrame = abctr('F:/filepathto/alembic.abc') print startFrame,endFrame
Why doesn't my grain wire solve work?
Check that you have:
- @restlength on the curves (prims)
- in the dopnetwork, Emission type: All Geometry
- each point needs to have @targetstiffness and an attr to drive the 'animated' point (@targetweight for instance) -- then in a pop wrangle:
if (@targetweight==1) { v@targetP=point(0,'P',@id); }
Why does my RBD bullet sim jump/explode on first frame
- Sometimes due to interpenetration solving. Make sure nothing collides before hand (duh). Usually inter-penetration solving 'spreads' Objects around, but the sim shouldn't explode
- I've also found out that if I use a random 'orientation' attribute it goes to shit, instead I use 'rot'
- If I use orientation (vec4) to setup randomness of objects, make sure the attribute is deleted if you copy pack&instance (ie: attr rand (orient) > copy to points (pack&instance) > delete attr (orient)) because the orientation is already stored in the packed intrinsics.
- Sometimes tiny masses will also make the objects skittish, also built-in drag/airresist sometimes goes to Inf or -Inf energy == shit
Edit: More reasons/details
- NaNs in sims can apparently cause this. Make sure you're not using airresist/popwind (perhaps this is broken on my side at work)which seems to fuck up a lot of things.
How do I scale manipulators viewport size (like +/- in maya)?
/ and * (be warned that + and - change smooth mesh preview like 1 and 3 in maya)
How do I scale uniformely using the gizmo ?
- http://www.sidefx.com/docs/houdini/basics/handles.html
- basically, moving an arrowhead scales uniformely, moving the rest of the handles scales non-uniformely
How do I interpolate motion between still frames
I might be missing something super simple because this seems unreasonably complicated
edit: I was probably missing the simple Timeblend node. I'll leave this up; who knows.
- The trick is to use floor($FF) in the timeshift rather than $F otherwise you get frame jumps on half-frames
- So 1 timeshift with floor($FF), one with floor($FF)+1, plus a blendshape with $FF-floor($FF)
Slightly more complex example where I had objects not necessarily sharing the same ptnum (but with a unique Id attribute) -- and a need to lerp orients too
int pt = findattribval(1, "point", "id", @id); i@id2 = pt; if(pt == -1){ @Cd = {1,0,0}; }else{ vector p2 = point(1,"P",pt); vector4 orient = point(1,"orient",pt); @P = lerp(@P,p2,@Frame%1); @orient = lerp(@orient,orient,@Frame%1); @Cd = @Cd; }
How do I instance a node (reference copy)
- ctrl-shift-alt drag nodes
Improve VDB viewport resolution
Volume visualization, even at maximum viewport resolution won't give a nice viewport display if your vdbs are very sparse ('pockets' of volumes). So, for preview purposes you can use 'VDB Segment by Connectivity' to re-split the vdb into smaller vdbs which will display properly (be warned that this can slow things down to a crawl)
In my case I toggled off 'use color' and 'append names' so that my volume visualization color still works. Also you can turn off 'smooth wire shaded' to remove bounding boxes. And if you're happy with the preview, Flipbook==Approved Render :D
How do I combine (easily) loads of vdbs
Thanks to esteemed friend&colleague Charles
- Make sure 'Flatten all B into A is on and your vdb (source A) is the same rez
How do I activate/fill vdbs cells (voxels)
Sometimes you need to fill your volume vdb with empty data to do stuff with it.
- Use vdb activate on itself to 'fill up', uncheck use value
How do I cleanly retrieve vertex info to point (like laying layout UVs in world space)
- Use vertex split ! https://www.youtube.com/watch?v=F2pwzyQ1oc4
How do I timestamp my outputs
You can use the a houdini variable: `strreplace(strreplace($_HIP_SAVETIME,':','-'),' ','_')`
Or you can go dirty with sytem calls, on windows and my locale (france) the following works:
`system("cmd /C echo %date:~6,4%%date:~3,2%%date:~0,2%")` //evaluates to 20200917 for today the 17 of september 2020
More modern python, works as a multiline expression if you have the return statement:
import time;return time.strftime("%Y-%m-%d_%Hh%M") #returns: 2022-09-08_13h29
How do I get pre and post infinity animation with keyframes
- In the Animation Editor, pick channels and Alt-E (channel properties):
How do I refer to a relative SOP in vex
The syntax can be confusing, but I think this works, when using the 'point' (or similar) functions. You must have a string with op in it: "op:chs('parm')"
Rounding numbers in Vex
Is really annoying. Save yourself the trouble and worst case use pythonexpression. Floating point issues, sprintf doesn't really want to work as it seems. Anyways:
//before, shows 1.610000000000000001 or simila //after, shows 1.61 `pythonexprs("'%0.2f' % " + ch("../parameter"))`
Creating a linear pre-roll
Freeze the two first frames of animation and interpolate to get your pre-roll. Volume (rotations) are lost but I'm not smart enough to do non-linear interpolation yet.
Exporting Houdini instances to Maya (via particles)
Fuck this shit. It can't be done. I lost two days of my life, I'll post back if I manage it but maya is a fucking nightmare and its low price is the only thing keeping people from buying Houdini.
Posting my research if another poor soul has to do this. We wanted to take instanced animation from H to maya keeping rotation and scale
First, here's things I haven't tried
- using H engine in maya. Way too expensive to put on the farm.
- Using Filmbox Crate .abc importer/exporter to get point info in maya. My colleagues don't seem to have gone far with it.
- Using old weird bgeoclassic importer.
What seemed to work was using MASH instancing BUT
- Using face instancing (distribution) seems to euler flip. (ie exporting thousands of simple triangles from Houdini). Scale works fine. Tried LOADs of combinations.
- Using edge instancing (distributions) seems to keep rotation fine (if you have a houdini triangle that fits the requirements -- and skip one out of 3 edges, ie instance nulls). Scaling only works in one axis.
It's 2018 2019 2020 Autodesk. Step up your fucking game.
Motion blur on changing topology from Houdini to Maya and Redshift
It's not clear from the doc. If you have a flip sim or something funky that changes at each frame, here's how to get velocity showing up in Redshift from Maya:
/!\ We had a pretty nasty bug (crashes) with redshift when using end-of-frame motion blur instead of center-of-frame.
In Houdini:
- change your v to Cd (from what I gather it needs to be a vector with R,G,B not X,Y,Z or 0,1,2) using a wrangle
- Promote Cd to vertices
- Change its name (optional, I chose myVel in examples) delete original v (optional)
- Export with alembic ROP (no need to turn on 'motion blur')
In Maya:
- Import abc cache (optional: lament on how unstable maya is when you reload an .abc cache). If your mesh comes in coloured it's a good sign.
- In the shape attributes of your abc, choose the vertex color attribute from Houdini for velocity
- Make sure your have moblur turned on in your render options and you should be good !