Hello,
Is there a way to undo only current viewport navigation like we do with “Alt+Z” in Softimage ?
Thanks
Grendizer
…Would be cool if it's implemented in v17
GrendizerNo, there is not still present in H17.
Good! Can someone with V17 tell us if undo camera is here?
cvalUpdated my exact same request (#63120) with the reference to your RFE number !
We logged an RFE for this feature a few years ago. It's ID is #73866 if you want to reference it in your RFEs
OneBigTreeAs I know we can't upvote RFE, you may send a new one with same request.
Can we upvote RFEs?
import hou from hdefereval import executeDeferred from PySide2 import QtCore, QtWidgets, QtGui import shiboken2 debug = False def areIdenticalCameras(cam1, cam2): if cam1.isPerspective() and cam2.isOrthographic(): return False if cam2.isPerspective() and cam1.isOrthographic(): return False if cam1.aperture() != cam2.aperture(): return False if cam1.focalLength() != cam2.focalLength(): return False if cam1.aspectRatio() != cam2.aspectRatio(): return False if cam1.orthoWidth() != cam2.orthoWidth(): return False if cam1.rotation() != cam2.rotation(): return False if cam1.translation() != cam2.translation(): return False if cam1.windowOffset() != cam2.windowOffset(): return False if cam1.windowSize() != cam2.windowSize(): return False return True class SceneViewerEventFilter(QtCore.QObject): SceneViewers = [] Refs = [] def __init__(self, sceneViewer, sceneViewerQt): QtCore.QObject.__init__(self) SceneViewerEventFilter.SceneViewers.append(sceneViewer) SceneViewerEventFilter.Refs.append(self) self.sceneViewer = sceneViewer; self.sceneViewerQt = sceneViewerQt; viewport = self.sceneViewer.curViewport() cam = viewport.defaultCamera().stash() self.views = [cam] self.viewtypes = [viewport.type()] self.viewindex = -1 def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.MouseButtonRelease: pane = hou.ui.paneTabUnderCursor() if pane and pane.type() == hou.paneTabType.SceneViewer: if "view" in pane.currentState(): executeDeferred(self.viewChangedEvent) elif event.type() == QtCore.QEvent.MouseMove: if len(self.views) == 0: viewport = self.sceneViewer.curViewport() cam = viewport.defaultCamera().stash() self.views.append(cam) self.viewtypes.append(viewport.type()) if debug: print ("mouse move") """ elif event.type() == QtCore.QEvent.KeyPress: if event.modifiers() & QtCore.Qt.ShiftModifier: if event.key() == QtCore.Qt.Key_Z: self.undoView() elif event.key() == QtCore.Qt.Key_A: self.redoView() """ return False def viewChangedEvent(self, force=False): viewport = self.sceneViewer.curViewport() cam = viewport.defaultCamera().stash() if force or len(self.views) == 0 or not areIdenticalCameras(cam, self.views[-1]): if self.viewindex != -1: self.views = self.views[: self.viewindex + 1] self.viewtypes = self.viewtypes[: self.viewindex + 1] self.viewindex = -1 self.views.append(cam) self.viewtypes.append(viewport.type()) if debug: print ("VIEW CHANGED: ", len(self.views), viewport.type()) print ("------------------------------------") def undoView(self): if self.viewindex == -1: self.viewindex = len(self.views) - 1 if self.viewindex > 0: self.viewindex -= 1 if debug: print ("undo", self.viewindex) viewport = self.sceneViewer.curViewport() viewport.changeType(self.viewtypes[self.viewindex]) try: viewport.setDefaultCamera(self.views[self.viewindex]) except: pass def redoView(self): if self.viewindex == -1: self.viewindex = len(self.views) - 1 if self.viewindex < len(self.viewtypes) - 1: self.viewindex += 1 if debug: print ("redo", self.viewindex) viewport = self.sceneViewer.curViewport() viewport.changeType(self.viewtypes[self.viewindex]) try: viewport.setDefaultCamera(self.views[self.viewindex]) except: pass @staticmethod def reset(): for ref in SceneViewerEventFilter.Refs: ref.views = [] ref.viewtypes = [] ref.viewindex = -1 # Install event filter if it's not installed yet for each viewport def installEventFilterForCurrentViewport(): pane = hou.ui.paneTabUnderCursor() if pane and pane.type() == hou.paneTabType.SceneViewer: if pane not in SceneViewerEventFilter.SceneViewers: if not hasattr(hou.session, "ViewerEventFilters"): hou.session.ViewerEventFilters = [] app = QtWidgets.QApplication.instance() sceneViewerQt = app.widgetAt(QtGui.QCursor.pos()) if len(sceneViewerQt.children()) == 0: viewerEF = SceneViewerEventFilter(pane, sceneViewerQt) hou.session.ViewerEventFilters.append(viewerEF) sceneViewerQt.installEventFilter(viewerEF) if debug: print ("INSTALL EVENT FILTER: ", pane.name()) def viewportViewTypeChangedCallback(): if not hasattr(hou.session, "AllSceneViewers"): hou.session.AllSceneViewers = [] hou.session.AllSceneViewerTypes = [] desktop = hou.ui.curDesktop() panetabs = desktop.paneTabs() for pane in panetabs: if pane.type() == hou.paneTabType.SceneViewer: if pane not in hou.session.AllSceneViewers: hou.session.AllSceneViewers.append(pane) hou.session.AllSceneViewerTypes.append(pane.curViewport().type()) if debug: print ("SCENE VIEWER ADDED") else: index = hou.session.AllSceneViewers.index(pane) viewtype = pane.curViewport().type() if viewtype != hou.session.AllSceneViewerTypes[index]: svindex = SceneViewerEventFilter.SceneViewers.index(pane) sv = SceneViewerEventFilter.Refs[index] if sv.viewindex == -1: if debug: print ("VIEW TYPE CHANGED ", hou.session.AllSceneViewerTypes[index], viewtype) hou.session.AllSceneViewerTypes[index] = viewtype sv.viewChangedEvent(force=True) hou.ui.addEventLoopCallback(installEventFilterForCurrentViewport) hou.ui.addEventLoopCallback(viewportViewTypeChangedCallback) hou.session.SceneViewerEventFilter = SceneViewerEventFilter
hou.session.AllSceneViewers = [] hou.session.AllSceneViewerTypes = [] hou.session.SceneViewerEventFilter.reset()