Hello,
Is there a way to undo only current viewport navigation like we do with “Alt+Z” in Softimage ?
Thanks
Undo for viewport navigation ?
18907 25 5- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- anon_user_89151269
- Member
- 1755 posts
- Joined: March 2014
- Offline
Exactly this behavior no, but there's something one can do to emulate that:
navigate your viewport through a locked camera (3rd lock icon on the tool bar on the right side of the viewport).
Of course it's rather limited for an “in the now” usage so to speak, since the undo will fill with other actions as you work and you won't be able to undo your camera changes.
File a RFE for “separate camera undo/redo stack” if you miss this feature so much.
navigate your viewport through a locked camera (3rd lock icon on the tool bar on the right side of the viewport).
Of course it's rather limited for an “in the now” usage so to speak, since the undo will fill with other actions as you work and you won't be able to undo your camera changes.
File a RFE for “separate camera undo/redo stack” if you miss this feature so much.
Edited by anon_user_89151269 - June 27, 2018 06:14:47
- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- Grendizer
- Member
- 375 posts
- Joined: May 2014
- Offline
- Rebus B
- Member
- 80 posts
- Joined: June 2013
- Offline
- Rebus B
- Member
- 80 posts
- Joined: June 2013
- Offline
- Grendizer
- Member
- 375 posts
- Joined: May 2014
- Offline
- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- Control_Vertex
- Member
- 161 posts
- Joined: May 2015
- Offline
- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- OneBigTree
- Member
- 382 posts
- Joined: Nov. 2010
- Offline
- julca
- Member
- 219 posts
- Joined: Oct. 2015
- Online
- Grendizer
- Member
- 375 posts
- Joined: May 2014
- Offline
- Control_Vertex
- Member
- 161 posts
- Joined: May 2015
- Offline
- anon_user_89151269
- Member
- 1755 posts
- Joined: March 2014
- Offline
As I said in another thread, it's best to make a habit of keying your camera. It's a solution for both the present and it would still be a good idea to do it even if you were to have this feature implemented, if the goal is to make sure you don't lose your camera transformation. And make sure “auto-commit changes” is off, or you'll update the keys every time you modify the cam view.
Edited by anon_user_89151269 - April 11, 2019 12:58:34
- motionpunk
- Member
- 14 posts
- Joined: Dec. 2016
- Offline
- animatrix_
- Member
- 4702 posts
- Joined: Feb. 2012
- Offline
I implemented this recently. You can give it a try. It supports multiple viewports. It has to be installed as a package or can be run without a package by installing directly into Houdini user directory. There seems to be some focus bug about scene viewer only hotkeys so I had to use a global hotkey for these. I will see if it's a bug in Houdini.
pythonrc.py:
456.py:
Special thanks to Alexey of DM and kosukek of SESI
pythonrc.py:
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
456.py:
hou.session.AllSceneViewers = [] hou.session.AllSceneViewerTypes = [] hou.session.SceneViewerEventFilter.reset()
Special thanks to Alexey of DM and kosukek of SESI
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
- Grendizer
- Member
- 375 posts
- Joined: May 2014
- Offline
Wow thanks!
I'd like to install this.
In my "houdini19.0" prefs folder, I added a folder called "packages".
Then if I understand correctly I must put your code into a text file and rename it something as "camundo.json"?
Then I must edit 456.py as you shown.
Then if I want to test it, what's the keyboard shortcut? In Maya it's ALT+Z.
Thanks
I'd like to install this.
In my "houdini19.0" prefs folder, I added a folder called "packages".
Then if I understand correctly I must put your code into a text file and rename it something as "camundo.json"?
Then I must edit 456.py as you shown.
Then if I want to test it, what's the keyboard shortcut? In Maya it's ALT+Z.
Thanks
Houdini gamboler
- animatrix_
- Member
- 4702 posts
- Joined: Feb. 2012
- Offline
Hi,
I made a separate zip, it's easier than copy pasting everything here. I am using them as part of my full customization so I separated these for there manually, it should work.
As for hotkeys, normally they were within the event filter code but there seems to be a focus problem in the latest Houdini I tried. I have to investigate this with SESI because it happens with scene viewer restricted hotkeys too.
So for now you have to hold Ctrl+Shift+Alt and click each shelf button to assign global hotkeys for undo and redo until that bug is fixed.
I made a separate zip, it's easier than copy pasting everything here. I am using them as part of my full customization so I separated these for there manually, it should work.
As for hotkeys, normally they were within the event filter code but there seems to be a focus problem in the latest Houdini I tried. I have to investigate this with SESI because it happens with scene viewer restricted hotkeys too.
So for now you have to hold Ctrl+Shift+Alt and click each shelf button to assign global hotkeys for undo and redo until that bug is fixed.
Senior FX TD @ Industrial Light & Magic
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
Get to the NEXT level in Houdini & VEX with Pragmatic VEX! [www.pragmatic-vfx.com]
youtube.com/@pragmaticvfx | patreon.com/animatrix | pragmaticvfx.gumroad.com
-
- Quick Links