git.lucas.co / hou-control
git clone https://git.lucas.co/hou-control.git

commit156267d03890e50441a1fae685b9773400489dbb
parent6d81aefd31
authorLucas Galante <lsgalante12@gmail.com>
date2026-04-05 20:30
HC: Update HC

 python3.11libs/hc/__init__.py        |  74 ++++++-----
 python3.11libs/hc/hccam.py           | 177 +++++++++++++-------------
 python3.11libs/hc/hcdefaultcam.py    |   7 +-
 python3.11libs/hc/hcguides.py        | 145 ++++++++++-----------
 python3.11libs/hc/hclayouts.py       |  64 +++++-----
 python3.11libs/hc/hcmenuutils.py     |   1 -
 python3.11libs/hc/hcnetworkeditor.py | 114 +++++++++++++----
 python3.11libs/hc/hcnode.py          |  47 +++----
 python3.11libs/hc/hcpane.py          | 160 +++++++++++++-----------
 python3.11libs/hc/hcpathtab.py       |  13 +-
 python3.11libs/hc/hcprefs.py         |  13 +-
 python3.11libs/hc/hcradial.py        |   2 +-
 python3.11libs/hc/hcsceneviewer.py   |  71 +++++------
 python3.11libs/hc/hcsession.py       | 235 ++++++++++++++++++-----------------
 python3.11libs/hc/hctab.py           |  84 +++++++++----
 python3.11libs/hc/hcviewport.py      |  14 ++-
 python3.11libs/hc/hcvisualizers.py   |   2 +-
 python3.11libs/hc/hcwidgets.py       | 119 +++++++++++++++++-
 18 files changed, 810 insertions(+), 532 deletions(-)

diff --git a/python3.11libs/hc/__init__.py b/python3.11libs/hc/__init__.py
index 509cd63..2c46b9e 100755
--- a/python3.11libs/hc/__init__.py
+++ b/python3.11libs/hc/__init__.py
@@ -1,43 +1,41 @@
-from .bindings      import Bindings
-from .cam           import Cam
-from .defaultcam    import DefaultCam
-from .geo           import Geo
-from .guides        import Guides
-from .networkeditor import NetworkEditor
-from .node          import Node
-from .panel         import Panel
-from .pane          import Pane
-from .pathtab       import PathTab
-from .prefs         import Prefs
-from .radial        import Radial
-from .sceneviewer   import SceneViewer
-from .session       import Session
-from .status        import Status
-from .tab           import Tab
-from .viewport      import Viewport
-from .visualizers   import Visualizers
-from .widgets       import Widgets
+from .hcbindings      import HCBindings
+from .hccam           import HCCam
+from .hcdefaultcam    import HCDefaultCam
+from .hcgeo           import HCGeo
+from .hcguides        import HCGuides
+from .hcnetworkeditor import HCNetworkEditor
+from .hcnode          import HCNode
+from .hcpane          import HCPane
+from .hcpathtab       import HCPathTab
+from .hcprefs         import HCPrefs
+from .hcradial        import HCRadial
+from .hcsceneviewer   import HCSceneViewer
+from .hcsession       import HCSession
+from .hcstatus        import HCStatus
+from .hctab           import HCTab
+from .hcviewport      import HCViewport
+from .hcvisualizers   import HCVisualizers
+from .hcwidgets       import HCWidgets
 
 __version__ = "1.0.0"
 
 __all__ = [
-    "Bindings",
-    "Cam",
-    "DefaultCam",
-    "Geo",
-    "Guides",
-    "NetworkEditor",
-    "Node",
-    "Panel",
-    "Pane",
-    "PathTab",
-    "Prefs",
-    "Radial",
-    "Session",
-    "SceneViewer",
-    "Status",
-    "Tab",
-    "Viewport",
-    "Visualizers",
-    "Widgets"
+    "HCBindings",
+    "HCCam",
+    "HCDefaultCam",
+    "HCGeo",
+    "HCGuides",
+    "HCNetworkEditor",
+    "HCNode",
+    "HCPane",
+    "HCPathTab",
+    "HCPrefs",
+    "HCRadial",
+    "HCSession",
+    "HCSceneViewer",
+    "HCStatus",
+    "HCTab",
+    "HCViewport",
+    "HCVisualizers",
+    "HCWidgets"
 ]
diff --git a/python3.11libs/hc/hccam.py b/python3.11libs/hc/hccam.py
index 651c81b..e156b7c 100644
--- a/python3.11libs/hc/hccam.py
+++ b/python3.11libs/hc/hccam.py
@@ -2,44 +2,41 @@ import hou
 from .hcgeo import HCGeo
 from .hcsceneviewer import HCSceneViewer
 
-"""
-Accepts 1 camera node object and 1 scene viewer object as arguments.
-"""
 
 class HCCam:
-    def __init__(self, node, scene_viewer):
-        self.node = node
+    def __init__(self, cam_node, scene_viewer):
+        self.cam_node = cam_node
         self.scene_viewer = scene_viewer
-        self.hc_scene_viewer = HCSceneViewer(scene_viewer)
-        self.node = node
-        self._t            = hou.Vector3(0, 0, 0)
-        self._r            = hou.Vector3(0, 0, 0)
-        self._p            = hou.Vector3(0, 0, 0)
-        self._ow           = 10
-        self._projection   = 'perspective'
-        self._resx         = 1000
-        self._resy         = 1000
+
+        self._t = hou.Vector3(0, 0, 0)
+        self._r = hou.Vector3(0, 0, 0)
+        self._p = hou.Vector3(0, 0, 0)
+        self._ow = 10
+        self._projection = 'perspective'
+        self._resx = 1000
+        self._resy = 1000
         self._aspect_ratio = 1
-        self.local_x       = hou.Vector3(1, 0, 0)
-        self.local_y       = hou.Vector3(0, 1, 0)
-        self.local_z       = hou.Vector3(0, 0, 1)
-        self.global_x      = hou.Vector3(1, 0, 0)
-        self.global_y      = hou.Vector3(0, 1, 0)
-        self.global_z      = hou.Vector3(0, 0, 1)
-        # self.zoom          = 10
-        self.delta_t       = 1
-        self.delta_r       = 15
-        self.delta_zoom    = 1
-        self.target        = None
+        self.local_x = hou.Vector3(1, 0, 0)
+        self.local_y = hou.Vector3(0, 1, 0)
+        self.local_z = hou.Vector3(0, 0, 1)
+        self.global_x = hou.Vector3(1, 0, 0)
+        self.global_y = hou.Vector3(0, 1, 0)
+        self.global_z = hou.Vector3(0, 0, 1)
+        # self.zoom = 10
+        self.delta_t = 1
+        self.delta_r = 15
+        self.delta_zoom = 1
+        self.target = None
 
         self.fitAspectRatio()
         self.lock()
         self.reset()
 
+
     """ Movement """
 
     def center(self):
-        centroid = self.hc_scene_viewer.geo().centroid()
+        centroid = self.scene_viewer.geo().centroid()
         self.t = hou.Vector3(centroid)
         self.p = hou.Vector3(centroid)
 
@@ -143,6 +140,64 @@ class HCCam:
         self.ow += self.delta_zoom * dir_map[dir]
 
 
+    """ Util """
+
+    def fitAspectRatio(self):
+        self.resx = 1000
+        self.resy = 1000
+        viewport = self.currentViewport()
+        ratio = viewport.size()[2] / viewport.size()[3]
+        self.aspect_ratio = ratio
+
+    def geo(self):
+        return self.scene_viewer.geo()
+
+    def lock(self):
+        viewport = self.currentViewport()
+        viewport.setCamera(self.cam_node)
+        viewport.lockCameraToView(1)
+
+    def reset(self):
+        self.t = hou.Vector3(0, 0, 2)
+        self.r = hou.Vector3(0, 0, 0)
+        self.p = hou.Vector3(0, 0, 0)
+        # self.zoom = 10
+        self.ow = 10
+        self.delta_t = 1
+        self.delta_r = 15
+        self.delta_zoom = 1
+        self.local_x = hou.Vector3(1, 0, 0)
+        self.local_y = hou.Vector3(0, 1, 0)
+        self.local_z = hou.Vector3(0, 0, 1)
+        self.global_x = hou.Vector3(1, 0, 0)
+        self.global_y = hou.Vector3(0, 1, 0)
+        self.global_z = hou.Vector3(0, 0, 1)
+
+    def setView(self):
+        view_map = {
+            'top':    hou.Vector3(270, 0, 0),
+            'bottom': hou.Vector3(90, 0, 0),
+            'front':  hou.Vector3(0, 180, 0),
+            'back':   hou.Vector3(0, 0, 0),
+            'right':  hou.Vector3(0, 90, 0),
+            'left':   hou.Vector3(0, 270, 0)
+        }
+        self.r = view_map[self.view]
+
+    def toggleProjection(self):
+        projection_map = {
+            'perspective': 'ortho',
+            'ortho': 'perspective'
+        }
+        self.projection = projection_map[self.projection]
+
+    def unlock(self):
+        self.viewport().lockCameraToView(0)
+
+    def currentViewport(self):
+        return self.scene_viewer.allViewports()[3]
+
+
     """ Props """
 
     @property
@@ -151,7 +206,7 @@ class HCCam:
     @t.setter
     def t(self, val):
         self._t = val
-        self.node.parmTuple('t').set(val)
+        self.cam_node.parmTuple('t').set(val)
 
     @property
     def r(self):
@@ -159,7 +214,7 @@ class HCCam:
     @r.setter
     def r(self, val):
         self._r = val
-        self.node.parmTuple('r').set(val)
+        self.cam_node.parmTuple('r').set(val)
 
     @property
     def p(self):
@@ -174,7 +229,7 @@ class HCCam:
     @ow.setter
     def ow(self, val):
         self._ow = val
-        self.node.parm('orthowidth').set(val)
+        self.cam_node.parm('orthowidth').set(val)
 
     @property
     def projection(self):
@@ -182,7 +237,7 @@ class HCCam:
     @projection.setter
     def projection(self, val):
         self._projection = val
-        self.node.parm('projection').set(val)
+        self.cam_node.parm('projection').set(val)
 
     @property
     def resx(self):
@@ -190,7 +245,7 @@ class HCCam:
     @resx.setter
     def resx(self, val):
         self._resx = val
-        self.node.parm('resx').set(val)
+        self.cam_node.parm('resx').set(val)
 
     @property
     def resy(self):
@@ -198,7 +253,7 @@ class HCCam:
     @resy.setter
     def resy(self, val):
         self._resy = val
-        self.node.parm('resy').set(val)
+        self.cam_node.parm('resy').set(val)
 
     @property
     def aspect_ratio(self):
@@ -206,61 +261,5 @@ class HCCam:
     @aspect_ratio.setter
     def aspect_ratio(self, val):
         self._aspect_ratio = val
-        self.node.parm('aspect').set(val)
-
-    """ Util """
-
-    def fitAspectRatio(self):
-        self.resx = 1000
-        self.resy = 1000
-        ratio = self.viewport().size()[2] / self.viewport().size()[3]
-        self.aspect_ratio = ratio
-
-    def geo(self):
-        return self.hc_scene_viewer.geo()
-
-    def lock(self):
-        hc_viewport = self.hc_viewport()
-        hc_viewport.setCamera(self.node)
-        hc_viewport.lockCameraToView(1)
-
-    def reset(self):
-        self.t          = hou.Vector3(0, 0, 2)
-        self.r          = hou.Vector3(0, 0, 0)
-        self.p          = hou.Vector3(0, 0, 0)
-        # self.zoom       = 10
-        self.ow         = 10
-        self.delta_t    = 1
-        self.delta_r    = 15
-        self.delta_zoom = 1
-        self.local_x    = hou.Vector3(1, 0, 0)
-        self.local_y    = hou.Vector3(0, 1, 0)
-        self.local_z    = hou.Vector3(0, 0, 1)
-        self.global_x   = hou.Vector3(1, 0, 0)
-        self.global_y   = hou.Vector3(0, 1, 0)
-        self.global_z   = hou.Vector3(0, 0, 1)
-
-    def setView(self):
-        view_map = {
-            'top':    hou.Vector3(270, 0, 0),
-            'bottom': hou.Vector3(90, 0, 0),
-            'front':  hou.Vector3(0, 180, 0),
-            'back':   hou.Vector3(0, 0, 0),
-            'right':  hou.Vector3(0, 90, 0),
-            'left':   hou.Vector3(0, 270, 0)
-        }
-        self.r = view_map[self.view]
-
-    def toggleProjection(self):
-        projection_map = {
-            'perspective': 'ortho',
-            'ortho':       'perspective'
-        }
-        self.projection = projection_map[self.projection]
-
-    def unlock(self):
-        self.viewport().lockCameraToView(0)
-
-    def viewport(self):
-        return self.hc_scene_viewer.allViewports()[3]
+        self.cam_node.parm('aspect').set(val)
 
diff --git a/python3.11libs/hc/hcdefaultcam.py b/python3.11libs/hc/hcdefaultcam.py
index 801bb5d..8f019ff 100644
--- a/python3.11libs/hc/hcdefaultcam.py
+++ b/python3.11libs/hc/hcdefaultcam.py
@@ -1,12 +1,13 @@
 import hou
 
 class HCDefaultCam:
-    def __init__(self, default_cam):
+    def __init__(self, default_cam, scene_viewer):
         self.default_cam = default_cam
+        self.scene_viewer = scene_viewer
 
     def frame(self):
-        for viewport in self.viewports():
-            hou_defaultcam = viewport.camera()
+        for viewport in self.scene_viewer.allViewports():
+            default_cam = viewport.camera()
             # Is cam default or node.
             if not hou_defaultcam:
                 viewport.frameAll()
diff --git a/python3.11libs/hc/hcguides.py b/python3.11libs/hc/hcguides.py
index 244d761..a68f311 100644
--- a/python3.11libs/hc/hcguides.py
+++ b/python3.11libs/hc/hcguides.py
@@ -5,32 +5,26 @@ class HCGuides:
         self.state = state
         self.cam_node = state.cam_node
         self.cam = state.cam
-        self.scene_viewer = hou_scene_viewer
-        self.hc_scene_viewer = hc_state.scene_viewer
-
-        self.options = {
-            'axis_size': 1,
-            'tie_axis_to_radius': 0
-        }
-
-        self.states = {
-            'cam_axis': 0,
-            'pivot_axis': 1,
-            'bbox': 0,
-            'perim': 0,
-            'pivot_2d': 0,
-            'pivot_3d': 0,
-            'ray': 0
-        }
+        self.scene_viewer = state.scene_viewer
+
+        self.axis_size = None
+        self.tie_axis_to_radius = None
+        self.cam_axis_enabled = None
+        self.pivot_axis_enabled = None
+        self.bbox_enabled = None
+        self.perim_enabled = None
+        self.pivot_2d_enabled = None
+        self.pivot_3d_enabled = None
+        self.ray_enabled = None
 
         self.cam_axis = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='cam_axis'
         )
 
         self.pivot_axis = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='pivot_axis',
             params={
@@ -39,7 +33,7 @@ class HCGuides:
         )
 
         self.bbox = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='bbox',
             params={
@@ -49,19 +43,19 @@ class HCGuides:
         )
 
         self.perim = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='perim'
         )
 
         self.pivot_2d = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='pivot_2d'
         )
 
         self.pivot_3d = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Face,
             name='pivot_3d',
             params={
@@ -71,7 +65,7 @@ class HCGuides:
         )
 
         self.ray = hou.GeometryDrawable(
-            scene_viewer=self.scene_viewer,
+            scene_viewer=self.scene_viewer.hou_tab,
             geo_type=hou.drawableGeometryType.Line,
             name='ray',
             params={
@@ -80,54 +74,65 @@ class HCGuides:
         )
 
     def draw(self, kwargs):
-        func_map = {
-            'bbox':       self.bbox.draw,
-            'cam_axis':   self.cam_axis.draw,
-            'pivot_axis': self.pivot_axis.draw,
-            'perim':      self.perim.draw,
-            'pivot_2d':   self.pivot_2d.draw,
-            'pivot_3d':   self.pivot_3d.draw,
-            'ray':        self.ray.draw
-        }
-        for name, value in self.states.items():
-            if value:
-                func_map[name](kwargs['draw_handle'], {})
+        draw_handle = kwargs['draw_handle']
+        if self.bbox_enabled: self.bbox.draw(draw_handle, {})
+        if self.cam_axis_enabled: self.cam_axis.draw(draw_handle, {})
+        if self.pivot_axis_enabled: self.pivot_axis.draw(draw_handle, {})
+        if self.perim_enabled: self.perim.draw(draw_handle, {})
+        if self.pivot_2d_enabled: self.pivot_2d.draw(draw_handle, {})
+        if self.pivot_3d_enabled: self.pivot_3d.draw(draw_handle, {})
+        if self.ray_enabled: self.ray.draw(draw_handle, {})
 
     def update(self):
-        func_map = {
-            'bbox':       self.makeBbox,
-            'cam_axis':   self.makeCamAxis,
-            'pivot_axis': self.makePivotAxis,
-            'perim':      self.makePerim,
-            'pivot_2d':   self.makePivot2d,
-            'pivot_3d':   self.makePivot3d,
-            'ray':        self.makeRay
-        }
-        for name, value in self.states.items():
-            if value:
-                func_map[name]()
-        # self.cam_axis.show(self.states['cam_axis'])
-        self.pivot_axis.show(self.states['pivot_axis'])
-        self.bbox.show(self.states['bbox'])
-        # self.cam.show(self.states['cam'])
-        # self.perim.show(self.states['perim'])
-        # self.pivot_2d.show(self.states['pivot_2d'])
-        self.pivot_3d.show(self.states['pivot_3d'])
-        # self.ray.show(self.states['ray'])
+        from hc import HCPrefs
+        prefs = HCPrefs().prefs().get('keycam').get('guides')
+        self.axis_size = prefs.get('axis_size')
+        self.tie_axis_to_radius = prefs.get('tie_axis_to_radius')
+        self.bbox_enabled = prefs.get('bbox_enabled')
+        self.cam_axis_enabled = prefs.get('cam_axis_enabled')
+        self.cam_geo_enabled = prefs.get('cam_geo_enabled')
+        self.pivot_axis_enabled = prefs.get('pivot_axis_enabled')
+        self.pivot_2d_enabled = prefs.get('pivot_2d_enabled')
+        self.pivot_3d_enabled = prefs.get('pivot_3d_enabled')
+        self.perim_enabled = prefs.get('perim_enabled')
+        self.ray_enabled = prefs.get('ray_enabled')
+
+        if self.bbox_enabled: self.makeBbox()
+        self.bbox.show(self.bbox_enabled)
+
+        if self.cam_axis_enabled: self.makeCamAxis()
+        self.cam_axis.show(self.cam_axis_enabled)
+
+        # if self.cam_geo_enabled: break
+
+        if self.pivot_axis_enabled: self.makePivotAxis()
+        self.pivot_axis.show(self.pivot_axis_enabled)
+
+        if self.perim_enabled: self.makePerim()
+        self.perim.show(self.perim_enabled)
+
+        if self.pivot_2d_enabled: self.makePivot2d()
+        self.pivot_2d.show(self.pivot_2d_enabled)
+
+        if self.pivot_3d_enabled: self.makePivot3d()
+        self.pivot_3d.show(self.pivot_3d_enabled)
+
+        if self.ray_enabled: self.makeRay()
+        self.ray.show(self.ray_enabled)
 
 
     """ Construction """
 
     def makeCamAxis(self):
         axes = (
-            self.hc_cam.local_x,
-            self.hc_cam.local_y,
-            self.hc_cam.local_z
+            self.cam.local_x,
+            self.cam.local_y,
+            self.cam.local_z
         )
         geo = hou.Geometry()
         for i in range(3):
-            P0 = self.hc_cam.t + axes[i]
-            P1 = self.hc_cam.t + axes[i] * -1
+            P0 = self.cam.t + axes[i]
+            P1 = self.cam.t + axes[i] * -1
             pts = geo.createPoints((P0, P1))
             poly = geo.createPolygon(is_closed=False)
             poly.addVertex(pts[0])
@@ -135,13 +140,11 @@ class HCGuides:
         self.cam_axis.setGeometry(geo)
 
     def makePivotAxis(self):
+        scale = self.axis_size
         axes = (
             self.cam.local_x,
             self.cam.local_y,
             self.cam.local_z
-            # hou.Vector3(1, 0, 0),
-            # hou.Vector3(0, 1, 0),
-            # hou.Vector3(0, 0, 1)
         )
         colors = (
             [1.0, 0.7, 0.7],
@@ -151,8 +154,8 @@ class HCGuides:
         geo = hou.Geometry()
         geo.addAttrib(hou.attribType.Point, 'Cd', (0.1, 0.1, 0.1))
         for i in range(3):
-            P0 = self.hc_cam.p + axes[i]
-            P1 = self.hc_cam.p + axes[i] * -1
+            P0 = self.cam.p + axes[i] * scale
+            P1 = self.cam.p + axes[i] * -scale
             pts = geo.createPoints((P0, P1))
             pts[0].setAttribValue('Cd', colors[i])
             pts[1].setAttribValue('Cd', colors[i])
@@ -166,7 +169,7 @@ class HCGuides:
 
     def makeBbox(self):
         guide_geo = hou.Geometry()
-        target_geo = self.hc_scene_viewer.geo()
+        target_geo = self.scene_viewer.geo()
         bbox = target_geo.bbox()
         box = hou.sopNodeTypeCategory().nodeVerb('box')
         box.setParms(
@@ -185,8 +188,8 @@ class HCGuides:
             {
                 'divs': 128,
                 'type': 1,
-                't':    self.hc_cam.p,
-                'scale': self.hc_cam.p.distanceTo(self.cam.t),
+                't':    self.cam.p,
+                'scale': self.cam.p.distanceTo(self.cam.t),
                 'orient': 2
             }
         )
@@ -228,7 +231,7 @@ class HCGuides:
                 'freq':  7,
                 'scale': scale,
                 'type':  1,
-                't':     self.hc_cam.p
+                't':     self.cam.p
             }
         )
         sphere.execute(guide_geo, [])
@@ -237,7 +240,7 @@ class HCGuides:
     def makeRay(self):
         guide_geo = hou.Geometry()
         guide_geo.addAttrib(hou.attribType.Point, 'Cd', (1, 0, 0))
-        pts = guide_geo.createPoints((self.hc_cam.p, self.hc_cam.t))
+        pts = guide_geo.createPoints((self.cam.p, self.cam.t))
         poly = guide_geo.createPolygon()
         poly.addVertex(pts[0])
         poly.addVertex(pts[1])
diff --git a/python3.11libs/hc/hclayouts.py b/python3.11libs/hc/hclayouts.py
index 728230b..6dc4bb8 100644
--- a/python3.11libs/hc/hclayouts.py
+++ b/python3.11libs/hc/hclayouts.py
@@ -1,41 +1,41 @@
 from .hcsession import HCSession
 
 def setLayoutQuad(self):
-    hc_session = HCSession()
-    hc_session.clearLayout()
-    hc_session.allTabs()[0].setType("PythonShell")
-    hc_session.allPanes()[0].splitHorizontal()
-    hc_session.allPanes()[0].splitVertical()
-    hc_session.allPanes()[1].splitVertical()
+    session = HCSession()
+    session.clearLayout()
+    session.allTabs()[0].setType("PythonShell")
+    session.allPanes()[0].splitHorizontal()
+    session.allPanes()[0].splitVertical()
+    session.allPanes()[1].splitVertical()
 
 def setLayoutRamp(self):
-    hc_session = HCSession()
-    hc_session.removeEventLoopCallbacks()
-    hc_session.clearLayout()
-    hc_session.allPanes()[0].splitVertical()
-    hc_session.allTabs()[1].setType("Parm")
-    hc_session.allPanes()[1].setSplitRatio(0.3)
-    hc_session.allPanes()[1].createTab()
+    session = HCSession()
+    session.removeEventLoopCallbacks()
+    session.clearLayout()
+    session.allPanes()[0].splitVertical()
+    session.allTabs()[1].setType("Parm")
+    session.allPanes()[1].setSplitRatio(0.3)
+    session.allPanes()[1].createTab()
 
 def setLayoutTriH(self):
-    hc_session = HCSession()
-    hc_session.removeEventLoopCallbacks()
-    hc_session.clearLayout()
+    session = HCSession()
+    session.removeEventLoopCallbacks()
+    session.clearLayout()
     # Make panes
-    hc_session.allTabs()[0].setType("PythonShell")
-    hc_session.allPanes()[0].splitHorizontal()
-    hc_session.allPanes()[1].splitHorizontal()
+    session.allTabs()[0].setType("PythonShell")
+    session.allPanes()[0].splitHorizontal()
+    session.allPanes()[1].splitHorizontal()
     # Make tabs
-    hc_session.allPanes()[1].createTab("PythonShell")
-    hc_session.allPanes()[1].allTabs()[0].setIsCurrentTab()
+    session.allPanes()[1].createTab("PythonShell")
+    session.allPanes()[1].allTabs()[0].setIsCurrentTab()
     # Set types
-    hc_session.allPanes()[0].allTabs()[0].setType("SceneViewer")
-    hc_session.allPanes()[1].allTabs()[0].setType("Parm")
-    hc_session.allPanes()[1].allTabs()[1].setType("DetailsView")
-    hc_session.allPanes()[2].allTabs()[0].setType("NetworkEditor")
+    session.allPanes()[0].tabs()[0].setType("SceneViewer")
+    session.allPanes()[1].tabs()[0].setType("Parm")
+    session.allPanes()[1].tabs()[1].setType("DetailsView")
+    session.allPanes()[2].tabs()[0].setType("NetworkEditor")
     # Ratios
-    hc_session.allPanes()[0].setSplitFraction(0.5)
-    hou.session.last_pane = self.pane()
+    session.allPanes()[0].setSplitFraction(0.5)
+    session.prev_pane = self.pane()
     hou.ui.addEventLoopCallback(triHCallback)
 
 def triHCallback(session):
@@ -55,17 +55,17 @@ def setLayoutTriV(session):
     # Reset layout
     session.clearLayout()
     # Make panes
-    session.allPanes()[0].allTabs()[0].setType("PythonShell")
+    session.allPanes()[0].tabs()[0].setType("PythonShell")
     session.allPanes()[0].splitHorizontal()
     session.allPanes()[1].splitVertical()
     # Make pane tabs
     session.allPanes()[1].createTab("PythonShell")
     session.allPanes()[1].allTabs()[0].setIsCurrentTab()
     # Set types
-    session.allPanes()[0].allTabs()[0].setType("SceneViewer")
-    session.allPanes()[1].allTabs()[0].setType("Parm")
-    session.allPanes()[1].allTabs()[1].setType("DetailsView")
-    session.allPanes()[2].allTabs()[0].setType("NetworkEditor")
+    session.allPanes()[0].tabs()[0].setType("SceneViewer")
+    session.allPanes()[1].tabs()[0].setType("Parm")
+    session.allPanes()[1].tabs()[1].setType("DetailsView")
+    session.allPanes()[2].tabs()[0].setType("NetworkEditor")
     # Set ratios
     session.allPanes()[0].setSplitFraction(0.66)
     # Ok
diff --git a/python3.11libs/hc/hcmenuutils.py b/python3.11libs/hc/hcmenuutils.py
index a8f7701..9b31488 100644
--- a/python3.11libs/hc/hcmenuutils.py
+++ b/python3.11libs/hc/hcmenuutils.py
@@ -1,6 +1,5 @@
 import hou
 
-
 def vector3Test(kwargs):
     parms = kwargs['parms']
     print(parms[0])
diff --git a/python3.11libs/hc/hcnetworkeditor.py b/python3.11libs/hc/hcnetworkeditor.py
index 76f089a..d3c34d0 100644
--- a/python3.11libs/hc/hcnetworkeditor.py
+++ b/python3.11libs/hc/hcnetworkeditor.py
@@ -1,41 +1,110 @@
 import hou, math, types
-from .pathtab import PathTab
-from .prefs import Prefs
+from .hcpathtab import HCPathTab
+from .hcprefs import HCPrefs
 
 
-class NetworkEditor(PathTab):
+class HCNetworkEditor(HCPathTab):
     def __init__(self, hou_tab):
         self.hou_tab = hou_tab
         self.delta_t = 2
+        self.network_node = self.pwd()
 
-    """ Move network objects """
 
-    def arrangeNodes(self):
+    """ Selection """
+
+
+    def addToSelection(self, direction):
         return
+        print(direction)
+        # direction_map = {
+            # 'left':
+            # 'down':
+            # 'up':
+            # 'right':
+        # }
+
+    def currentNode(self):
+        return self.hou_tab.currentNode()
+
+    def deselectAllNodes(self):
+        self.hou_tab.clearAllSelected()
+
+    def selectAllNodes(self):
+        nodes = self.network_node.children()
+        for node in nodes:
+            node.setSelected(True)
+
+
+    """ Connectivity """
+
+
+    def chunk(self):
+        search_nodes = [self.currentNode()]
+        tree = []
+        search = True
+        while search:
+            if len(search_nodes) == 0:
+                break
+            for node in search_nodes:
+                tree.append(node)
+                search_nodes.remove(node)
+                input_nodes = node.inputs()
+                output_nodes = node.outputs()
+                search_nodes.append(input_nodes)
+                search_nodes.append(output_nodes)
+            continue
+        return tree
+
+
+
+    def chunks(self):
+        nodes = self.network_node.children()
+        # for node in nodes:
+
+
+
+    """ Flags """
+
+
+    def setDisplayFlag(self):
+        self.currentNode().setDisplayFlag(True)
+        self.currentNode().setRenderFlag(True)
+
+    def toggleBypassFlag(self):
+        self.currentNode().bypass(not self.currentNode().isBypassed())
+
+    def toggleTemplateFlag(self):
+        self.currentNode().setTemplateFlag(not self.currentNode().isTemplateFlagSet())
+
+
+    """ Objects and node control """
+
 
     def snapToGrid(self, node):
-        P = node.position()
-        P[0] = round(P[0] - 0.5) + 0.5
-        P[1] = round(P[1] - 0.85) + 0.85
-        node.setPosition(P)
+        pos = node.position()
+        pos[0] = round(pos[0] - 0.5) + 0.5
+        pos[1] = round(pos[1] - 0.85) + 0.85
+        node.setPosition(pos)
 
-    def translateNodes(self, direction):
-        for node in self.pwd().selectedChildren():
+    def translateSelectedNodes(self, direction):
+        for node in self.selectedNodes():
             self.snapToGrid(node)
-            P = node.position()
+            pos = node.position()
             # do the move
             if direction == 'up':
-                P[1] += 1
+                pos[1] += 1
             elif direction == 'down':
-                P[1] -= 1
+                pos[1] -= 1
             elif direction == 'left':
-                P[0] -= 1
+                pos[0] -= 1
             elif direction == 'right':
-                P[0] += 1
-            node.setPosition(P)
+                pos[0] += 1
+            node.setPosition(pos)
+
 
     """ Viewport """
 
+
     def bounds(self):
         return self.hou_tab.visibleBounds()
 
@@ -78,7 +147,9 @@ class NetworkEditor(PathTab):
         zoomlevel = self.size()[0] / self.size()[0]
         return zoomlevel
 
-    """ Interface states & utils """
+
+    """ Interface"""
+
 
     def isMenuOpen(self):
         value = self.hou_tab.getPref('showmenu')
@@ -91,7 +162,7 @@ class NetworkEditor(PathTab):
         self.hou_tab.flashMessage(image=None, message=self.path(), duration=1)
 
     # def showRadialMenu(self):
-        # from .radialutils import editorRadialMain
+        # from .hcradialutils import editorRadialMain
         # menu = editorRadialMain()
         # self.hou_tab.displayRadialMenu("hc_editor_radial_menu")
 
@@ -120,10 +191,11 @@ class NetworkEditor(PathTab):
         mode = self.hou_tab.getPref('showmenu')
         self.hou_tab.setPref('showmenu', map[mode])
 
+
     """ Utility """
 
     def type(self):
-        return "NetworkEditor"
+        return "HCNetworkEditor"
 
     def reloadNodeShapes(self):
         self.hou_tab.reloadNodeShapes()
@@ -135,7 +207,7 @@ class NetworkEditor(PathTab):
             node.setName(name[1])
 
     def setNodeColors(self):
-        color = hou.ui.selectColor(hou.Color(Prefs().node_color))
+        color = hou.ui.selectColor(hou.Color(HCPrefs().node_color))
         nodes = self.pwd().selectedChildren()
         for node in nodes:
             node.setColor(color)
diff --git a/python3.11libs/hc/hcnode.py b/python3.11libs/hc/hcnode.py
index b09bc28..699cb99 100644
--- a/python3.11libs/hc/hcnode.py
+++ b/python3.11libs/hc/hcnode.py
@@ -1,27 +1,27 @@
-from .geo import Geo
+from .hcgeo import HCGeo
 import hou
 
-class Node:
+class HCNode:
     def __init__(self, hou_node):
         self.hou_node = hou_node
 
 
     """ Selection """
 
+    def allChildren(self):
+        nodes = []
+        for hou_node in self.hou_node.children():
+            nodes.append(__class__(hou_node))
+        return nodes
+
     def currentNode(self):
         return self.__class__(self.hou_node.currentNode())
 
-    def deselectAll(self):
-        for child in self.selectedChildren():
-            child.setSelected(False)
-
-    def selectAllChildren(self):
-        for child in self.children():
-            child.setSelected(True)
-
     def selectedChildren(self):
-        hou_nodes = self.hou_node.selectedChildren()
-        return [self.__class__(hou_node) for hou_node in hou_nodes]
+        nodes = []
+        for node in self.hou_node.selectedChildren():
+            nodes.append(self.__class__(hou_node))
+        return nodes
 
     def setSelected(self, state):
         self.hou_node.setSelected(state)
@@ -30,9 +30,9 @@ class Node:
     """ Visibility """
 
     def displayNode(self):
-        display_node = self.hou_node.displayNode()
+        hou_display_node = self.hou_node.displayNode()
         if display_node:
-            return self.__class__(display_node)
+            return self.__class__(hou_display_node)
         else:
             return None
 
@@ -41,12 +41,12 @@ class Node:
         visible_nodes = []
 
         while stack:
-            node = stack.pop()
-            if node.hou_node.isSubNetwork():
-                child_cat = node.childCat()
-                if child_cat == 'Object' and node.hou_node.isDisplayFlagSet():
+            hc_node = stack.pop()
+            if hc_node.node.isSubNetwork():
+                child_cat = hc_node.childCat()
+                if child_cat == 'Object' and hc_node.node.isDisplayFlagSet():
                     stack.extend(node.children())
-                elif child_cat == 'Sop' and node.hou_node.isDisplayFlagSet():
+                elif child_cat == 'Sop' and hc_node.node.isDisplayFlagSet():
                     display_node = node.displayNode()
                     if display_node:
                         visible_nodes.append(display_node)
@@ -59,7 +59,7 @@ class Node:
     def geometry(self):
         return self.hou_node.geometry()
 
-    def hou_geo(self):
+    def geo(self):
         geo = hou.Geometry()
         for node in self.visibleNodes():
             geo.merge(node.geometry())
@@ -74,10 +74,13 @@ class Node:
 
     def children(self):
         hou_nodes = self.hou_node.children()
-        return [self.__class__(hou_node) for hou_node in hou_nodes]
+        nodes = []
+        for hou_node in hou_nodes:
+            nodes.append(self.__class__(hou_node))
+        return nodes
 
     def netPos(self):
-        """ net editor xy position """
+        """ Network editor xy position """
         return self.hou_node.position()
 
 
diff --git a/python3.11libs/hc/hcpane.py b/python3.11libs/hc/hcpane.py
index 8ff0941..3be0533 100644
--- a/python3.11libs/hc/hcpane.py
+++ b/python3.11libs/hc/hcpane.py
@@ -1,33 +1,35 @@
 import hou
-from .hctab           import HCTab
-from .hcpathtab       import HCPathTab
-from .hcsceneviewer   import HCSceneViewer
+from .hctab import HCTab
+from .hcpathtab import HCPathTab
+from .hcsceneviewer import HCSceneViewer
 from .hcnetworkeditor import HCNetworkEditor
 
 class HCPane:
-    def __init__(self, pane):
-        self.pane = pane
+    def __init__(self, hou_pane):
+        self.hou_pane = hou_pane
 
-    """ Pane """
+    """ Adjust size """
 
-    def close(self):
-        for hc_tab in self.allHCTabs():
-            hc_tab.close()
+    def setIsMaximized(self, bool):
+        self.hou_pane.setIsMaximized(bool)
 
-    def isMaximized(self):
-        return self.pane.isMaximized()
+    def setIsSplitMaximized(self, bool):
+        self.hou_pane.setIsSplitMaximized(bool)
 
-    def qtScreenGeometry(self):
-        return self.pane.qtScreenGeometry()
+    def setSplitFraction(self, fraction):
+        self.hou_pane.setSplitFraction(fraction)
 
-    def setIsMaximized(self, bool):
-        self.pane.setIsMaximized(bool)
+    def splitHorizontal(self):
+        self.hou_pane.splitHorizontally()
 
-    def toggleMaximize(self):
-        self.pane.setIsMaximized(not self.isMaximized())
+    def splitRotate(self):
+        self.hou_pane.splitRotate()
 
+    def splitSwap(self):
+        self.hou_pane.splitSwap()
 
-    """ Split """
+    def splitVertical(self):
+        self.hou_pane.splitVertically()
 
     def contract(self):
         fraction = round(self.splitFraction(), 3) + 0.1
@@ -39,12 +41,6 @@ class HCPane:
         self.setSplitFraction(fraction)
         hou.ui.setStatusMessage("Pane fraction: " + str(fraction))
 
-    def isSplitMaximized(self):
-        return self.pane.isSplitMaximized()
-
-    def setIsSplitMaximized(self, bool):
-        self.pane.setIsSplitMaximized(bool)
-
     def setRatioHalf(self):
         self.setSplitFraction(0.5)
 
@@ -54,72 +50,88 @@ class HCPane:
     def setRatioThird(self):
         self.setSplitFraction(0.333)
 
-    def setSplitFraction(self, fraction):
-        self.pane.setSplitFraction(fraction)
+    def toggleSplitMaximized(self):
+        self.setIsSplitMaximized(not self.isSplitMaximized())
 
-    def splitFraction(self):
-        return self.pane.getSplitFraction()
+    def toggleMaximize(self):
+        self.hou_pane.setIsMaximized(not self.isMaximized())
 
-    def splitHorizontal(self):
-        self.pane.splitHorizontally()
 
-    def splitRotate(self):
-        self.pane.splitRotate()
+    """ Size info """
 
-    def splitSwap(self):
-        self.pane.splitSwap()
+    def isMaximized(self):
+        return self.hou_pane.isMaximized()
 
-    def splitVertical(self):
-        self.pane.splitVertically()
+    def qtScreenGeometry(self):
+        return self.hou_pane.qtScreenGeometry()
+
+    def isSplitMaximized(self):
+        return self.hou_pane.isSplitMaximized()
+
+    def splitFraction(self):
+        return self.hou_pane.getSplitFraction()
 
-    def toggleSplitMaximized(self):
-        self.setIsSplitMaximized(not self.isSplitMaximized())
 
+    """ Tabs """
 
-    """ Interface """
-
-    def allHCTabs(self):
-        hc_tabs = []
-        for tab in self.pane.tabs():
-            hc_tabs.append(HCTab(tab))
-        return hc_tabs
-
-    def convertTab(self, tab):
-        tab_type = tab.type()
-        if tab_type == hou.paneTabType.SceneViewer:
-            return HCSceneViewer(tab)
-        elif tab_type == hou.paneTabType.NetworkEditor:
-            return HCNetworkEditor(tab)
-        elif tab_type == hou.paneTabType.DetailsView:
-            return HCPathTab(tab)
-        elif tab_type == hou.paneTabType.Parm:
-            return HCPathTab(tab)
+    def close(self):
+        for tab in self.tabs():
+            tab.close()
+
+    def convertTab(self, hou_tab):
+        hou_tab_type = hou_tab.type()
+        if hou_tab_type == hou.paneTabType.SceneViewer:
+            return HCSceneViewer(hou_tab)
+        elif hou_tab_type == hou.paneTabType.NetworkEditor:
+            return HCNetworkEditor(hou_tab)
+        elif hou_tab_type == hou.paneTabType.DetailsView:
+            return HCPathTab(hou_tab)
+        elif hou_tab_type == hou.paneTabType.Parm:
+            return HCPathTab(hou_tab)
         else:
-            return HCTab(tab)
+            return HCTab(hou_tab)
 
-    def currentHCTab(self):
-        tab = self.pane.currentTab()
-        return self.convertTab(tab)
+    def currentTab(self):
+        hou_tab = self.hou_pane.currentTab()
+        return self.convertTab(hou_tab)
 
     def isShowingTabs(self):
-        return self.pane.isShowingPaneTabs()
+        return self.hou_pane.isShowingPaneTabs()
+
+    def newTab(self, tab_type, python_panel_interface=None):
+        # self.tab.
+        return
 
     def nextTab(self):
-        tabs = self.pane.tabs()
-        tab = self.pane.currentTab()
-        index = tabs.index(tab)
-        index = (index + 1) % len(tabs)
-        tabs[index].setIsCurrentTab()
-
-    def previousTab(self):
-        tabs = self.pane.tabs()
-        tab = self.pane.currentTab()
-        index = tabs.index(tab)
-        index = (index - 1) % len(tabs)
-        tabs[index].setIsCurrentTab()
+        tabs = self.tabs()
+        tab_names = self.tabNames()
+        current_tab_name = self.currentTab().name()
+        current_tab_index = tab_names.index(current_tab_name)
+        new_tab_index = (current_tab_index + 1) % len(tabs)
+        tabs[new_tab_index].setCurrent()
+
+    def prevTab(self):
+        tabs = self.tabs()
+        tab_names = self.tabNames()
+        current_tab_name = self.currentTab().name()
+        current_tab_index = tab_names.index(current_tab_name)
+        new_tab_index = (current_tab_index - 1) % len(tabs)
+        tabs[new_tab_index].setCurrent()
 
     def showTabs(self, value):
-        self.pane.showPaneTabs(value)
+        self.hou_pane.showPaneTabs(value)
+
+    def tabs(self):
+        tabs = []
+        for hou_tab in self.hou_pane.tabs():
+            tabs.append(HCTab(hou_tab))
+        return tabs
+
+    def tabNames(self):
+        tab_names = []
+        for tab in self.tabs():
+            tab_names.append(tab.name())
+        return tab_names
 
     def toggleTabs(self):
         self.showTabs(not self.isShowingTabs())
diff --git a/python3.11libs/hc/hcpathtab.py b/python3.11libs/hc/hcpathtab.py
index 3d4991d..7250b7b 100644
--- a/python3.11libs/hc/hcpathtab.py
+++ b/python3.11libs/hc/hcpathtab.py
@@ -4,8 +4,8 @@ from .hcnode import HCNode
 from .hctab  import HCTab
 
 class HCPathTab(HCTab):
-    def __init__(self, tab):
-        self.tab = tab
+    def __init__(self, hou_tab):
+        self.hou_tab = hou_tab
 
     def hcGeo(self):
         return HCGeo(self.geo())
@@ -21,4 +21,11 @@ class HCPathTab(HCTab):
         return self.pwd().path()
 
     def pwd(self):
-        return Node(self.tab.pwd())
+        return HCNode(self.hou_tab.pwd())
+
+    def selectedNodes(self):
+        nodes = self.hou_tab.pwd().selectedChildren()
+        hc_nodes = []
+        for node in nodes:
+            hc_nodes.append(HCNode(node))
+        return hc_nodes
diff --git a/python3.11libs/hc/hcprefs.py b/python3.11libs/hc/hcprefs.py
index e653abb..331ef4c 100644
--- a/python3.11libs/hc/hcprefs.py
+++ b/python3.11libs/hc/hcprefs.py
@@ -1,3 +1,14 @@
+import hou
+import json
+from pathlib import Path
+
 class HCPrefs:
     def __init__(self):
-        self.node_color = (0.28, 0.35, 0.4)
+        self.node_color = (0.38, 0.38, 0.56)
+
+    def prefs(self):
+        base_path = hou.getenv('HC_PATH')
+        config_file = Path(base_path) / "scripts" / "settings.json"
+        if config_file.exists():
+            data = json.loads(config_file.read_text())
+            return data
diff --git a/python3.11libs/hc/hcradial.py b/python3.11libs/hc/hcradial.py
index 6c71145..837626d 100644
--- a/python3.11libs/hc/hcradial.py
+++ b/python3.11libs/hc/hcradial.py
@@ -4,7 +4,7 @@ import hou
 # PaneTab object is retrieved by calling kwargs["pane"]
 #
 
-class Radial:
+class HCRadial:
     def __init__(self):
         return
 
diff --git a/python3.11libs/hc/hcsceneviewer.py b/python3.11libs/hc/hcsceneviewer.py
index 299f0e8..896659e 100644
--- a/python3.11libs/hc/hcsceneviewer.py
+++ b/python3.11libs/hc/hcsceneviewer.py
@@ -37,14 +37,15 @@ setViewportLayout(layout, single=-1)
 """
 
 class HCSceneViewer(HCPathTab):
-    def __init__(self, tab):
-        self.tab = tab
+    def __init__(self, hou_tab):
+        self.hou_tab = hou_tab
+
 
     """ Geometry """
 
     def allDisplaySets(self):
         displaySets = []
-        for hc_viewport in self.allHCViewports():
+        for hc_viewport in self.allViewports():
             settings = hc_viewport.settings()
             displaySet = settings.displaySet(hou.displaySetType.DisplayModel)
             displaySets.append(displaySet)
@@ -108,7 +109,7 @@ class HCSceneViewer(HCPathTab):
             displaySet.showPrimNumbers(not visible)
 
     def toggleVectors(self):
-        for hc_viewport in self.allHCViewports():
+        for viewport in self.allViewports():
             settings = viewport.settings()
             scale = settings.vectorScale()
             if scale == 1:
@@ -121,7 +122,7 @@ class HCSceneViewer(HCPathTab):
     """ Grids """
 
     def referencePlane(self):
-        return self.tab.referencePlane()
+        return self.hou_tab.referencePlane()
 
     def toggleGrid(self):
         reference_plane = self.referencePlane()
@@ -131,7 +132,7 @@ class HCSceneViewer(HCPathTab):
     """ Layout """
 
     def layout(self):
-        return self.tab.viewportLayout()
+        return self.hou_tab.viewportLayout()
 
     def layouts(self):
         return (
@@ -176,34 +177,34 @@ class HCSceneViewer(HCPathTab):
             "TripleBottomSplit": hou.geometryViewportLayout.TripleBottomSplit,
             "TripleLeftSplit":   hou.geometryViewportLayout.TripleLeftSplit
         }
-        self.tab.setViewportLayout(layout_map[layout])
+        self.hou_tab.setViewportLayout(layout_map[layout])
 
 
     """ UI """
 
     def isVisibleDisplayBar(self):
-        return self.tab.isShowingDisplayOptionsBar()
+        return self.hou_tab.isShowingDisplayOptionsBar()
 
     def isVisibleGroupList(self):
-        return self.tab.isGroupListVisible()
+        return self.hou_tab.isGroupListVisible()
 
     def isVisibleOperationBar(self):
-        return self.tab.isShowingOperationBar()
+        return self.hou_tab.isShowingOperationBar()
 
     def isVisibleSelectionBar(self):
-        return self.tab.isShowingSelectionBar()
+        return self.hou_tab.isShowingSelectionBar()
 
     def showDisplayBar(self, value):
-        self.tab.showDisplayOptionsBar(value)
+        self.hou_tab.showDisplayOptionsBar(value)
 
     def showGroupList(self, value):
-        self.tab.setGroupListVisible(value)
+        self.hou_tab.setGroupListVisible(value)
 
     def showOperationBar(self, value):
-        self.tab.showOperationBar(value)
+        self.hou_tab.showOperationBar(value)
 
     def showSelectionBar(self, value):
-        self.tab.showSelectionBar(value)
+        self.hou_tab.showSelectionBar(value)
 
     def toggleDisplayBar(self):
         self.showDisplayBar(not self.isVisibleDisplayBar())
@@ -218,7 +219,7 @@ class HCSceneViewer(HCPathTab):
         self.showSelectionBar(not self.isVisibleSelectionBar())
 
     def toggleBars(self):
-        state = self.tab.isShowingOperationBar() + self.tab.isShowingDisplayOptionsBar() + self.tab.isShowingSelectionBar()
+        state = self.hou_tab.isShowingOperationBar() + self.hou_tab.isShowingDisplayOptionsBar() + self.hou_tab.isShowingSelectionBar()
         if state > 0:
             self.showOperationBar(0)
             self.showDisplayBar(0)
@@ -228,25 +229,17 @@ class HCSceneViewer(HCPathTab):
             self.showDisplayBar(1)
             self.showSelectionBar(1)
 
+
     """ Utils """
 
     def type(self):
         return "HCSceneViewer"
 
     def keycam(self):
-        """
-        Contexts:
-        Chop, ChopNet, Cop, Cop2, CopNet, Data, Director, Dop, Driver, Lop, Manager, Object, Shop, Sop, Top, TopNet, Vop, VopNet
-        """
-        context_map = {
-            "Object": "Keycam obj context",
-            "Sop": "Keycam sop context",
-            "Lop": "Keycam lop context",
-        }
+        contexts = ('Object', 'Sop', "Lop")
         context = self.pwd().childCat()
-        if context in context_map:
-            self.tab.setCurrentState('keycam')
-            hou.ui.setStatusMessage(context_map[context])
+        if context in contexts:
+            self.hou_tab.setCurrentState('keycam')
         else:
             hou.ui.setStatusMessage("No obj, sop or lop context", hou.severityType.Error)
 
@@ -254,21 +247,21 @@ class HCSceneViewer(HCPathTab):
     """ Viewports """
 
     def homeAllViewports(self):
-        for hc_viewport in self.allHCViewports():
-            hc_viewport.home()
+        for viewport in self.allViewports():
+            viewport.home()
 
-    def currentHCViewport(self):
-        return self.tab.curViewport()
+    def currentViewport(self):
+        return self.hou_tab.curViewport()
 
-    def allHCViewports(self):
-        hc_viewports = []
-        for viewport in self.tab.viewports():
-            hc_viewports.append(HCViewport(viewport))
-        return hc_viewports()
+    def allViewports(self):
+        viewports = []
+        for viewport in self.hou_tab.viewports():
+            viewports.append(HCViewport(viewport))
+        return viewports
 
     def frameAllViewports(self):
-        for hc_viewport in self.allHCViewports():
-            cam = hc_viewport.camera()
+        for viewport in self.allViewports():
+            cam = viewport.camera()
             # Is camera node or default
             if not cam:
                 viewport.frameAll()
diff --git a/python3.11libs/hc/hcsession.py b/python3.11libs/hc/hcsession.py
index c1890fd..d261b8f 100644
--- a/python3.11libs/hc/hcsession.py
+++ b/python3.11libs/hc/hcsession.py
@@ -5,111 +5,105 @@ from .hcsceneviewer import HCSceneViewer
 from .hcpane import HCPane
 from .hcpathtab import HCPathTab
 from .hctab import HCTab
+from .hcwidgets import HCWidgets
 
 
-class Session:
+class HCSession:
     def __init__(self):
         return
 
-    """ Context """
 
-    def currentNode(self):
-        return self.currentHCTab().currentNode()
+    """ Return HC Objects """
 
-    def projectPath(self):
-        return hou.hipFile.path()
-
-
-    """
-    Layout
-    'allTabs' and 'currentTab' do not use hou.ui.paneTabUnderCursor method
-    """
-
-    def allHCNetworkEditors(self):
-        hc_network_editors = []
-        for hc_tab in self.allHCTabs():
-            if hc_tab.type() == "NetworkEditor":
-                hc_network_editors.append(tab)
-        return hc_network_editors
+    def allNetworkEditors(self):
+        network_editors = []
+        for tab in self.allTabs():
+            if tab.type() == 'HCNetworkEditor':
+                network_editors.append(tab)
+        return network_editors
 
-    def allHCPanes(self):
-        hc_panes = []
+    def allPanes(self):
+        panes = []
         for pane in self.desktop().panes():
-            hc_panes.append(HCPane(pane))
+            panes.append(HCPane(pane))
         return panes
 
-    def allHCSceneViewers(self):
-        hc_scene_viewers = []
+    def allSceneViewers(self):
+        scene_viewers = []
         for tab in self.allTabs():
-            if tab.type() == "SceneViewer":
-                viewers.append(SceneViewer(tab))
-        return viewers
+            if tab.type() == 'HCSceneViewer':
+                scene_viewers.append(tab)
+        return scene_viewers
 
-    def allHCTabs(self):
+    def allTabs(self):
         tabs = []
         for pane in self.allPanes():
             for tab in pane.allTabs():
                 tabs.append(tab)
         return tabs
 
-    def allHCViewports(self):
-        hc_viewports = []
-        hc_scene_viewers = self.allHCSceneViewers
-        for hc_scene_viewer in hc_scene_viewers:
-            for hc_viewport in hc_scene_viewer.allHCCiewports():
-                hc_viewports.append(hc_viewport)
-        return hc_viewports
+    def allViewports(self):
+        viewports = []
+        scene_viewers = self.allSceneViewers
+        for scene_viewer in scene_viewers:
+            for viewport in scene_viewer.allViewports():
+                viewports.append(viewport)
+        return viewports
 
-    def clearLayout(self):
-        tabs = self.allTabs()
-        for tab in tabs:
-            if tab != tabs[0]:
-                tab.close()
-
-    def currentHCPane(self):
+    def currentPane(self):
         return HCPane(hou.ui.paneUnderCursor())
 
-    def currentHCTab(self):
-        return self.currentHCPane().currentHCTab()
+    def currentTab(self):
+        return self.currentPane().currentTab()
 
-    def desktop(self):
-        return hou.ui.curDesktop()
 
-    def printHCLayout(self):
-        panes = hou.ui.panes()
-        root = panes[0].getSplitParent()
-        lefts = []
-        tops = []
-        for pane in self.panes():
-            geo = pane.qtScreenGeometry()
-            lefts.append(geo.left())
-            tops.append(geo.top())
-        print(lefts)
-        print(tops)
-
-    def renameTabs(self):
-        tabs = hou.ui.paneTabs()
-        i = 0
-        for tab in tabs:
-            tab.setName('placeholder' + str(i))
-            i += 1
-        i = 0
-        for tab in tabs:
-            tab.setName('panetab' + str(i))
-            i += 1
+    """ Windows """
+
+    def colorEditor(self):
+        hou.ui.selectColor()
 
-    def layoutRoot(self):
-        root = hou.ui.panes()[0].getSplitParent().getSplitParent()
+    def floatingParameterEditor(self):
+        tab = self.currentTab()
+        if tab.type() == 'HCNetworkEditor':
+            hou.ui.showFloatingParameterEditor(self.currentNode())
+        else:
+            hou.ui.setStatusMessage('Not a network editor', hou.severityType.Error)
 
+    def hcPanel(self):
+        from .hcmaps import HCMaps
 
-    """ Settings """
+        pane = self.currentPane()
+        tab = self.currentTab()
+        tab_type = tab.type()
 
-    def isAutoSave(self):
-        return hou.getPreference('autoSave')
+        maps = HCMaps()
+        list_dict = maps.tab_map_base(self, pane, tab)
+        if tab_type == 'HCPathTab':
+            list_dict = list_dict | maps.tab_map_path(self, pane, tab)
+        elif tab_type == 'HCNetworkEditor':
+            list_dict = list_dict | maps.tab_map_network_editor(self, pane, tab)
+        elif tab_type == 'HCSceneViewer':
+            list_dict = list_dict | maps.tab_map_scene_viewer(self, pane, tab)
+
+
+        panel = HCWidgets.SelectionDialog('HC Panel', list_dict)
+        panel.show()
+        panel.raise_()
+        panel.activateWindow()
+
+    def openFile(self):
+        file = hou.ui.selectFile()
+        hou.hipFile.load(file)
 
     def openPreferences(self):
         hou.ui.openPreferences('ui', '')
 
+
+    """ Settings """
+
+    def isAutoSave(self):
+        return hou.getPreference('autoSave')
+
     def reloadColorSchemes(self):
         hou.ui.reloadColorScheme()
         hou.ui.reloadViewportColorSchemes()
@@ -138,8 +132,8 @@ class Session:
 
     def toggleUpdateMode(self):
         mode_map = {
-            "updateMode.AutoUpdate": hou.updateMode.Manual,
-            "updateMode.Manual": hou.updateMode.AutoUpdate
+            'updateMode.AutoUpdate': hou.updateMode.Manual,
+            'updateMode.Manual': hou.updateMode.AutoUpdate
         }
         hou.setUpdateMode(mode_map(str(hou.updateModeSetting)))
 
@@ -149,27 +143,13 @@ class Session:
 
     """ Utils """
 
-    def colorEditor(self):
-        hou.ui.selectColor()
-
-    def keycam(self):
-        msgmap = {
-            "Object": "Entered keycam in an obj/object context",
-            "Sop": "Entered keycam in a sop/geometry context",
-            "Lop": "Entered keycam in a lop context"
-        }
-        viewer = self.sceneViewers()[0]
-        category = viewer.pwd().childTypeCategory().name()
-        if category in msgmap:
-            viewer.setCurrentState('keycam')
-            hou.ui.setStatusMessage(msgmap[category])
-        else:
-            hou.ui.setStatusMessage("Keycam is only available in obj, sop and lop contexts",
-                hou.severityType.Error)
+    def projectPath(self):
+        return hou.hipFile.path()
 
-    def openFile(self):
-        file = hou.ui.selectFile()
-        hou.hipFile.load(file)
+    def reloadHC(self):
+        import importlib
+        import hc
+        importlib.reload(hc)
 
     def removeEventLoopCallbacks(self):
         callbacks = hou.ui.eventLoopCallbacks()
@@ -189,7 +169,45 @@ class Session:
         hou.hipFile.save()
 
 
-    """ Interface """
+    """ Layout """
+
+    # def clearLayout(self):
+    #     tabs = self.allTabs()
+    #     for tab in tabs:
+    #         if tab != tabs[0]:
+    #             tab.close()
+
+    def desktop(self):
+        return hou.ui.curDesktop()
+
+    # def layoutRoot(self):
+    #     root = hou.ui.panes()[0].getSplitParent().getSplitParent()
+
+    # def printLayout(self):
+    #     panes = hou.ui.panes()
+    #     root = panes[0].getSplitParent()
+    #     lefts = []
+    #     tops = []
+    #     for pane in self.panes():
+    #         geo = pane.qtScreenGeometry()
+    #         lefts.append(geo.left())
+    #         tops.append(geo.top())
+    #     print(lefts)
+    #     print(tops)
+
+    # def renameTabs(self):
+    #     tabs = hou.ui.paneTabs()
+    #     i = 0
+    #     for tab in tabs:
+    #         tab.setName('placeholder' + str(i))
+    #         i += 1
+    #     i = 0
+    #     for tab in tabs:
+    #         tab.setName('panetab' + str(i))
+    #         i += 1
+
+
+    """ Visibility """
 
     def isVisibleMainMenu(self):
         value = hou.getPreference('showmenu.val')
@@ -204,15 +222,15 @@ class Session:
             visible = 1
         # Tabs
         for tab in tabs:
-            if tab.type() == "NetworkEditor":
+            if tab.type() == 'HCNetworkEditor':
                 if tab.isMenuOpen():
                     visible = 1
                 elif tab.isShowingNetworkControls():
                     visible = 1
-            elif tab.type() == "PathTab":
+            elif tab.type() == 'HCPathTab':
                 if tab.isShowingNetworkControls():
                     visible = 1
-            elif tab.type() == "SceneViewer":
+            elif tab.type() == 'HCSceneViewer':
                 if tab.isShowingNetworkControls():
                     visible = 1
                 elif tab.isVisibleOperationBar():
@@ -227,13 +245,6 @@ class Session:
                 visible = 1
         return visible
 
-    def floatingParameterEditor(self):
-        tab = self.currentTab()
-        if tab.type() == "NetworkEditor":
-            hou.ui.showFloatingParameterEditor(self.currentNode())
-        else:
-            hou.ui.setStatusMessage("Not a network editor", hou.severityType.Error)
-
     def hideShelf(self):
         self.desktop().shelfDock().show(0)
 
@@ -254,12 +265,12 @@ class Session:
         # Set state
         self.showMainMenu((visible+1) % 2)
         for tab in tabs:
-            if tab.type() == "NetworkEditor":
+            if tab.type() == 'HCNetworkEditor':
                 tab.showNetworkControls(not visible)
                 tab.setMenuOpen(0)
-            elif tab.type() == "PathTab":
+            elif tab.type() == 'HCPathTab':
                 tab.showNetworkControls(not visible)
-            elif tab.type() == "SceneViewer":
+            elif tab.type() == 'HCSceneViewer':
                 tab.showNetworkControls(not visible)
                 tab.showOperationBar(not visible)
                 tab.showDisplayBar(not visible)
@@ -270,7 +281,7 @@ class Session:
         # hou.ui.setHideAllMinimizedStowbars(visible)
         # hou.ui.setHideAllMinimizedStowbars(visible)
 
-    def toggleNetworkControls(self):
+    def toggleAllNetworkControls(self):
         visible = 0
         tabs = self.allTabs()
         for tab in tabs:
@@ -286,7 +297,7 @@ class Session:
             hou.ui.setHideAllMinimizedStowbars(True)
             hou.ui.setHideAllMinimizedStowbars(True)
 
-    def toggleTabs(self):
+    def toggleAllTabs(self):
         visible = 0
         panes = self.allPanes()
         for pane in panes:
@@ -294,3 +305,5 @@ class Session:
                 visible = 1
         for pane in panes:
             pane.showTabs(not visible)
+
+
diff --git a/python3.11libs/hc/hctab.py b/python3.11libs/hc/hctab.py
index 9ae6bf9..42971b9 100644
--- a/python3.11libs/hc/hctab.py
+++ b/python3.11libs/hc/hctab.py
@@ -1,28 +1,35 @@
 import hou
 import types
-from .hcpane import HCPane
 
 class HCTab():
-    def __init__(self, tab):
-        self.tab = tab
+    def __init__(self, hou_tab):
+        self.hou_tab = hou_tab
 
-    #
-    # Tab
-    #
+    """ Status """
 
     def close(self):
-        self.tab.close()
+        self.hou_tab.close()
 
     def closeOtherTabs(self):
-        for tab in self.hcPane().allTabs():
+        from .hcpane import HCPane
+        for tab in self.pane().tabs():
             if tab != self.tab:
                 tab.close()
 
-    def hcPane(self):
-        return HCPane(self.tab.pane())
+    def name(self):
+        return self.hou_tab.name()
 
-    def hcType(self):
-        return "Tab"
+    def pane(self):
+        from .hcpane import HCPane
+        return HCPane(self.hou_tab.pane())
+
+    def setCurrent(self):
+        self.hou_tab.setIsCurrentTab()
+
+    """ Type """
+
+    def tab_type(self):
+        return 'HCTab'
 
     def setTypeDetailsView(self):
         self.setType(hou.paneTabType.DetailsView)
@@ -39,29 +46,62 @@ class HCTab():
     def setTypeSceneViewer(self):
         self.setType(hou.paneTabType.SceneViewer)
 
-    def setType(self, type):
-        tab = self.tab.setType(type)
+    def setType(self, tab_type):
+        tab_type_map = {
+            'AssetBrowser':       hou.paneTabType.AssetBrowser,
+            'ApexEditor':         hou.paneTabType.ApexEditor,
+            'BundleList':         hou.paneTabType.BundleList,
+            'ChannelEditor':      hou.paneTabType.ChannelEditor,
+            'ChannelList':        hou.paneTabType.ChannelList,
+            'ChannelViewer':      hou.paneTabType.ChannelViewer,
+            'CompositorViewer':   hou.paneTabType.CompositorViewer,
+            'ContextViewer':      hou.paneTabType.ContextViewer,
+            'DataTree':           hou.paneTabType.DataTree,
+            'DetailsView':        hou.paneTabType.DetailsView,
+            'EngineSessionSync':  hou.paneTabType.EngineSessionSync,
+            'HandleList':         hou.paneTabType.HandleList,
+            'HelpBrowser':        hou.paneTabType.HelpBrowser,
+            'IPRViewer':          hou.paneTabType.IPRViewer,
+            'LightLinker':        hou.paneTabType.LightLinker,
+            'MaterialPalette':    hou.paneTabType.MaterialPalette,
+            'NetworkEditor':      hou.paneTabType.NetworkEditor,
+            'OutputViewer':       hou.paneTabType.OutputViewer,
+            'Parm':               hou.paneTabType.Parm,
+            'ParmSpreadsheet':    hou.paneTabType.ParmSpreadsheet,
+            'PerformanceMonitor': hou.paneTabType.PerformanceMonitor,
+            'PythonPanel':        hou.paneTabType.PythonPanel,
+            'PythonShell':        hou.paneTabType.PythonShell,
+            'RenderGallery':      hou.paneTabType.RenderGallery,
+            'SceneViewer':        hou.paneTabType.SceneViewer,
+            'ShaderViewer':       hou.paneTabType.ShaderViewer,
+            'TakeList':           hou.paneTabType.TakeList,
+            'Textport':           hou.paneTabType.Textport,
+            'TreeView':           hou.paneTabType.TreeView
+        }
+        tab = self.hou_tab.setType(type)
         return tab
 
-    #
-    # UI
-    #
+
+    """ UI """
 
     def hasNetworkControls(self):
-        return self.tab.hasNetworkControls()
+        return self.hou_tab.hasNetworkControls()
+
+    def hcPanel(self, list_items):
+        HCSession.hcPanel(list_items)
 
     def isPin(self):
-        return self.tab.isPin()
+        return self.hou_tab.isPin()
 
     def isShowingNetworkControls(self):
-        value = self.tab.isShowingNetworkControls()
+        value = self.hou_tab.isShowingNetworkControls()
         return value
 
     def setPin(self, value):
-        self.tab.setPin(value)
+        self.hou_tab.setPin(value)
 
     def showNetworkControls(self, value):
-        self.tab.showNetworkControls(value)
+        self.hou_tab.showNetworkControls(value)
 
     def toggleNetworkControls(self):
         if self.hasNetworkControls():
diff --git a/python3.11libs/hc/hcviewport.py b/python3.11libs/hc/hcviewport.py
index 2e5923a..dcaa665 100644
--- a/python3.11libs/hc/hcviewport.py
+++ b/python3.11libs/hc/hcviewport.py
@@ -9,10 +9,20 @@ class HCViewport():
         display_set = settings.displaySet(hou.displaySetType.DisplayModel)
         return displaySet
 
+    def lockCameraToView(self, boolean):
+        self.viewport.lockCameraToView(boolean)
+
+    def setCamera(self, camera_node):
+        self.viewport.setCamera(camera_node)
+
+    def setType(self, type):
+        self.viewport.changeType(type)
+
+    def size(self):
+        return self.viewport.size()
+
     def visualizers(self):
         category = hou.viewportVisualizerCategory.Scene
         vis_arr = hou.viewportVisualizers.visualizers(category)
         return vis_arr
 
-    def setType(self, type):
-        self.viewport.changeType(type)
diff --git a/python3.11libs/hc/hcvisualizers.py b/python3.11libs/hc/hcvisualizers.py
index 165b0b5..1099cfc 100644
--- a/python3.11libs/hc/hcvisualizers.py
+++ b/python3.11libs/hc/hcvisualizers.py
@@ -5,7 +5,7 @@ from PySide6.QtWidgets import QListWidget, QListWidgetItem, QDialog, QLineEdit,
 from PySide6.QtCore import Qt, QEvent
 from .hcsession import HCSession
 
-class Visualizers(QDialog):
+class HCVisualizers(QDialog):
     def __init__(self):
         super(VisualizerMenu, self).__init__(hou.qt.mainWindow())
 
diff --git a/python3.11libs/hc/hcwidgets.py b/python3.11libs/hc/hcwidgets.py
index c599795..179d14d 100644
--- a/python3.11libs/hc/hcwidgets.py
+++ b/python3.11libs/hc/hcwidgets.py
@@ -1,8 +1,10 @@
+import hou
+from fuzzyfinder import fuzzyfinder
 from importlib import reload
 from PySide6 import QtWidgets
 from PySide6.QtCore import Qt
 
-class Widgets:
+class HCWidgets:
 
     class Button(QtWidgets.QPushButton):
         def __init__(self, text, parent=None):
@@ -17,3 +19,118 @@ class Widgets:
             super().__init__(label, parent)
             self.setStyleSheet("text-align: left; padding: 0 0 0 0")
             self.setFlat(1)
+
+
+    class SelectionDialog(QtWidgets.QDialog):
+        def __init__(self, window_title, list_dict):
+            super().__init__(hou.qt.mainWindow())
+            self.resize(900, 600)
+            self.setWindowTitle(window_title)
+            self.setWindowFlags(Qt.Tool | Qt.WindowStaysOnTopHint)
+
+            self.list = self.List()
+            self.list_dict = list_dict
+            self.list_items = []
+            for item in list_dict:
+                self.list_items.append(item)
+            self.populate(self.list_items)
+            self.list.setIndex(0)
+
+            self.list.itemClicked.connect(self.execute)
+            self.list.setSelectionMode(QtWidgets.QListWidget.SingleSelection)
+
+            """ Input line """
+            self.input_line = QtWidgets.QLineEdit()
+            self.input_line.returnPressed.connect(self.execute)
+            self.input_line.textEdited.connect(self.list.filter)
+
+            """ Layout """
+            self.layout = QtWidgets.QVBoxLayout()
+            self.layout.addWidget(self.list)
+            self.layout.addWidget(self.input_line)
+            self.setLayout(self.layout)
+
+            """ Do this last """
+            self.input_line.setFocus()
+
+        def closeEvent(self, event):
+            self.setParent(None)
+
+        def keyPressEvent(self, event):
+            if event.key() == Qt.Key_Up:
+                self.list.selectPrevious()
+                return
+            elif event.key() == Qt.Key_Down:
+                self.list.selectNext()
+            elif event.key() == Qt.Key_P and event.modifiers() == Qt.ControlModifier:
+                self.list.selectPrevious()
+                return
+            elif event.key() == Qt.Key_N and event.modifiers() == Qt.ControlModifier:
+                self.list.selectNext()
+                return
+            super().keyPressEvent(event)
+
+        def execute(self):
+            items = self.list.allItems()
+            index = items.index(self.list.currentItem())
+            # item = items[index]
+            item = self.list_items[index]
+            value = self.list_dict[item]()
+            return
+
+        def populate(self, item_list):
+            items = []
+            for key in item_list:
+                items.append(key)
+            self.list.addItems(items)
+
+
+        class List(QtWidgets.QListWidget):
+
+            def allItems(self):
+                items = []
+                for i in range(self.count()):
+                    items.append(self.item(i))
+                return items
+
+            def currentItem(self):
+                return self.selectedItems()[0]
+
+            def visibleItems(self):
+                items = []
+                for i in range(self.count()):
+                    item = self.item(i)
+                    if not item.isHidden():
+                        items.append(item)
+                return(items)
+
+            def filter(self, query):
+                all_items = self.allItems()
+                all_item_names = [item.text() for item in all_items]
+                matches = list(fuzzyfinder(query, all_item_names))
+                for item in all_items:
+                    if item.text() in matches:
+                        item.setHidden(0)
+                    else:
+                        item.setHidden(1)
+                self.setIndex(0)
+
+            def selectNext(self):
+                items = self.visibleItems()
+                index = items.index(self.currentItem())
+                index = (index + 1) % len(items)
+                self.setIndex(index)
+
+            def selectPrev(self):
+                items = self.visibleItems()
+                index = items.index(self.currentItem())
+                index = (index - 1) % len(items)
+                self.setIndex(index)
+
+            def setIndex(self, index):
+                counter = 0
+                for item in self.visibleItems():
+                    if counter == index:
+                        self.setCurrentItem(item)
+                    counter += 1
+