Custom VEX functions

I store them here, on Windows:

I include them in a wrangle like this:
#include "qq.vfl"

Here is the content of the qq.vfl:

void clamp01(float value)
    value = clamp(value,0,1);    

float falloff_linear(vector sample_pos, from, to) //unclamped
    vector u = normalize(to - from);
    vector v = sample_pos - from;

    float eval = dot(u,v) / length(to - from);
    return eval;

float falloff_radial(vector sample_pos, center, radius) //unclamped
    float max = length(radius - center);
    float eval = length(sample_pos - center) / max;
    return eval;

vector farthest_point_position(vector from) //run over detail of input 0
    int count = npoints(0);
    float maxdist = 0;
    vector eval;

    for (int pt = 0; pt < count; pt++)
        vector sample_pos = point(0,"P",pt);
        float distance = length(sample_pos - from);
        if (distance > maxdist)    
            maxdist = distance;
            eval = sample_pos;
    return eval;

vector farthest_point_distance(vector from) //pointcloud of input 0
    int maxpts = npoints(0);
    int handle = pcopen(0, "P", from, radius, maxpts);
    float eval = pcfarthest(handle);
    return eval;

 void bounding_vector (vector direction_from, direction_to, result_from, result_to) //run over detail of input 0
    vector u, v, pos, center;
    float distance, mindist, maxdist;
    int count = npoints(0);

    u = normalize(direction_to - direction_from);
    mindist = 1e10;
    maxdist = -1e10;

    for (int pt = 0; pt < count; pt++)
        pos = point(0,"P",pt);
        v = pos - direction_from;
        distance = dot(u,v);

        maxdist = max(distance, maxdist);
        mindist = min(distance, mindist);

    v = getbbox_center(0) - direction_from;
    center = dot(u,v);

    result_to = (maxdist - center) * u + getbbox_center(0) ;
    result_from = (mindist - center) * u + getbbox_center(0) ;

float float_hittest(float try, stored, maxdist) //clamped
    float eval, trywide;
    trywide = fit01(try, -maxdist , 1+maxdist);

    if ( maxdist>0 )
        float omin = stored - maxdist;
        float omax = stored + maxdist;
        eval = fit(trywide, omin, omax, 0, 1);
    } else {
        if ( trywide > stored )
            eval = 1;
        } else {
            eval = 0;

    return eval;


toolset: generate animation channels from notes (music) work in progress

Little vex/python toolset to generate animation from ♪♫ notes.

For now, the notes can be
– added manually
– generated from tuples (python)

Next step is to
– implement MIDI import
– implement MIDI velocities

Please, I have to decide which software should I buy and learn, to edit MIDI.
Should I buy Ableton? It also has nice “Audio to MIDI” feature.

Comments are REALLY highly welcome, especially from anyone who does music. The tool is intended to be free for anybody. Download link is here. But it really is under development, so excuse the “fragile construction”.

Object Merge SOP, new node references the selection

# define
offsetx = 3
offsety = 0
color = hou.Color(0.0, 0.0, 0.0)

node_src = hou.selectedNodes()[0]
name_src =
name_src = name_src.split("_")[-1]

posx = node_src.position()[0] + offsetx
posy = node_src.position()[1] + offsety

#create, name, pos
container = node_src.parent().path()
name_mrg = "IN_" + name_src
node_mrg = hou.node(container).createNode('object_merge',name_mrg)
node_mrg.setPosition( [posx,posy] )

path_src = node_src.path()
parm = node_mrg.parm("objpath1")



Toolset: “code shortcuts” into “vex snippets” and interface update (chf, chi, chramp) from comments

I did a little python toolset to speed up my VEX writing. It replaces “code shortcuts” into “code snippets” and also updates the parm interface (default values, channel ranges from comments, ramps are generated from custom library). You can build your own libraries of snippets with specific channel ranges and defaults.

All the information and source files are stored here, on odforce.

The initial idea comes from here, Matt Estela.

Network Editor, Layout 1%

Another bit, recursive search through all connected nodes. Later I will layout these connected “trees” nicely. Cameras, Lights, ROPs into specific locations.

Inside SOP Geo nodes, I also like to have multiple separate trees (multiple OUT… / Object Merge… / OUT… / Object Merge / OUT…) so I will layout those trees automatically in logical order of dependencies, left to right.

def getConnectedNodes(node,got):
    iteration = []

    inout = []
    inout += node.inputs()    
    inout += node.outputs()
    for n in inout:
        if n not in got:
            iteration += getConnectedNodes(n,got)

    return iteration

selection = hou.selectedNodes()[0]
allConnected = []
allConnected = getConnectedNodes(selection,allConnected)

This is just the beginning of the journey! I like the new “Layout All” system in H16, hotkey L or Shift-L for selected nodes. It behaves quite logically, 99% times I can rely on automatic layout. The remaining 1% I will solve by python script.

This small part takes all the Chopnets and positions them beside their appropriate Channel SOPs. Naming convention has to be maintained. To be continued.

# define offset
offsetx = 3;
offsety = 0;

import hou
import toolutils

# container path
active_pane = toolutils.activePane(kwargs)
if active_pane is not None and active_pane.type() == hou.paneTabType.NetworkEditor:
    containerpath = active_pane.pwd().path()

# find all chopnets
chopnets = hou.node(containerpath).glob("chopnet_*")

# for all
for ch in chopnets:
    xxx,task ="_")
    # appropriate channel node
    path_channel = containerpath + "/channel_" + task
    path_chopnet = containerpath + "/chopnet_" + task
    node_channel = hou.node(path_channel)
    node_chopnet = hou.node(path_chopnet)    
    # get
    posx = node_channel.position()[0] + offsetx
    posy = node_channel.position()[1] + offsety

    # set
    node_chopnet.setPosition( [posx,posy] )


Little Python Shelf Tools

I have few little python snippets like this, in a shelf. Some of them bound to hotkeys. Btw with the Autohotkey, you can also remap to any Key + Scroll wheel. Thanks goes to the community. I did not built those scripts from scratch, other smart people did (graham, galagast, mestela, and others).

Toggle manual / auto update

Thanks to berniebernie!

import hou
mode = hou.updateModeSetting().name()
if mode == 'AutoUpdate':
if mode == 'Manual':

Activate OpenCL on all subchildren

for node in hou.selectedNodes():
    for subnode in node.allSubChildren():
        for p in subnode.parms():
                except hou.PermissionError: 

Scope all animated channels

nodeArr = hou.node("/").allSubChildren()
for n in nodeArr:
    if not n.isInsideLockedHDA():
        parmArr = n.parms()
        for p in parmArr:
            if p.isTimeDependent():

Toggle Display points with global hotkey

pane = hou.ui.curDesktop().paneTabOfType(hou.paneTabType.SceneViewer)
settings = pane.curViewport().settings()
markersDisplayModel = settings.displaySet(hou.displaySetType.DisplayModel)
markersSceneObject = settings.displaySet(hou.displaySetType.SceneObject)

# Toggle the markers (visible when inside /obj/...)
markersDisplayModel.showPointMarkers(not markersDisplayModel.isShowingPointMarkers())

# Unify with the scene (visible when in top level "/obj")

Little snippets to navigate the network view with kbd

# hotkey alt-shift-r
hou.playbar.setRealTime(not hou.playbar.isRealTime())

# hotkey ctrl-ins
for node in hou.selectedNodes():
    node.setRenderFlag(not node.isRenderFlagSet())

# hotkey ins
for node in hou.selectedNodes():
    node.setDisplayFlag(not node.isDisplayFlagSet())

# hotkey ctrl-del
for node in hou.selectedNodes():
    node.bypass(not node.isBypassed())

# hotkey ctrl-shift-ins
for node in hou.selectedNodes():
    node.setTemplateFlag(not node.isTemplateFlagSet())

# hotkey Z
pane = hou.ui.curDesktop().paneTabOfType(hou.paneTabType.SceneViewer)

# hotkey shift-Z
pane = hou.ui.curDesktop().paneTabOfType(hou.paneTabType.SceneViewer)

Wedge HScript Render Takes Automation (filename, cam, framerange)

In the current project, I have lots of takes, multiple cameras and different frame ranges. So I use the Wedge ROP (By Take all the takes) and I have named my takes this way:

  • name_startframe_endframe, e.g.:
    • “magnetic_400_2200”
    • “terrain_600_1800”

Name is descriptive, for further comping. The first number is Start of the frame range, the second number is the End of the frame range.

I have many different ROPs to set up the renders. In the ROP, I automate the file names and frame ranges with HScript expressions. For example this one is to extract the Start Frame or End Frame from the name of the take:

    string take = chsop("take");
    float first = index(take, "_");
    float last = rindex(take, "_");
    float start = first + 1;
    float length = last - first - 1;
    string startFrameString = substr(take, start, length);
    float  startFrame = atof(startFrameString);
    float start = last+1;
    float length = strlen(take) - last - 1;
    string endFrameString = substr(take, start, length);
    float  endFrame = atof(endFrameString);
    return startFrame;

This expression is to generate the folder and filename (Output Image) e.g.

    string take = chsop("take");
    string camera = chsop("camera");
    float first = index(take, "_");
    float start = 0;
    float length = first;
    string takeName = substr(take, start, length);

    string camName = substr(camera, 5, 5);
    string takeName += "_" + camName;
    string output = "$HIP/render/";
    string output += takeName + "/" + takeName;
    string output += "_$F4.png";
    return output;


VDB Avoid Colliders Smoothed

VDB SDF (from colliders), Analyze gradient, and then Point VOP, volume sample vector multiplied with ramped distance. I wanted it to be proof for more complex 3d “colliders”. VDB is sparse, so maybe we just need bigger “Exterior Band Voxels”


Here is the preview, with points and Attribute Interpolate (Matt Estela has tutorial on this here).

VEX Banked Turn

Thanks to Javier Toledo for the initial script. I have added the side_mult_error multiplier and few other things.

Polyframe the @tangentu, correct @up and gen @side

//create perpendicular SIDE
v@up = {0,1,0};
v@side = cross(v@up, v@tangentu);

//correct the UP
v@up = cross(v@tangentu, v@side);
v@N = v@tangentu;


Add Curvature and then Smooth

int prevId = clamp(@ptnum-1,0,@numpt);
int nextId = clamp(@ptnum+1,0,@numpt);

vector prevPos = point(0,"P",prevId);
vector nextPos = point(0,"P",nextId);

vector prevSide = point(0,"side",prevId);
vector nextSide = point(0,"side",nextId);

float side_mult_error = chf("side_mult_error") * 0.001;

vector prevDisp = prevPos + prevSide * side_mult_error;
vector nextDisp = nextPos + nextSide * side_mult_error;

float dist = length(prevPos - nextPos);
float dispDist = length(prevDisp - nextDisp);

//ratio by distances
f@ratio = (dispDist/dist) - 1;

f@ratio *= chf("curvature_mult") * 10;
f@ratio /= side_mult_error;
f@ratio = clamp(f@ratio, -chf("curvature_clamp"), chf("curvature_clamp"));

//rotate matrix
matrix3 rot = ident();
rotate(rot, f@ratio, v@tangentu);

v@side *= rot;
v@up *= rot;


VEX Carve

Thanks a lot to Andrew for the initial script. I have rewritten it to work on open curves. I found the setpointattrib to be slow. UV texture is faster to get the uv.x, instead of computing the arclength in the prim wrangle.

vector getlinepos(int primnum; float u) {
    vector pos = primuv(0, "P", primnum, set(u,0,0));
    return pos;

int    createpoint(int primnum; vector pos) {
    int ptnum = addpoint(primnum, pos+{0.5,0,0});
    int vertex = addvertex(0, primnum, ptnum);
    return vertex;

int oldprim = @primnum;
int count = primvertexcount(0,@primnum)-1;

if(!(hasprimattrib(0, "start"))) f@start = ch("start");
if(!(hasprimattrib(0, "end"))) f@end = ch("end");

if (@start<@end){
    int newprim = addprim(0, "polyline");
    createpoint(newprim, getlinepos(oldprim, @start));
    //from prim
    int startvert, endvert;
    startvert  = 1 + floor(@start * count);
    endvert    = 1 + floor(@end * count);
    endvert    = min(endvert, count);
    for (int i = startvert; i < endvert; i++)
        createpoint(newprim, point(0, "P", i));
    createpoint(newprim, getlinepos(oldprim, @end));
} else {
    int newprim;
    newprim = addprim(0, "polyline");

    //from prim
    int startvert, endvert;
    startvert  = 1 + floor(@start * count);
    endvert    = 1 + floor(@end * count);
    endvert    = min(endvert, count);
    for (int i = 0; i < endvert; i++)
        createpoint(newprim, point(0, "P", i));
    createpoint(newprim, getlinepos(oldprim, @end));

    newprim = addprim(0, "polyline");
    createpoint(newprim, getlinepos(oldprim, @start));

    for (int i = startvert; i <= count; i++)
        createpoint(newprim, point(0, "P", i));


removeprim(0, oldprim, 1);


DOP Rigid Body Simulation

DOP theory

  • w attribute = angular velocity
  • understand the dop object as container, which can contain thousands of rigid body packed fragments (or packed geometries)
  • pack name – “piece”
  • pack fragments vs packed geometries – packed fragments stored in one memory location and fragment is sublocation
  • the Bullet solver automatically detects objects that are initially overlapping and prevents them from colliding/exploding until they separate (since H12.5)
  • passive objects can be collided with by active objects, but don’t move, and are not affected by forces
  • walls/floors, raying a grid to get the shape and then extruding the faces into unconnected little cubes speeds up collisions

Fractured Rigids SOP

Pack SOP
  • no materials until unpack
  • orientation etc. stored in Primitive Intrinsics
  • fast view as Point Cloud
  • path: op:`opfullpath(‘.’)`
Connectivity SOP
  • attribs from polygon connectivity
Partition SOP
  • groups from rule
  • group_$CLASS (@class being prim attrib created by connectivity SOP)
Exploded view SOP
  • poly connectivity from attribs
Packed Edit SOP
  • can change visibility etc
Name SOP
  • name from group
Voronoi SOP
  • poly connectivity from VDB/scatter
Voronoi Fracture Points SOP
  • adds points to surface/interior depending on position of Impact point
Assemble SOP
  • finds connected islands of geometry
  • gives name to pieces
  • packs into Packed Fragments (not packed geometries)

Fractured Rigids DOP

RBD Packed Object DOP
  • use SOP path
  • Geometry Representation (Convex Concave etc)
  • BULLET is made for Convex, Concave is slow with thousands of pieces
  • Collision Compound
    • VDB to spheres, Bake ODE, Merge
  • use Collision Padding (0 = same as geo, 0.1 = far from)
RBD Object DOP
  • same as above
  • use SOP path
RBD Point Object
  • creates a new simulation object at each point of a source geometry object
  • useful for simulating a large collection of identical objects
Static Object
  • its motion is not controlled by the simulation
Rigid Body Solver DOP
  • solver types
  • RBD was built in solver, not used much anymore
  • ODE never use
  • Fracture – we don’t use
Merge DOP
  • defines collision
 POP forces
  • can be used to drive rigid body simulation (packed as points)
  • wire node into Post-solve or Pre-solve
Gravity DOP
  • does not create force attribute on point
  • creates “../Forces/Gravity”

VEX snippets

Find min / max value

thanks to petz!

setdetailattrib(geoself(), "min_val", @uv.y, "min");
setdetailattrib(geoself(), "max_val", @uv.y, "max");


List of Primitive neighbours by half edges

thanks to petz!

int     prim_edge, edge, prim, i, n, num;
string  neighbours = "";

i = 0;
prim_edge = primhedge(@OpInput1, @primnum);
while(i < primvertexcount(@OpInput1, @primnum))
    num = hedge_equivcount(@OpInput1, prim_edge);
    n = 0;
    while(n < num)
        edge = hedge_nextequiv(@OpInput1, prim_edge);
        prim = hedge_prim(@OpInput1, edge);
        if(prim != @primnum)
            neighbours += sprintf("%g ", prim);

        prim_edge = edge;

    prim_edge = hedge_next(@OpInput1, prim_edge);

s@neighbours = neighbours;


Insert a point to the middle of the curve

thanks to awong from discord

int prim_num = 0;
int new_point = addpoint(0, {0,0,0});
int insert_position = 3;

// store the old vertices
int old_vertices[] = primvertices(0, prim_num);

// add a placeholder using an arbitrary point
addvertex(0, prim_num, 0);

// replace the vertex at the desired position
setvertexpoint(0, prim_num, insert_position, new_point);

// replace the vertices after the inserted position
for(int i = insert_position; i < len(old_vertices); i++)
    setvertexpoint(0, prim_num, i + 1, old_vertices[i]);

U coordinate on closed prim

thanks to f1480187

// Detail wrangle.
float length = primintrinsic(0, "measuredperimeter", 0);

// Set to false if value of 1.0 is unwanted for the last point
// of closed prims and instead need to be treated as if point with
// u=1 is coincident with the first point (like in unrolled prims).
int as_open = true;

// Compensate for closing auto-edge length.
if (as_open && primintrinsic(0, "closed", 0))
    vector auto_edge = point(0, "P", 0) - point(0, "P", @numpt-1);
    length -= length(auto_edge);

// Compute curve u.
float passed = 0;
for (int i = 1; i < @numpt; i++)
    vector d = point(0, "P", i) - point(0, "P", i-1);
    passed += length(d);
    setpointattrib(0, "u", i, passed/length);

Print to console

printf("OUT=%f;  ", out); //  %s string,   %i integer

Compilable For Each Material

s@shop_materialpath = "/obj/butterflies/shop/hud";
s@shop_materialpath += itoa( detail(1,"iteration") %10 );

Random unit vector in the direction

thanks to Javier

vector center = {0,0,1};
float  maxangle = chf("maxangle");
v@N = sample_direction_cone(center, maxangle, rand(@ptnum) );

Other inputs

v@P.y = v@opinput1_P.y;
f@y = v@opinput1_P.y;

//2015: @opinput1_P binds as a float


@group_my = 1;
if (@group_my) v@N = {0,1,0};

Group adhoc syntax / expression

@myattr="foo bar"
@ptnum%(@numpt-1)==0 // first and last point


s@name = sprintf("piece%d", @class);
s@name = sprintf("nameX%dY%d",@P.x,@P.y);

Time Globals

@Time //Float time ($T)
@Frame //Float frame ($FF)
@SimTime //Float simulation time ($ST), only present in DOP contexts.
@SimFrame //Float simulation frame ($SF), only present in DOP contexts.
@TimeInc //Float time step (1/$FPS)


vector min, max;
getbbox(0, min, max);
v@center = (min+max)/2;

Attrib type info

setattribtypeinfo(0, "point", "myvector", "vector");


==, !=, <, <=, >, >=

The logical (&&, ||, and !) and bitwise (& |, ^, and ~) operators are only defined for integers. AND OR:

if( res.x<precis || t>tmax ) break;

Shortcut to if statement

float a = condition? b: c;




Find and delete ngons

int np[] = primpoints(0,@primnum);
int lnp = len(np);

if( lnp > 3 ) {
    removeprim(0, @primnum, 1); // 1 = and points

P smooth

int maxpoints = chi("maxpoints");
float radius = chf("radius");

int handle = pcopen(0, "P", @P, radius, maxpoints);
@P = pcfilter(handle,"P");

Init Attrib Interpolate

//random prim
int prim = floor( rand(@ptnum) * nprimitives(1) );
i@sourceprim = prim;

//random speed, looping
float speed = fit01( rand(@ptnum), chf("speed_min"), chf("speed_max") );
float dist = (@Time * speed) % 1;
v@sourceprimuv = set(dist,0.5,1.0);

Prims from point array

thanks to @petz from odforce:

int point = addpoint(0, @P);
int points[] = primpoints(0, @primnum);
for(int i = 0; i < len(points); i++)
    int point_array[] = array(points[i - 1], points[i], point);
    int prim = addprim(0, "poly", point_array); 
removeprim(0, @primnum, 0);


The geometry functions, table from the docs

vertexpoint(), pointvertex(), vertexnext(), vertexprev(), vertexindex(), primvertexcount(), vertexprim(), vertexprimindex()

Write point numbers to an array

thanks to @petz from odforce

//in detail mode
i[]@points = expandpointgroup(@OpInput1, "!");

//in point mode
int point[] = array(@ptnum);
setdetailattrib(geoself(), "points", point, "append");


#include <groom.h>

adjustPrimLength(0, @primnum, @perimeter, @perimeter*@dist);


thanks to

@gl_wireframe = true;
@gl_lit = true;

Split string

thanks to Chris,

//Split based on '_'
string bars[] = split(s@shop_materialpath, "_");

//Use last element as attribute value
s@mtlGrpName = bars[-1];

0-360 angle between vectors

thanks to f1480187

#define PI 3.1415926535897932384

float angle = acos(dot(v@up, v@aim));
int first_half = sign(dot(v@z, cross(v@up, v@aim))) >= 0;
angle = first_half ? angle : 2*PI - angle;

@angle = degrees(angle);


append() // end
push() // end
insert() // index (negative from the end, inserting past the end will grow the array)


VEX Quaternion orient, N, up

Without @orient:

v@N; // +Z axis of the copy
v@up; // +Y axis of the copy

Representing a quaternion from an angle and axis. The angle is specified in radians:

float angle = radians(90);
vector axis = set(0, 1, 0);
p@rot = quaternion(angle, axis);

Representing a quaternion from a 3×3 rotational matrix:

float angle = radians(90);
vector axis = {0,1,0};
matrix3 m = ident();
rotate(m, angle, axis);
@orient = quaternion(m);

PI eight digits

#include "math.h";
float e = M_E; //2.7182818
f@angle = PI; //3.1415926
f@angle = radians(180);


VEX Arrays and Matrices

To create:

f[]@myFarray = {0,1,2,3,4,5,6};
i[]@myIarray = {0,1,2,3,4,5,6};
v[]@myVarray = {{1,2,3},{4,5,6}};
v@readvect = @myVarray[1];

3[]@myMatrixarray = { {0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0}};

matrix3 mat = {1,2,3,4,5,6,7,8,9};
3[]@myMatrixarray[0] = mat; //assign

Read from prim:

3[]@rotmatrixarray[index] = prim(0, "rotmatrix", index );

Read from attrib:

vector array[] = v[]@atrail;
vector position = array[i];


float solve_beats[] = {};
for (int i = 0; i<700; i++)
    if (val_curr >= 0.1) append(solve_beats, i);
int lenght = len(solve_beats);

Create empty, resize, faster:

resize(@array, len);

Pipeline notes

C4D camera properties

Sensor Size (Film Gate) = Aperture
Focal Length = Focal Length
1920 × 1080 – Focal Length = 150 mm (full = full)
1920 × 360 – Focal Length = 50 mm (third = third)
1920 × 360 – right cam = Screen Window X/Y = 1
1920 × 360 – left cam = Screen Window X/Y = -1


  "font_size": 11,
  "close_windows_when_empty": true,
Key bindings:
  { "keys": ["alt+shift+up"], "command": "swap_line_up" },
  { "keys": ["alt+shift+down"], "command": "swap_line_down" },	

  { "keys": ["ctrl+alt+q"], "command": "toggle_record_macro" },
  { "keys": ["ctrl+q"], "command": "close" },
  { "keys": ["f1"], "command": "vex_helpcard" },

Alt F3 – multiple cursors
Ctrl D – search and select
Ctrl Shift P – search command palette

Package settings

Preferences > Package Settings > VEX

    "popup_max_width": 900,
    "popup_max_height": 900,
External editor file watcher






Graphical Function Explorer url

VEX gurus repositories (URLs)

Elisha Hung,
Anastacia Opara
Stefan Sietzen,
Animatrix, Pusat
Matt Estela
Junichiro Horikawa

Shelf Tools and Hotkeys

This is just my little repository of custom hotkeys and little python tools



    #  Desktops            Ctrl+Alt+NUM

h.desktop05 "Desktop 5" "Switch to Desktop 5"    Alt+Ctrl+1
h.desktop06 "Desktop 6" "Switch to Desktop 6"    Alt+Ctrl+4
h.desktop07 "Desktop 7" "Switch to Desktop 7"    Alt+Ctrl+5
h.desktop08 "Desktop 8" "Switch to Desktop 8"    Alt+Ctrl+6

    #  Render              F12

h.tool:start_ren	start_ren	"Shelf Tool: start_ren"	 F12
h.tool:kill_ren	kill_ren	"Shelf Tool: kill_ren"	 F11

    #  Network             F

h.pane.wsheet.home_selected "Home Selected" "Home selected OP tiles"     Shift+H G F
h.pane.wsheet.frame_selected    "Frame Selected"    "Frame selected OP tiles"    Shift+F

    #  Network             Backspace

h.pane.chedit.toggle_list   "Toggle Channel List"   "Toggle channel list"    Tab
h.pane.gview.operator_menu  "Toolbar Menu"  "Pop up toolbar menu"    Tab
h.pane.jump_back    "Jump Back" "Jump back one step"     Alt+LeftArrow Backspace
h.pane.wsheet.add_op    "Add Operator"  "Add Operator"   Tab

    #  Network  Display                 Ins
    #  Network  Display + Render        Ctrl Ins
    #  Network  Bypass                  Ctrl Del    
    #  Network  Template                Ctrl Shift Ins
    #  Network  Selectable Template     Ctrl Alt Ins (TODO)
    #  Network  Clear templates         Ctrl Shift Del

h.tool:node_disp    node_disp   "Shelf Tool: node_disp"  Insert
h.tool:node_byp node_byp    "Shelf Tool: node_byp"   Ctrl+Del
h.tool:node_ren node_ren    "Shelf Tool: node_ren"   Ctrl+Insert
h.tool:toggle_realtime  toggle_realtime "Shelf Tool: toggle_realtime"    Alt+Shift+T
h.tool:node_tpl node_tpl    "Shelf Tool: node_tpl"   Ctrl+Shift+Insert
h.tool:toggle_pts   toggle_pts  "Shelf Tool: toggle_pts"     Alt+Shift+W
h.textport  Textport    "Open texport"  
h.floatpanel    "Floating Panel"    "New floating panel"    

h.pane.gview.cleartemplates "Clear All templates"   "Clear all template flags"   Ctrl+Shift+Del

    # Insert fix
h.pane.take.list.insert "Insert New Take"   "Insert New Take"   
h.pane.projectm.new_folder  "Add New Folder"    "Add New Folder"    
h.pane.gview.handle.xform.pivot_mode    "Pivot Mode"    "Toggle pivot mode"  \"

    #  Network  Left Right Page Down

h.pane.wsheet.left  "Set Current Left"  "Set Current left"   Shift+PageUp , Ctrl+PageUp
h.pane.wsheet.right "Set Current Right" "Set Current right"  Shift+PageDown . Ctrl+PageDown
h.pane.gview.left   "Move To Left Sibling"  "Move to left sibling operation"     Shift+PageUp , Ctrl+PageUp
h.pane.gview.right  "Move To Right Sibling" "Move to right sibling operation"    Shift+PageDown . Ctrl+PageDown
h.pane.nexttab  "Next Tab"  "Next pane tab"  Ctrl+Tab
h.pane.prevtab  "Previous Tab"  "Previous pane tab"  Ctrl+Shift+Tab

    #  Network  Color    Shift-C
    #  Network  Align    C

h.pane.wsheet.align_horizontal  "Align Nodes Horizontally"  "Align the selected nodes horizontally"  C
h.pane.wsheet.color_palette "Color Palette" "Open color palette"     Shift+C

    #  Network        collapse to subnet          Ctrl-N

h.pane.wsheet.collapse  "Collapse Selected" "Collapse selected operators"    Ctrl+N   New "Delete all contents"    Alt+N

    #  Network        drag Render                 Z
    #  Network        drag Template               X
    #  Network        drag Visualise              V
    #  Network        drag Bypass                 B

h.pane.wsheet.visualize_mode    "Visualize Output"  "Hold this key and select a node or output connector to visualize the output"    V
h.pane.wsheet.flag2_mode    "Set Secondary Flag"    "Hold this key and select a node to toggle the secondary flag value"     X
h.pane.wsheet.flag3_mode    "Set Third Flag"    "Hold this key and select a node to toggle a third flag value"   Z
h.pane.wsheet.scope_chans   "Scope Channels"    "Scope channels"    

    #  Network align     E
h.pane.wsheet.align_vertical    "Align Nodes Vertically"    "Align the selected nodes vertically"    E

    #  Houdini           Maximize Pane          ' 
    #  Houdini           Maximize To Split      \
    #  Houdini           Next Camera      ]

h.pane.gview.handle.xform.handle_geometry_detachment    "Toggle Handle-Geometry Detachment" "Toggle handle-geometry detachment" 
h.pane.maximize_full    Maximize    "Toggle pane full screen"    Alt+\\' Ctrl+B \\'
h.pane.maximize_split   "Maximize in Split Direction"   "Toggle pane full size horizontally or vertically"   \\
h.pane.gview.nextcamera "Next Camera"   "Look through the next camera in the list"   ]

    #  Geometry Quad       Alt-W

h.pane.gview.state.view.toggle_single_quad  "Toggle Single/Quad"    "Toggle single/quad viewport layouts"    B Alt+W
h.rename_selected_nodes "Rename Selected Nodes" "Rename selected nodes"
    #  Restart Selecting Group                             Ctrl+Shift+R
h.pane.gview.redoselection  "Restart Selecting" "Restart selecting"  Ctrl+Shift+R
h.pane.gview.state.new_view "View Tool" "Invoke the view tool"   `

    #  Network   Create Nested Channel Groups              Ctrl+Shift+A

h.pane.wsheet.create_channel_groups "Create Nested Channel Groups"  "Create nested channel groups that correspond to parameter folders"  Ctrl+Shift+A

    #  Houdini    Copy Paste Relative Refs                 Alt+C   Alt+V

h.pane.parms.copy_parm  "Copy Parameter"    "Copy parameter"     Alt+C
h.pane.parms.paste_rel_refs "Paste Copied Relative Refs"    "Paste copied relative refs"     Alt+V
h.paste Paste   "Paste Selection"    Ctrl+V
h.copy  Copy    "Copy selection"     Ctrl+C

    #  Houdini    Timeline        End of Range              Ctrl+DownArrow

h.range_end "Jump To End Of Range"  "Jump to end of range"   Ctrl+DownArrow

    #  Recook All Sims                                       Alt+Ctrl+S

h.reset_sim "Reset Simulations" "Recook simulations in open viewers"     Alt+Ctrl+S

    #  External Editor

h.pane.parms.edit_expression_external   "Edit in External Editor"   "Custom Menu Operation: Edit in External Editor"     Alt+E

    #  Edit Parameter Interface

h.pane.wsheet.opmenu.spareparms "Edit Parameter Interface"  "Edit the node's parameter interface"    Ctrl+Shift+I


Python snippets

Bind light’s “Enable” checkbox to the display flag

obj = hou.node(".")
return obj.isDisplayFlagSet()

Reference SOP input from chopnet Geometry

chopnode = hou.node("..")
chopname =                  # chopnet_smooth
chopnet,task = chopname.split('_')          # chopnet smooth
channelnodepath = "../../channel_" + task   # ../../channel_smooth
channelnode = hou.node(channelnodepath)
inputpath = channelnode.inputs()[0].path()
return inputpath

instances() nodes of type in the scene

thanks to julian johnson!

node_type = hou.objNodeTypeCategory().nodeTypes()['bone']
for x in node_type.instances():
    print x

hou.playbar.setPlaybackRange(self, start, end)

print node.type().name() # file, filecache, delete, solver, dopimport, …
node = hou.pwd()
path = node.path()
objContextNodeName = path.split(‘/)[-2]