Network Editor, Layout 1%

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)

Python Script: Update chf(“parm”) values (default, min, max) from VEX comment

Inspired by great Matt Estela. Now I can comment my VEX like this:

@pscale = chf("pscale"); // 0.2 in -1 to 1

The script reads the comment, and sets these values to the pscale parm:

– default value = 0.2
– slider range min = -1
– slider range max = 1

I will update the script to be a tool with hotkey. But it works even like this:

import re
#parm = kwargs['parms'][0]
for nodes in hou.selectedNodes():
    node = nodes
# I will update the script to be a tool, with hotkey. But it works already like this:

parm = node.parm("snippet")
snippet = parm.unexpandedString()


lines = snippet.split('\n')

for line in lines:
    chf = re.findall('chf.+$',line)         #chf = chf("pscale"); // 0.6 in 0.5 to 1.0
    if chf:
        chf = chf[0]                        
        name,range = chf.split('//')        #name = chf("pscale");      range =  5 to 10
        default, minmax = range.split('in')
        min,max = minmax.split('to')
        name = re.findall("chf\(\"(\w+)\"", line)[0]
        default = float(default.strip())
        default = ([default])               #make tuple from float
        min = float(min.strip())
        max = float(max.strip())
        ptg = node.parmTemplateGroup()
        parmedit = ptg.find( name )
        parmedit.setDefaultValue(  default  )
        parmedit.setMinValue(  min  )
        parmedit.setMaxValue(  max  )
        ptg.replace( name, parmedit )
        node.setParmTemplateGroup( ptg )


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

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;




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);

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);


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": "helpcard" },

Alt F3 – multiple cursors

Package settings

Preferences > Package Settings > VEX

    "popup_max_width": 900,
    "popup_max_height": 900,






Graphical Function Explorer url

VEX gurus repositories (URLs)

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


If you have a clue how to solve these, please let me know (

  • automate the distribution of OpenCL calculations to all GPUs
    • please, did you manage to automate the distribution of OpenCL calculations to all your GPUs? I also have 4 gpus in one computer now. Is there any management system, which could help me distribute this HOUDINI _OCL_DEVICENUMBER and run more instances of Houdini simultaneously, each calculating distributed slice on one computer?
  • camera y-lock (3d mouse)
  • group adhoc
    • @primnum%2==0? @elemnum==5? why not?
  • cache
    • cache sop is slow (file td – v47 – back hud.hiplc – water mesh)
    • alembic is fast
    • polysoup is quite fast
    • packed is quite fast


  • addressing values in the sheet …python?



  • chf default values and ranges //comment in the wrangle


  • ok


  • shift enter rename
  •  mouse
    • ctrl shift ? set cam pivot
    • maximize pane, all
  • underscore ctrl-space
  • restore cam
  • home end?

After Isolating/Unisolating (I/Shift-I) channels in Animation Editor, the channel view does not refresh and behaves just like inactive “screenshot”. If I maximize or resize the window, the channels view refresh and I can edit channels again.

help to be printed

  • Q Box, Shift-Q Brush
  • Shift-C Contained, Shift-V Visible


  • file: sops + chops + rop + shop
  • folder: dop
  • firefox

array expression

    string takes = chsop("take");
    startS = slice( split( takes, "_"), 1 );
    startF = atof(startS);
    return startF;

voxel resolution / positions

– sample animated SOP colisionvel at “0.2” voxel size, voxels always aligned to {0,0,0} thanks to the bound?
– calculate DOP smoke at “0.1” voxel size, voxels always aligned to {0,0,0}
Please tell me what is roughly the workflow, I will study.


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


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

node = hou.pwd()
path = node.path()
objContextNodeName = path.split(‘/)[-2]