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

python3.11libs/hc/hcsceneviewer.py (8.8K)

  1 import hou, types
  2 from .hcpathtab import HCPathTab
  3 from .hcviewport import HCViewport
  4 
  5 
  6 def _hcPrintSceneViewerEvent(**kwargs):
  7     event_type = kwargs.get("event_type")
  8     viewer = kwargs.get("viewer")
  9     viewer_name = viewer.name() if viewer is not None else "?"
 10     extras = {k: v for k, v in kwargs.items() if k not in ("event_type", "desktop", "viewer")}
 11     extras_str = " ".join(f"{k}={v!r}" for k, v in extras.items())
 12     print(f"[HCSceneViewer {viewer_name}] {event_type} {extras_str}".rstrip())
 13 
 14 """
 15 Layout/viewport IDs
 16 
 17 DoubleSide:        2 3
 18 
 19 DoubleStack:       3
 20                    0
 21 
 22 Quad:              2 3
 23                    1 0
 24 
 25 QuadBottomSplit:     3
 26                    2 1 0
 27 
 28 QuadLeftSplit:     2
 29                    1 3
 30                    0
 31 
 32 TripleBottomSplit:   3
 33                    1   0
 34 
 35 TripleLeftSplit:   2
 36                    0 3
 37                    1
 38 
 39 Single:
 40 setViewportLayout(layout, single=-1)
 41 -1: current viewport (viewportmouse is/was over)
 42 0: top-left quad viewport (default: Top)
 43 1: top-right quad viewport (default: Perspective)
 44 2: bottom-left quad viewport (default: Front)
 45 3: bottom-right quad viewport (default: Right)
 46 """
 47 
 48 class HCSceneViewer(HCPathTab):
 49     def __init__(self, hou_tab):
 50         self.hou_tab = hou_tab
 51 
 52 
 53     """ Geometry """
 54 
 55     def allDisplaySets(self):
 56         displaySets = []
 57         for hc_viewport in self.allViewports():
 58             settings = hc_viewport.settings()
 59             displaySet = settings.displaySet(hou.displaySetType.DisplayModel)
 60             displaySets.append(displaySet)
 61         return displaySets
 62 
 63     def toggleLightGeo(self):
 64         self.setShowLights(not self.showLights())
 65 
 66     def toggleBackface(self):
 67         visible = 0
 68         displaySets = self.allDisplaySets()
 69         for displaySet in displaySets:
 70             if displaySet.isShowingPrimBackfaces():
 71                 visible = 1
 72         for displaySet in displaySets:
 73             displaySet.showPrimBackfaces(not visible)
 74 
 75     def togglePointMarkers(self):
 76         visible = 0
 77         displaySets = self.allDisplaySets()
 78         for displaySet in displaySets:
 79             if displaySet.isShowingPointMarkers():
 80                 visible = 1
 81         for displaySet in displaySets:
 82             displaySet.showPointMarkers(not visible)
 83 
 84     def togglePointNormals(self):
 85         visible = 0
 86         displaySets = self.allDisplaySets()
 87         for displaySet in displaySets:
 88             if displaySet.isShowingPointNormals():
 89                 visible = 1
 90         for displaySet in displaySets:
 91             displaySet.showPointNormals(not visible)
 92 
 93     def togglePointNumbers(self):
 94         visible = 0
 95         displaySets = self.allDisplaySets()
 96         for displaySet in displaySets:
 97             if displaySet.isShowingPointNumbers():
 98                 visible = 1
 99         for displaySet in displaySets:
100             displaySet.showPointNumbers(not visible)
101 
102     def togglePrimNormals(self):
103         visible = 0
104         displaySets = self.allDisplaySets()
105         for displaySet in displaySets:
106             if displaySet.isShowingPrimNormals():
107                 visible = 1
108         for displaySet in displaySets:
109             displaySet.showPrimNormals(not visible)
110 
111     def togglePrimNumbers(self):
112         visible = 0
113         displaySets = self.allDisplaySets()
114         for displaySet in displaySets:
115             if displaySet.isShowingPrimNumbers():
116                 visible = 1
117         for displaySet in displaySets:
118             displaySet.showPrimNumbers(not visible)
119 
120     def toggleVectors(self):
121         for viewport in self.allViewports():
122             settings = viewport.settings()
123             scale = settings.vectorScale()
124             if scale == 1:
125                 settings.setVectorScale(0)
126             elif scale == 0:
127                 settings.setVectorScale(1)
128             else:
129                 settings.setVectorScale(1)
130 
131     """ Grids """
132 
133     def referencePlane(self):
134         return self.hou_tab.referencePlane()
135 
136     def toggleGrid(self):
137         reference_plane = self.referencePlane()
138         reference_plane.setIsVisible(not reference_plane.isVisible())
139 
140 
141     """ Layout """
142 
143     def layout(self):
144         return self.hou_tab.viewportLayout()
145 
146     def layouts(self):
147         return (
148             hou.geometryViewportLayout.DoubleSide,
149             hou.geometryViewportLayout.DoubleStack,
150             hou.geometryViewportLayout.Quad,
151             hou.geometryViewportLayout.QuadBottomSplit,
152             hou.geometryViewportLayout.QuadLeftSplit,
153             hou.geometryViewportLayout.TripleBottomSplit,
154             hou.geometryViewportLayout.TripleLeftSplit,
155             hou.geometryViewportLayout.Single,
156         )
157 
158     def layoutIndices(self):
159         return (
160             (2, 3),
161             (3, 0),
162             (2, 3, 1, 0),
163             (3, 2, 1, 0),
164             (2, 1, 0, 3),
165             (3, 1, 0),
166             (2, 3, 1),
167             (3),
168         )
169 
170     def nextLayout(self):
171         layouts = self.layouts()
172         layout = self.layout()
173         index = layouts.index(layout)
174         index = (index+1) % len(layouts)
175         self.setLayout(layouts[index])
176         return
177 
178     def setLayout(self, layout):
179         layout_map = {
180             "DoubleSide":        hou.geometryViewportLayout.DoubleSide,
181             "DoubleStack":       hou.geometryViewportLayout.DoubleStack,
182             "Quad":              hou.geometryViewportLayout.Quad,
183             "QuadBottomSplit":   hou.geometryViewportLayout.QuadBottomSplit,
184             "QuadLeftSplit":     hou.geometryViewportLayout.QuadLeftSplit,
185             "Single":            hou.geometryViewportLayout.Single,
186             "TripleBottomSplit": hou.geometryViewportLayout.TripleBottomSplit,
187             "TripleLeftSplit":   hou.geometryViewportLayout.TripleLeftSplit
188         }
189         self.hou_tab.setViewportLayout(layout_map[layout])
190 
191 
192     """ UI """
193 
194     def isVisibleDisplayBar(self):
195         return self.hou_tab.isShowingDisplayOptionsBar()
196 
197     def isVisibleGroupList(self):
198         return self.hou_tab.isGroupListVisible()
199 
200     def isVisibleOperationBar(self):
201         return self.hou_tab.isShowingOperationBar()
202 
203     def isVisibleSelectionBar(self):
204         return self.hou_tab.isShowingSelectionBar()
205 
206     def showDisplayBar(self, value):
207         self.hou_tab.showDisplayOptionsBar(value)
208 
209     def showGroupList(self, value):
210         self.hou_tab.setGroupListVisible(value)
211 
212     def showOperationBar(self, value):
213         self.hou_tab.showOperationBar(value)
214 
215     def showSelectionBar(self, value):
216         self.hou_tab.showSelectionBar(value)
217 
218     def toggleDisplayBar(self):
219         self.showDisplayBar(not self.isVisibleDisplayBar())
220 
221     def toggleGroupList(self):
222         self.showGroupList(not self.isVisibleGroupList)
223 
224     def toggleOperationBar(self):
225         self.showOperationBar(not self.isVisibleOperationBar())
226 
227     def toggleSelectionBar(self):
228         self.showSelectionBar(not self.isVisibleSelectionBar())
229 
230     def toggleBars(self):
231         state = self.hou_tab.isShowingOperationBar() + self.hou_tab.isShowingDisplayOptionsBar() + self.hou_tab.isShowingSelectionBar()
232         if state > 0:
233             self.showOperationBar(0)
234             self.showDisplayBar(0)
235             self.showSelectionBar(0)
236         else:
237             self.showOperationBar(1)
238             self.showDisplayBar(1)
239             self.showSelectionBar(1)
240 
241 
242     """ Events """
243 
244     def addEventListener(self):
245         if _hcPrintSceneViewerEvent not in self.hou_tab.eventCallbacks():
246             self.hou_tab.addEventCallback(_hcPrintSceneViewerEvent)
247 
248     def removeEventListener(self):
249         if _hcPrintSceneViewerEvent in self.hou_tab.eventCallbacks():
250             self.hou_tab.removeEventCallback(_hcPrintSceneViewerEvent)
251 
252     def isListening(self):
253         return _hcPrintSceneViewerEvent in self.hou_tab.eventCallbacks()
254 
255     def toggleEventListener(self):
256         if self.isListening():
257             self.removeEventListener()
258         else:
259             self.addEventListener()
260 
261 
262     """ Utils """
263 
264     def type(self):
265         return "HCSceneViewer"
266 
267     def keycam(self):
268         contexts = ('Object', 'Sop', "Lop")
269         context = self.pwd().childCat()
270         if context in contexts:
271             self.hou_tab.setCurrentState('keycam')
272         else:
273             hou.ui.setStatusMessage("No obj, sop or lop context", hou.severityType.Error)
274 
275 
276     """ Viewports """
277 
278     def homeAllViewports(self):
279         for viewport in self.allViewports():
280             viewport.home()
281 
282     def currentViewport(self):
283         return self.hou_tab.curViewport()
284 
285     def allViewports(self):
286         viewports = []
287         for viewport in self.hou_tab.viewports():
288             viewports.append(HCViewport(viewport))
289         return viewports
290 
291     def frameAllViewports(self):
292         for viewport in self.allViewports():
293             cam = viewport.camera()
294             # Is camera node or default
295             if not cam:
296                 viewport.frameAll()
297             else:
298                 viewport.frameAll()