⭐ I also have saved some useful snippets as gists
A rough list of some free, some paid, useful HDAs and tool sets
- Lucas Scheller LYNX fabric/weave HDAs https://www.lucascheller.de/posts/ecae2c0393b0980c5c909b5060fdc1a3/
- OD tools https://origamidigital.com/cart/index.php?route=product/product&path=59_63&product_id=64
For example a camera from Maya needs to be rescaled from meters to cm for houdini
This could have adverse effects, in mantra for example (maybe no longer) scaling the actual camera object by 0.01
the exposure is also scaled, so instead you can just fetch
and blend
padzero(4, $F4-1000)
A good way (showed to me by Mark J) to get the maximum value of a specific attribute is to use attribute promote
SOP and promote to detail
based on maximum
Use extract transform
and transform pieces
SOPs to 'stick' additional geometry to somewhere on a deforming geo.
The setup can be confusing but it works like this:
Extract Transform
wants:
- input 1: rest point
- input 2: deformed/animated point
Transform Pieces
wants:
- input 1: geo to deform IN situ of rest point
- input 2: extracted transform point
as an expression
fit(@Frame, 1001, 1101, 0, 360)
In camera background for example
$JOB/MySequence.`padzero(4, $F4-1000)`.jpg
Just watch these Sidefx tutorials by Michael Goldfarb
- Scripts are included on the sidefx page
- watch the series 1 playlist
- series 2 is one big video that coves deformation
✔️ Watch on youtube instead of vimeo, better player, supports resuming.
The SideFX rigging tutorials have lots of useful tips on how to create, and manage HDAs
Turning on the asset definitions toolbar is useful for to see the version of a HDA in your scene (toolbar appears at top of parameters window) Assets Toolbar > Asset Manager... > Configuration tab > Asset Bar switch dropdown menu to 'Display Menu of All Definitions' Enable asset bar to show versions
This is detailed in the help, but briefly:
- On a param's 'Callback Script' setting, add callback code like
hou.pwd().hm().my_function(kwargs)
- Then in the scripts tab, add a
PythonModule
- Then add the function with kwargs argument
- If the param was a menu for example,
script_value0
returns the item selected in the dropdown
- If the param was a menu for example,
def my_function(kwargs):
this_node = kwargs['node']
selection_value = kwargs['script_value0']
If there is a cog button to press such as this example from the deadline submitter node, you can acccess the python module in the HDA like this:
It's useful to pass kwargs along too
kwargs['node'].hdaModule().myfunction(kwargs)
To set a HDA's initial look, add a OnCreated
python script in scripts tab. The following code sets the shape as 'clipped_left' and to some blueish colour.
kwargs['node'].setUserData('nodeshape', 'clipped_left')
kwargs['node'].setColor(hou.Color(0.175, 0.3, 0.35))
If it is a material, it is useful to set the material flag
kwargs['node'].setMaterialFlag(True)
Set focus from object (null), this expression gets distance between origins of two objects
vlength(vtorigin(".","../focus"))
- Clear simple quick video about using the retopo tool !
- As of H18 - always set substeps to at least 5, fixes initial stretching - then consider reducing collision passes.
- Really useful section of Sidefx Jeff Laits vellum cloth tutorial, he shows a (complicated!) way to extract the holes after using create planar patch
- Help initially intersecting collisions
- Un-pin using @stopped attribute (vellum H17)
- stiffness dropoff
Print a list of all materials attributes assigned on a selected node. Made this as I wanted a list to be able to pick materials to override in a redshift proxy!
for n in hou.selectedNodes():
g = n.geometry()
a = g.findPrimAttrib('shop_materialpath')
materials = a.strings()
for m in materials:
print(m)
Check if in UI mode, ie. disable popups or enable things only when rendering
hou.isUIAvailable()
Create null
objects from transform SOPs
.
This can be useful to re-create transforms at object level instead of 'deforming' geometry which is much heavier.
def nulls_from_x():
for node in hou.selectedNodes():
print(node.name())
t = node.parmTuple('t').eval()
r = node.parmTuple('r').eval()
s = node.parmTuple('s').eval()
scale = node.parm('scale').eval()
new_null = hou.node('obj/').createNode('null')
new_null.parmTuple('t').set(t)
new_null.parmTuple('r').set(r)
new_null.parmTuple('s').set(s)
new_null.parm('scale').set(scale)
// get nearest point index of second input
int np = nearpoint(1, @P);
// get that point's position
vector np_pos = point(1, 'P', np);
// measure distance
float dist = distance(@P, np_pos);
// normalise distance
dist = fit(dist, ch('in_min'), ch('in_max'), ch('out_min'), ch('out_max'));
// remap with ramp
dist = chramp('remap', dist);
// set attribute
f@dist = dist;
// get centroid
vector min, max;
getbbox(min, max);
vector centroid = (min+max)/2;
vector axis = {0, 1, 0};
vector2 u = rand(@class);
vector direction = sample_direction_cone(axis, radians(ch("angle")), u);
On a prim wrangle!
addpoint(0, @P);
removeprim(0, @primnum, 1);
int posprim;
vector param_uv;
float maxdist = 1;
float dist = xyzdist(1, @P, posprim, param_uv, maxdist);
// if you needed to store the position / primuv
i@posprim = posprim;
v@param_uv = param_uv;
float dist_ramped = chramp('distance', dist);
// create angle from dist ramp
float angle = chf('angle') * dist_ramped;
// get current packed transform
matrix packed_transform = getpackedtransform(0, @primnum);
// matrix to transform by
matrix transform = ident();
rotate(transform, radians(angle), normalize(chv('axis')));
// set transform
setpackedtransform(0, @primnum, transform * packed_transform);
Based on [[http://www.tokeru.com/cgwiki/?title=Houdini#Transform_packed_prims_with_instance_attributes|cgwiki]]!
in a primitive wrangle sop
// instead of creating a new transform, use the current one
//matrix3 m = ident();
matrix3 m = primintrinsic(0, "transform", @primnum);
float angle = @Time*10;
// rotate around up
vector axis = {0,1,0};
// vector axis = primintrinsic(0, "transform", @primnum);
// rotate
rotate(m, angle, axis);
// set the attribute
setprimintrinsic(0, "transform", @primnum, m);
Not well documented, how to enable console log
# Toggle Redshift console log
hou.hscript("Redshift_setLogLevel -L 5")
# Set log level
hou.hscript("Redshift_switchConsoleLog")
Useful big save on caching to disk is just saving the points from a RBD solver. But this often doesn't work how you would expect.
This example works, had problems with using the rbd input or configure geo, but the first frame of the solver works fine - inside the rbd solver SOP it is actually using transform pieces for the first output...