git.lucas.co / hou-control
SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git

commit3c686278f1fce2c7aaa3826c63043eaedee7d54c
parent5afb2c5f32
authorLucas Galante <[email protected]>
date2026-09-17 21:12
keycam: register under SOP and hide the current node's wireframe

Clicking a non-display node in the network editor drew its output as a
white wireframe over the display node while keycam was active. That is
Houdini's Current Model display set, switched on whenever a SOP state
enters; hou.SceneViewer.showCurrentSopGeometry(False) turns it off, but
only inside a state whose home category is SOP. Keycam was registered
under Object with SOP as an extra context, so the call was a no-op.

Register keycam under SOP with Object as the extra context, call the
flag in onGenerate, and rename the hotkey symbols from state.obj.keycam
to state.sop.keycam to match.

Co-Authored-By: Claude Fable 5.1 <[email protected]>

 hc_hotkeys.json         | 18 +++++++++---------
 viewer_states/keycam.py | 15 +++++++++++----
 2 files changed, 20 insertions(+), 13 deletions(-)

diff --git a/hc_hotkeys.json b/hc_hotkeys.json
index b372556..f3f4fd1 100644
--- a/hc_hotkeys.json
+++ b/hc_hotkeys.json
@@ -9,15 +9,15 @@
         "h.hc_session_prevpane": "alt+shift+tab",
         "h.hc_session_togglemainmenu": "alt+m",
         "h.hc_session_togglestatusbar": "alt+b",
-        "h.pane.gview.state.obj.keycam.trans_up": "shift+k",
-        "h.pane.gview.state.obj.keycam.cycle_draw_mode": "ctrl+d",
-        "h.pane.gview.state.obj.keycam.cycle_layout": "ctrl+l",
-        "h.pane.gview.state.obj.keycam.view_top": "1",
-        "h.pane.gview.state.obj.keycam.view_bottom": "2",
-        "h.pane.gview.state.obj.keycam.view_front": "3",
-        "h.pane.gview.state.obj.keycam.view_back": "4",
-        "h.pane.gview.state.obj.keycam.view_left": "5",
-        "h.pane.gview.state.obj.keycam.view_right": "6",
+        "h.pane.gview.state.sop.keycam.trans_up": "shift+k",
+        "h.pane.gview.state.sop.keycam.cycle_draw_mode": "ctrl+d",
+        "h.pane.gview.state.sop.keycam.cycle_layout": "ctrl+l",
+        "h.pane.gview.state.sop.keycam.view_top": "1",
+        "h.pane.gview.state.sop.keycam.view_bottom": "2",
+        "h.pane.gview.state.sop.keycam.view_front": "3",
+        "h.pane.gview.state.sop.keycam.view_back": "4",
+        "h.pane.gview.state.sop.keycam.view_left": "5",
+        "h.pane.gview.state.sop.keycam.view_right": "6",
         "h.pane.nexttab": "ctrl+tab",
         "h.pane.prevtab": "ctrl+shift+tab",
         "h.pane.gview.refplane": "g",
diff --git a/viewer_states/keycam.py b/viewer_states/keycam.py
index f30e997..914bae1 100644
--- a/viewer_states/keycam.py
+++ b/viewer_states/keycam.py
@@ -66,6 +66,11 @@ class State(object):
         self.guides = HCGuides(self)
         # Prevent exiting state when current node changes
         self.kwargs['state_flags']['exit_on_node_select'] = False
+        # Houdini turns on the current SOP's wireframe when a SOP state
+        # enters, so a node picked in the network editor is drawn over the
+        # display node. Keycam only navigates; show the display node alone.
+        # Houdini restores the flag when the state exits.
+        self.scene_viewer.hou_tab.showCurrentSopGeometry(False)
         self.guides.update()
         self.hud = Hud(self)
         self.hud.update()
@@ -428,8 +433,10 @@ class Hud:
 def createViewerStateTemplate():
     template = hou.ViewerStateTemplate(
         type_name='keycam', label='keycam',
-        category=hou.objNodeTypeCategory(),
-        contexts=[hou.sopNodeTypeCategory()]
+        # SOP is the home category: showCurrentSopGeometry() is a no-op in a
+        # state registered under Object, even when SOP is an extra context.
+        category=hou.sopNodeTypeCategory(),
+        contexts=[hou.objNodeTypeCategory()]
     )
 
     template.bindFactory(State)
@@ -437,7 +444,7 @@ def createViewerStateTemplate():
 
     # Define Commands and Default Bindings
     hotkeys = hou.PluginHotkeyDefinitions()
-    ctx = 'h.pane.gview.state.obj.keycam'
+    ctx = 'h.pane.gview.state.sop.keycam'
     hotkeys.addContext(ctx, 'HC Keycam', 'Hotkeys for the HC Keycam viewer state')
     
     commands = {
@@ -640,7 +647,7 @@ def createViewerStateTemplate():
     """ Context Menu """
 
     menu = hou.ViewerStateMenu('keycam_menu', 'Keycam Menu')
-    ctx = 'h.pane.gview.state.obj.keycam'
+    ctx = 'h.pane.gview.state.sop.keycam'
     
     menu.addActionItem('frame', 'Frame', hotkey=f'{ctx}.frame')
     menu.addActionItem('reset', 'Reset', hotkey=f'{ctx}.reset')