From b0055516e6631d26fedfd499769984a7f2963f79 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 29 Mar 2022 15:21:35 +0200 Subject: [PATCH 1/6] OP-2834 - Fix getting non-active model panel. --- .../maya/plugins/publish/extract_playblast.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index bb1ecf279d..7fa9a840e9 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -90,6 +90,24 @@ class ExtractPlayblast(openpype.api.Extractor): else: preset["viewport_options"] = {"imagePlane": image_plane} + # Image planes do not update the file sequence unless the active panel + # is viewing through the camera. + model_panel = instance.context.data.get("model_panel") + if not model_panel: + model_panels = cmds.getPanel(type="modelPanel") + visible_panels = cmds.getPanel(visiblePanels=True) + model_panel = list( + set(visible_panels) - (set(visible_panels) - set(model_panels)) + )[0] + instance.context.data["model_panel"] = model_panel + + panel_camera = instance.context.data.get("panel_camera") + if not panel_camera: + panel_camera = capture.parse_view(model_panel)["camera"] + instance.context.data["panel_camera"] = panel_camera + + cmds.modelPanel(model_panel, edit=True, camera=preset["camera"]) + with maintained_time(): filename = preset.get("filename", "%TEMP%") @@ -108,6 +126,9 @@ class ExtractPlayblast(openpype.api.Extractor): path = capture.capture(**preset) + # Restore panel camera. + cmds.modelPanel(model_panel, edit=True, camera=panel_camera) + self.log.debug("playblast path {}".format(path)) collected_files = os.listdir(stagingdir) From ab4179d49a06185da3b852861c50e216ad226238 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 17 Mar 2023 16:51:36 +0000 Subject: [PATCH 2/6] Properly get and set model panel camera. --- .../maya/plugins/publish/extract_playblast.py | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index 06d3ccb4a9..a652db2eb5 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -114,21 +114,12 @@ class ExtractPlayblast(publish.Extractor): # Image planes do not update the file sequence unless the active panel # is viewing through the camera. - model_panel = instance.context.data.get("model_panel") - if not model_panel: - model_panels = cmds.getPanel(type="modelPanel") - visible_panels = cmds.getPanel(visiblePanels=True) - model_panel = list( - set(visible_panels) - (set(visible_panels) - set(model_panels)) - )[0] - instance.context.data["model_panel"] = model_panel - - panel_camera = instance.context.data.get("panel_camera") - if not panel_camera: - panel_camera = capture.parse_view(model_panel)["camera"] - instance.context.data["panel_camera"] = panel_camera - - cmds.modelPanel(model_panel, edit=True, camera=preset["camera"]) + panel_camera = cmds.modelPanel( + instance.data["panel"], query=True, camera=True + ) + cmds.modelPanel( + instance.data["panel"], edit=True, camera=preset["camera"] + ) # Disable Pan/Zoom. pan_zoom = cmds.getAttr("{}.panZoomEnabled".format(preset["camera"])) @@ -188,7 +179,7 @@ class ExtractPlayblast(publish.Extractor): cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom) # Restore panel camera. - cmds.modelPanel(model_panel, edit=True, camera=panel_camera) + cmds.modelPanel(instance.data["panel"], edit=True, camera=panel_camera) self.log.debug("playblast path {}".format(path)) From d88cd48b8eda227873191b830a5792f3403b1abf Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 24 Mar 2023 07:48:28 +0000 Subject: [PATCH 3/6] Refactor to nested/stacked contextlib --- .../maya/plugins/publish/extract_playblast.py | 83 ++++++++++++------- 1 file changed, 52 insertions(+), 31 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index a652db2eb5..9d35789343 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -1,5 +1,6 @@ import os import json +import contextlib import clique import capture @@ -11,6 +12,16 @@ from maya import cmds import pymel.core as pm +@contextlib.contextmanager +def panel_camera(panel, camera): + original_camera = cmds.modelPanel(panel, query=True, camera=True) + try: + cmds.modelPanel(panel, edit=True, camera=camera) + yield + finally: + cmds.modelPanel(panel, edit=True, camera=original_camera) + + class ExtractPlayblast(publish.Extractor): """Extract viewport playblast. @@ -25,6 +36,31 @@ class ExtractPlayblast(publish.Extractor): optional = True capture_preset = {} + def _capture(self, preset, override_viewport_options, instance): + filename = preset.get("filename", "%TEMP%") + + # Force viewer to False in call to capture because we have our own + # viewer opening call to allow a signal to trigger between + # playblast and viewer + preset['viewer'] = False + + # Update preset with current panel setting + # if override_viewport_options is turned off + if not override_viewport_options: + panel_preset = capture.parse_view(instance.data["panel"]) + panel_preset.pop("camera") + preset.update(panel_preset) + + self.log.info( + "Using preset:\n{}".format( + json.dumps(preset, sort_keys=True, indent=4) + ) + ) + + path = capture.capture(log=self.log, **preset) + + return filename, path + def process(self, instance): self.log.info("Extracting capture..") @@ -112,15 +148,6 @@ class ExtractPlayblast(publish.Extractor): else: preset["viewport_options"] = {"imagePlane": image_plane} - # Image planes do not update the file sequence unless the active panel - # is viewing through the camera. - panel_camera = cmds.modelPanel( - instance.data["panel"], query=True, camera=True - ) - cmds.modelPanel( - instance.data["panel"], edit=True, camera=preset["camera"] - ) - # Disable Pan/Zoom. pan_zoom = cmds.getAttr("{}.panZoomEnabled".format(preset["camera"])) cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), False) @@ -147,28 +174,25 @@ class ExtractPlayblast(publish.Extractor): override_viewport_options = ( capture_presets['Viewport Options']['override_viewport_options'] ) - with lib.maintained_time(): - filename = preset.get("filename", "%TEMP%") - # Force viewer to False in call to capture because we have our own - # viewer opening call to allow a signal to trigger between - # playblast and viewer - preset['viewer'] = False - - # Update preset with current panel setting - # if override_viewport_options is turned off - if not override_viewport_options: - panel_preset = capture.parse_view(instance.data["panel"]) - panel_preset.pop("camera") - preset.update(panel_preset) - - self.log.info( - "Using preset:\n{}".format( - json.dumps(preset, sort_keys=True, indent=4) + if getattr(contextlib, "nested", None): + with contextlib.nested( + lib.maintained_time(), + panel_camera(instance.data["panel"], preset["camera"]) + ): + filename, path = self._capture( + preset, override_viewport_options, instance + ) + else: + with contextlib.ExitStack() as stack: + stack.enter_context(lib.maintained_time()) + stack.enter_context( + panel_camera(instance.data["panel"], preset["camera"]) ) - ) - path = capture.capture(log=self.log, **preset) + filename, path = self._capture( + preset, override_viewport_options, instance + ) # Restoring viewport options. if viewport_defaults: @@ -178,9 +202,6 @@ class ExtractPlayblast(publish.Extractor): cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom) - # Restore panel camera. - cmds.modelPanel(instance.data["panel"], edit=True, camera=panel_camera) - self.log.debug("playblast path {}".format(path)) collected_files = os.listdir(stagingdir) From 4d42e58074c873f2247fa31e4d86b51c6c1b4262 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Fri, 24 Mar 2023 09:37:05 +0000 Subject: [PATCH 4/6] Update openpype/hosts/maya/plugins/publish/extract_playblast.py --- openpype/hosts/maya/plugins/publish/extract_playblast.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index 9d35789343..e7dc42d2c0 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -175,7 +175,10 @@ class ExtractPlayblast(publish.Extractor): capture_presets['Viewport Options']['override_viewport_options'] ) + # Need to ensure Python 2 compatibility. + # TODO: Remove once dropping Python 2. if getattr(contextlib, "nested", None): + # Python 3 compatibility. with contextlib.nested( lib.maintained_time(), panel_camera(instance.data["panel"], preset["camera"]) @@ -184,6 +187,7 @@ class ExtractPlayblast(publish.Extractor): preset, override_viewport_options, instance ) else: + # Python 2 compatibility. with contextlib.ExitStack() as stack: stack.enter_context(lib.maintained_time()) stack.enter_context( From d1038ace686dea66069319b2a8e0df7df3c4e4c7 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 24 Mar 2023 09:44:39 +0000 Subject: [PATCH 5/6] Refactor _capture --- .../maya/plugins/publish/extract_playblast.py | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index e7dc42d2c0..9bd859ade1 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -37,29 +37,13 @@ class ExtractPlayblast(publish.Extractor): capture_preset = {} def _capture(self, preset, override_viewport_options, instance): - filename = preset.get("filename", "%TEMP%") - - # Force viewer to False in call to capture because we have our own - # viewer opening call to allow a signal to trigger between - # playblast and viewer - preset['viewer'] = False - - # Update preset with current panel setting - # if override_viewport_options is turned off - if not override_viewport_options: - panel_preset = capture.parse_view(instance.data["panel"]) - panel_preset.pop("camera") - preset.update(panel_preset) - self.log.info( "Using preset:\n{}".format( json.dumps(preset, sort_keys=True, indent=4) ) ) - path = capture.capture(log=self.log, **preset) - - return filename, path + return capture.capture(log=self.log, **preset) def process(self, instance): self.log.info("Extracting capture..") @@ -175,6 +159,18 @@ class ExtractPlayblast(publish.Extractor): capture_presets['Viewport Options']['override_viewport_options'] ) + # Force viewer to False in call to capture because we have our own + # viewer opening call to allow a signal to trigger between + # playblast and viewer + preset['viewer'] = False + + # Update preset with current panel setting + # if override_viewport_options is turned off + if not override_viewport_options: + panel_preset = capture.parse_view(instance.data["panel"]) + panel_preset.pop("camera") + preset.update(panel_preset) + # Need to ensure Python 2 compatibility. # TODO: Remove once dropping Python 2. if getattr(contextlib, "nested", None): @@ -183,7 +179,7 @@ class ExtractPlayblast(publish.Extractor): lib.maintained_time(), panel_camera(instance.data["panel"], preset["camera"]) ): - filename, path = self._capture( + path = self._capture( preset, override_viewport_options, instance ) else: @@ -194,7 +190,7 @@ class ExtractPlayblast(publish.Extractor): panel_camera(instance.data["panel"], preset["camera"]) ) - filename, path = self._capture( + path = self._capture( preset, override_viewport_options, instance ) @@ -214,6 +210,7 @@ class ExtractPlayblast(publish.Extractor): minimum_items=1, patterns=patterns) + filename = preset.get("filename", "%TEMP%") self.log.debug("filename {}".format(filename)) frame_collection = None for collection in collections: From 799a6b6cc457d4ef6b4b28f18fe6c831521376ea Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Fri, 24 Mar 2023 10:02:48 +0000 Subject: [PATCH 6/6] Remove path variable and _capture arguments. --- .../maya/plugins/publish/extract_playblast.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_playblast.py b/openpype/hosts/maya/plugins/publish/extract_playblast.py index 9bd859ade1..41e4f3a7c2 100644 --- a/openpype/hosts/maya/plugins/publish/extract_playblast.py +++ b/openpype/hosts/maya/plugins/publish/extract_playblast.py @@ -36,14 +36,15 @@ class ExtractPlayblast(publish.Extractor): optional = True capture_preset = {} - def _capture(self, preset, override_viewport_options, instance): + def _capture(self, preset): self.log.info( "Using preset:\n{}".format( json.dumps(preset, sort_keys=True, indent=4) ) ) - return capture.capture(log=self.log, **preset) + path = capture.capture(log=self.log, **preset) + self.log.debug("playblast path {}".format(path)) def process(self, instance): self.log.info("Extracting capture..") @@ -179,9 +180,7 @@ class ExtractPlayblast(publish.Extractor): lib.maintained_time(), panel_camera(instance.data["panel"], preset["camera"]) ): - path = self._capture( - preset, override_viewport_options, instance - ) + self._capture(preset) else: # Python 2 compatibility. with contextlib.ExitStack() as stack: @@ -190,9 +189,7 @@ class ExtractPlayblast(publish.Extractor): panel_camera(instance.data["panel"], preset["camera"]) ) - path = self._capture( - preset, override_viewport_options, instance - ) + self._capture(preset) # Restoring viewport options. if viewport_defaults: @@ -202,8 +199,6 @@ class ExtractPlayblast(publish.Extractor): cmds.setAttr("{}.panZoomEnabled".format(preset["camera"]), pan_zoom) - self.log.debug("playblast path {}".format(path)) - collected_files = os.listdir(stagingdir) patterns = [clique.PATTERNS["frames"]] collections, remainder = clique.assemble(collected_files,