Looking Through: part 2 — Basics

It is best practice to keep things as general and reusable as possible, so the first task is to design a function that takes a tuple of object types and returns all nodes of that type whose transform matrix matches that of the viewport — without being concerned about exactly what it is being looked through.. To get the current viewport, toolutils is made use of.  It gets imported along with the hou. toolutils is included in Houdini and is made use of by the shelf buttons amongst other places. I highly recommend exploring it.

import hou
import toolutils

As an arg to this function a tuple “node_types” expects a operator types as strings. You can quickly see the node type by pressing MMB over a node in the network editor.

def viewportObjectsOfType(node_types):

Included in toolutils is a method to grab the active sceneviewer tab and from there we can get to the viewport and then pull the transform.

cur_viewport      = toolutils.sceneViewer().curViewport()
cur_view_xform = cur_viewport.viewTransform()

node_types is ensured to be a list and then iterated through. We use hou.nodeType with scope limited to object types to gather all instances of each of the types passed in node_types and place them in a list, as lights and cameras are object level nodes.

# get all the objects of specified types
all_possible_nodes = []
for node_type in list(node_types):

found_nodes = hou.nodeType(hou.objNodeTypeCategory(), node_type).instances()

The list of matching instances is then iterated through, pulling the transform and testing if its equal to the transform pulled from the viewport. If it is a match, its appended to the list matching_nodes, which is then turned into a tuple and returned.

**NOTE** However, if you set the viewport to look through a light ie “mylight”, pull the transform of the viewport and the light you might notice sometimes  they don’t entirely match and therefore fail an equality test. ie …

>>> cur_viewport.viewTransform() == mylight.worldTransform()

This is because of precision differences where the amount of decimal places will mean they aren’t always totally equal even though for all practical purposes they are. Fortunately sidefx dealt with this by providing a method as part of matrix and vector objects– isAlmostEqual() –which as the name implies returns True when almost equal.

# look for a matching transform
matching_nodes = []
for node in all_possible_nodes:

if node.worldTransform().isAlmostEqual(cur_view_xform):


# return as typically expected tuple
matching_nodes = tuple(matching_nodes)

return matching_nodes

  And thats it! -A general function that will match any object node of a specified types to the viewport. Another function is going to be built calling viewportObjectsOfType() but specifically for light and cameras.

Next is looking closer at Houdini light nodes and considering them in this second function.

Leave a Reply

Your email address will not be published. Required fields are marked *