5 Hour free course on Houdini basics:
Shout out to Denis J-F for putting me onto this one. So far so good. Well explained and has playback speed controls which is always a godsend when watching tutorials so you can fast-forward on the real basic stuff that's easy to digest and then slow down again for the bits that need a bit more concentration.
Key things to remember:
Houdini is like a UNIX style OS.
Nodes organised like folders and are the address to themselves within the DCC
eg "/" is the root of a houdini file
"/obj/geo1" is the 'path' to the node "geo1"
Houdini Python Cheatsheet:
(Formatting generated with http://hilite.me/ using the "fruity" style)
# Houdini python reference: # https://www.sidefx.com/docs/houdini/hom/index.html # hou is the name of the python houdini commands. # It's already imported in a python shell that's loaded from Houdini #### FILE OPERATIONS #### # open a file file_name = "/my/file/path.hip" hou.hipFile.load(file_name) # save a file hou.hipFile.save(file_name) #### WORKING WITH NODES #### # GETTING/SELECTING path_to_node = "/obj/geo1" node = hou.node(path_to_node) # set a node to be selected in the GUI new_geo_node.setSelected(True) # TYPES # getting a node's type (this get's a NodeType class) node_type = node.type() node_type_name = note_type.name() print node_type_name >>> "geo" # PARAMETERS # setting parameters on a node #(NB: this works much the same way that Nuke does it's knobs with python) parameter_name = "tx" # first get the parameter parameter = node.parm(parameter_name) value = 2 # then set the value you want. parameter.set(value) # SET FLAGS ON NODES # Some settings on nodes are known as flags (not sure what the technical difference # is yet between parameters and flags) # Some notable flags display and selectable in viewport can be modified as shown below # set the display of the geo to off new_geo_node.setDisplayFlag(False) # set the select-ablity of the geo to off new_geo_node.setSelectableInViewport(False) # set the lock state of the node new_geo_node.setHardLocked(True) # MULTIPLE NODES # There's almost certainly a better way of doing this, but a basic # way to list nodes in a scene looks like this: # get the root root = hou.node("/") # get the children of that node # (which are the different houdini contexts (eg: obj, mat, cop, chop, etc) contexts = root.children() # for each context for cxt in contexts: print cxt.name() # get the children of that context nodes = cxt.children() if nodes: # for each node in that context print the name of the node for n in nodes: print n.name() #### CREATING NEW NODES #### # to create new nodes you've got to do so from and class instance of the context in # which that node can be created. # eg: for a Geometry node you need create it from an instance of the "/obj" context # eg: for a Shader node (principledShader) you need to create it from an instance of # the "/mat" context # setup the instance of the obj context obj_context = hou.node("/obj") new_node_type = "geo" new_node_name = "my_geo" # create the geometry container (essentially the transform node to use Maya terms) new_geo_node = obj_context.createNode(new_node_type, new_node_name) primitive_type = "box" primitive_name = "my_geo_box" # now create the primitive inside the geo container (ie the shape node in Maya terms) box = new_geo_node.createNode(primitive_type, primitive_name) #### NODE CONNECTIONS AND INPUTS #### # setting the input of one node to the output of another # create a new polybevel node so we've got something to connect up polybevel = new_geo_node.createNode("polybevel") # set the 1st input to the box created above. # NB: The first arg is the index of the input 'slot' # The second arg must be a class object. A string to the path of the object is not sufficient polybevel.setInput(0, box) # break/disconnect inputs # the way to do this is to just set a None input. polybevel.setInput(0, None) #### MISC #### # POSITIONING NODES IN THE GRAPH # get the current position of the node in the graph. # This appears as a list but is actually and instance of the hou.Vector2 class. current_position = new_geo_node.position() >>> [-1,1] # set the position of a node in the graph by passing a list with the x and y position # you want to node to go to. new_geo_node.setPosition([0,2])