From 911c089319b7b90fc6e5726555d9fc9aa5d21a80 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 29 Mar 2023 17:54:17 +0200 Subject: [PATCH 01/12] Fix collect current file - Fix families filtering - Remove unused import - Fix correct detection if scene is new but unsaved scene --- .../hosts/houdini/plugins/publish/collect_current_file.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_current_file.py b/openpype/hosts/houdini/plugins/publish/collect_current_file.py index 9cca07fdc7..caf679f98b 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_current_file.py +++ b/openpype/hosts/houdini/plugins/publish/collect_current_file.py @@ -1,7 +1,6 @@ import os import hou -from openpype.pipeline import legacy_io import pyblish.api @@ -11,7 +10,7 @@ class CollectHoudiniCurrentFile(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder - 0.01 label = "Houdini Current File" hosts = ["houdini"] - family = ["workfile"] + families = ["workfile"] def process(self, instance): """Inject the current working file""" @@ -21,7 +20,7 @@ class CollectHoudiniCurrentFile(pyblish.api.InstancePlugin): # By default, Houdini will even point a new scene to a path. # However if the file is not saved at all and does not exist, # we assume the user never set it. - filepath = "" + current_file = "" elif os.path.basename(current_file) == "untitled.hip": # Due to even a new file being called 'untitled.hip' we are unable From 36f1a1103ee6e148c0dd42aa66f81fff05b352cf Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Mar 2023 00:23:43 +0200 Subject: [PATCH 02/12] Fix #4693: Add `displayGradient` key to allow disabling gradient background --- openpype/hosts/maya/api/lib.py | 4 ++-- openpype/settings/defaults/project_settings/maya.json | 3 ++- .../projects_schema/schemas/schema_maya_capture.json | 10 +++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index aa1e501578..1a62e7dbc3 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -2478,8 +2478,8 @@ def load_capture_preset(data=None): float(value[2]) / 255 ] disp_options[key] = value - else: - disp_options['displayGradient'] = True + elif key == "displayGradient": + disp_options[key] = value options['display_options'] = disp_options diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index e914eb29f9..fda053e6e6 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -795,6 +795,7 @@ "quality": 95 }, "Display Options": { + "override_display": true, "background": [ 125, 125, @@ -813,7 +814,7 @@ 125, 255 ], - "override_display": true + "displayGradient": true }, "Generic": { "isolate_view": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json index 416e530db2..a4a986bad8 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_capture.json @@ -48,7 +48,11 @@ "type": "label", "label": "Display Options" }, - + { + "type": "boolean", + "key": "override_display", + "label": "Override display options" + }, { "type": "color", "key": "background", @@ -66,8 +70,8 @@ }, { "type": "boolean", - "key": "override_display", - "label": "Override display options" + "key": "displayGradient", + "label": "Display background gradient" } ] }, From 4ee44bcfec4b06f2ba95881261de7a79b0ae99a1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Mar 2023 09:15:48 +0200 Subject: [PATCH 03/12] update project action workflow --- .github/workflows/project_actions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/project_actions.yml b/.github/workflows/project_actions.yml index 769f40e0b8..4c09549ac4 100644 --- a/.github/workflows/project_actions.yml +++ b/.github/workflows/project_actions.yml @@ -69,3 +69,4 @@ jobs: with: repo-token: ${{ secrets.YNPUT_BOT_TOKEN }} configuration-path: ".github/pr-glob-labeler.yml" + sync-labels: false From b752035022dd21abdf192a74084aefd6dfcf276f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Mar 2023 09:19:05 +0200 Subject: [PATCH 04/12] project actions sync labels true --- .github/workflows/project_actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/project_actions.yml b/.github/workflows/project_actions.yml index 4c09549ac4..8080d68156 100644 --- a/.github/workflows/project_actions.yml +++ b/.github/workflows/project_actions.yml @@ -69,4 +69,4 @@ jobs: with: repo-token: ${{ secrets.YNPUT_BOT_TOKEN }} configuration-path: ".github/pr-glob-labeler.yml" - sync-labels: false + sync-labels: true From c3e4bc6409a91d88a481dffa98ecc9ff1454e32a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Mar 2023 09:29:55 +0200 Subject: [PATCH 05/12] project actions sync labels off update labeler --- .github/workflows/project_actions.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/project_actions.yml b/.github/workflows/project_actions.yml index 8080d68156..cfee140541 100644 --- a/.github/workflows/project_actions.yml +++ b/.github/workflows/project_actions.yml @@ -65,8 +65,8 @@ jobs: || (github.event_name == 'pull_request' && github.event.action == 'opened')}} steps: - name: Label PRs - Globe detection - uses: actions/labeler@v4 + uses: actions/labeler@v4.0.3 with: repo-token: ${{ secrets.YNPUT_BOT_TOKEN }} configuration-path: ".github/pr-glob-labeler.yml" - sync-labels: true + sync-labels: false From 18efd5276df132909d8eae592f09cd6d7b011cbb Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 30 Mar 2023 11:57:36 +0200 Subject: [PATCH 06/12] :art: add camera loader --- .../hosts/maya/plugins/load/load_camera.py | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 openpype/hosts/maya/plugins/load/load_camera.py diff --git a/openpype/hosts/maya/plugins/load/load_camera.py b/openpype/hosts/maya/plugins/load/load_camera.py new file mode 100644 index 0000000000..5e26e8c02f --- /dev/null +++ b/openpype/hosts/maya/plugins/load/load_camera.py @@ -0,0 +1,76 @@ +import openpype.hosts.maya.api.plugin +from openpype.hosts.maya.api.lib import get_container_members + + +class CameraLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): + """Reference Camera""" + + families = ["camera", "camerarig"] + label = "Reference camera" + representations = ["abc", "ma"] + order = -10 + icon = "code-fork" + color = "orange" + + def process_reference(self, context, name, namespace, data): + + import maya.cmds as cmds + # Get family type from the context + + cmds.loadPlugin("AbcImport.mll", quiet=True) + nodes = cmds.file(self.fname, + namespace=namespace, + sharedReferenceFile=False, + groupReference=True, + groupName="{}:{}".format(namespace, name), + reference=True, + returnNewNodes=True) + + cameras = cmds.ls(nodes, type="camera") + + # Check the Maya version, lockTransform has been introduced since + # Maya 2016.5 Ext 2 + version = int(cmds.about(version=True)) + if version >= 2016: + for camera in cameras: + cmds.camera(camera, edit=True, lockTransform=True) + else: + self.log.warning("This version of Maya does not support locking of" + " transforms of cameras.") + + self[:] = nodes + + return nodes + + def update(self, container, representation): + + from maya import cmds + + # Get the modelPanels that used the old camera + members = get_container_members(container) + old_cameras = cmds.ls(members, type="camera", long=True) + update_panels = [] + for panel in cmds.getPanel(type="modelPanel"): + cam = cmds.ls(cmds.modelPanel(panel, query=True, camera=True), + long=True) + + # Often but not always maya returns the transform from the + # modelPanel as opposed to the camera shape, so we convert it + # to explicitly be the camera shape + if cmds.nodeType(cam) != "camera": + cam = cmds.listRelatives(cam, + children=True, + fullPath=True, + type="camera")[0] + if cam in old_cameras: + update_panels.append(panel) + + # Perform regular reference update + super(CameraLoader, self).update(container, representation) + + # Update the modelPanels to contain the new camera + members = get_container_members(container) + new_cameras = cmds.ls(members, type="camera", long=True) + new_camera = new_cameras[0] + for panel in update_panels: + cmds.modelPanel(panel, edit=True, camera=new_camera) From ea2490ce5618f556d8374e488364cabefea51a7a Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 30 Mar 2023 13:37:52 +0200 Subject: [PATCH 07/12] project action - reducing job triggering --- .github/workflows/project_actions.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/project_actions.yml b/.github/workflows/project_actions.yml index cfee140541..1e1a1441f7 100644 --- a/.github/workflows/project_actions.yml +++ b/.github/workflows/project_actions.yml @@ -25,8 +25,8 @@ jobs: name: pr_size_label runs-on: ubuntu-latest if: | - ${{(github.event_name == 'pull_request' && github.event.action == 'synchronize') - || (github.event_name == 'pull_request' && github.event.action == 'assigned')}} + ${{(github.event_name == 'pull_request' && github.event.action == 'assigned') + || (github.event_name == 'pull_request' && github.event.action == 'opened')}} steps: - name: Add size label @@ -49,7 +49,7 @@ jobs: name: pr_branch_label runs-on: ubuntu-latest if: | - ${{(github.event_name == 'pull_request' && github.event.action == 'synchronize') + ${{(github.event_name == 'pull_request' && github.event.action == 'assigned') || (github.event_name == 'pull_request' && github.event.action == 'opened')}} steps: - name: Label PRs - Branch name detection @@ -61,7 +61,7 @@ jobs: name: pr_globe_label runs-on: ubuntu-latest if: | - ${{(github.event_name == 'pull_request' && github.event.action == 'synchronize') + ${{(github.event_name == 'pull_request' && github.event.action == 'assigned') || (github.event_name == 'pull_request' && github.event.action == 'opened')}} steps: - name: Label PRs - Globe detection From 951f868cef89ad5c778511c4b7f3f95b7fc7ecb4 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 30 Mar 2023 15:14:21 +0200 Subject: [PATCH 08/12] :recycle: move logic from camera loader to reference loader --- .../hosts/maya/plugins/load/load_camera.py | 76 ------------------- .../hosts/maya/plugins/load/load_reference.py | 57 +++++++++++++- 2 files changed, 56 insertions(+), 77 deletions(-) delete mode 100644 openpype/hosts/maya/plugins/load/load_camera.py diff --git a/openpype/hosts/maya/plugins/load/load_camera.py b/openpype/hosts/maya/plugins/load/load_camera.py deleted file mode 100644 index 5e26e8c02f..0000000000 --- a/openpype/hosts/maya/plugins/load/load_camera.py +++ /dev/null @@ -1,76 +0,0 @@ -import openpype.hosts.maya.api.plugin -from openpype.hosts.maya.api.lib import get_container_members - - -class CameraLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): - """Reference Camera""" - - families = ["camera", "camerarig"] - label = "Reference camera" - representations = ["abc", "ma"] - order = -10 - icon = "code-fork" - color = "orange" - - def process_reference(self, context, name, namespace, data): - - import maya.cmds as cmds - # Get family type from the context - - cmds.loadPlugin("AbcImport.mll", quiet=True) - nodes = cmds.file(self.fname, - namespace=namespace, - sharedReferenceFile=False, - groupReference=True, - groupName="{}:{}".format(namespace, name), - reference=True, - returnNewNodes=True) - - cameras = cmds.ls(nodes, type="camera") - - # Check the Maya version, lockTransform has been introduced since - # Maya 2016.5 Ext 2 - version = int(cmds.about(version=True)) - if version >= 2016: - for camera in cameras: - cmds.camera(camera, edit=True, lockTransform=True) - else: - self.log.warning("This version of Maya does not support locking of" - " transforms of cameras.") - - self[:] = nodes - - return nodes - - def update(self, container, representation): - - from maya import cmds - - # Get the modelPanels that used the old camera - members = get_container_members(container) - old_cameras = cmds.ls(members, type="camera", long=True) - update_panels = [] - for panel in cmds.getPanel(type="modelPanel"): - cam = cmds.ls(cmds.modelPanel(panel, query=True, camera=True), - long=True) - - # Often but not always maya returns the transform from the - # modelPanel as opposed to the camera shape, so we convert it - # to explicitly be the camera shape - if cmds.nodeType(cam) != "camera": - cam = cmds.listRelatives(cam, - children=True, - fullPath=True, - type="camera")[0] - if cam in old_cameras: - update_panels.append(panel) - - # Perform regular reference update - super(CameraLoader, self).update(container, representation) - - # Update the modelPanels to contain the new camera - members = get_container_members(container) - new_cameras = cmds.ls(members, type="camera", long=True) - new_camera = new_cameras[0] - for panel in update_panels: - cmds.modelPanel(panel, edit=True, camera=new_camera) diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index d93702a16d..a0345dceb0 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -8,7 +8,10 @@ from openpype.pipeline.create import ( get_legacy_creator_by_name, ) import openpype.hosts.maya.api.plugin -from openpype.hosts.maya.api.lib import maintained_selection +from openpype.hosts.maya.api.lib import ( + maintained_selection, + get_container_members +) class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): @@ -68,6 +71,9 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): new_nodes = (list(set(nodes) - set(shapes))) + # if there are cameras, try to lock their transforms + self._lock_camera_transforms(new_nodes) + current_namespace = pm.namespaceInfo(currentNamespace=True) if current_namespace != ":": @@ -136,6 +142,11 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): def switch(self, container, representation): self.update(container, representation) + def update(self, container, representation): + update_panels = self._update_cameras(container) + super(ReferenceLoader, self).update(container, representation) + self._update_model_panels(container, update_panels) + def _post_process_rig(self, name, namespace, context, options): output = next((node for node in self if @@ -168,3 +179,47 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): options={"useSelection": True}, data={"dependencies": dependency} ) + + def _lock_camera_transforms(self, nodes): + cameras = cmds.ls(nodes, type="camera") + + # Check the Maya version, lockTransform has been introduced since + # Maya 2016.5 Ext 2 + version = int(cmds.about(version=True)) + if version >= 2016: + for camera in cameras: + cmds.camera(camera, edit=True, lockTransform=True) + else: + self.log.warning("This version of Maya does not support locking of" + " transforms of cameras.") + + @staticmethod + def _update_cameras(container): + # Get the modelPanels that used the old camera + members = get_container_members(container) + old_cameras = cmds.ls(members, type="camera", long=True) + update_panels = [] + for panel in cmds.getPanel(type="modelPanel"): + cam = cmds.ls(cmds.modelPanel(panel, query=True, camera=True), + long=True) + + # Often but not always maya returns the transform from the + # modelPanel as opposed to the camera shape, so we convert it + # to explicitly be the camera shape + if cmds.nodeType(cam) != "camera": + cam = cmds.listRelatives(cam, + children=True, + fullPath=True, + type="camera")[0] + if cam in old_cameras: + update_panels.append(panel) + return update_panels + + @staticmethod + def _update_model_panels(container, update_panels): + # Update the modelPanels to contain the new camera + members = get_container_members(container) + new_cameras = cmds.ls(members, type="camera", long=True) + new_camera = new_cameras[0] + for panel in update_panels: + cmds.modelPanel(panel, edit=True, camera=new_camera) From e62b0e48cb5c984595b36f20fb577cc84d5e1998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 30 Mar 2023 15:50:12 +0200 Subject: [PATCH 09/12] Update openpype/hosts/maya/plugins/load/load_reference.py Co-authored-by: Roy Nieterau --- openpype/hosts/maya/plugins/load/load_reference.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index a0345dceb0..60cae131bc 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -218,6 +218,8 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): @staticmethod def _update_model_panels(container, update_panels): # Update the modelPanels to contain the new camera + if not update_panels: + return members = get_container_members(container) new_cameras = cmds.ls(members, type="camera", long=True) new_camera = new_cameras[0] From 52b45f0384ea06be303f6e9392101f41c1b470d3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Mar 2023 16:36:44 +0200 Subject: [PATCH 10/12] Correctly preserve cameras in modelPanels with multiple cameras in a mayaScene --- .../hosts/maya/plugins/load/load_reference.py | 114 ++++++++++++------ 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index 60cae131bc..235bee8ae1 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -1,4 +1,6 @@ import os +import difflib +import contextlib from maya import cmds from openpype.settings import get_project_settings @@ -14,6 +16,78 @@ from openpype.hosts.maya.api.lib import ( ) +@contextlib.contextmanager +def preserve_modelpanel_cameras(container, log=None): + """Preserve camera members of container in the modelPanels. + + This is used to ensure a camera remains in the modelPanels after updating + to a new version. + + """ + + # Get the modelPanels that used the old camera + members = get_container_members(container) + old_cameras = set(cmds.ls(members, type="camera", long=True)) + if not old_cameras: + # No need to manage anything + yield + return + + panel_cameras = {} + for panel in cmds.getPanel(type="modelPanel"): + cam = cmds.ls(cmds.modelPanel(panel, query=True, camera=True), + long=True) + + # Often but not always maya returns the transform from the + # modelPanel as opposed to the camera shape, so we convert it + # to explicitly be the camera shape + if cmds.nodeType(cam) != "camera": + cam = cmds.listRelatives(cam, + children=True, + fullPath=True, + type="camera")[0] + if cam in old_cameras: + panel_cameras[panel] = cam + + if not panel_cameras: + # No need to manage anything + yield + return + + try: + yield + finally: + new_members = get_container_members(container) + new_cameras = set(cmds.ls(new_members, type="camera", long=True)) + if not new_cameras: + return + + for panel, cam_name in panel_cameras.items(): + new_camera = None + if cam_name in new_cameras: + new_camera = cam_name + elif len(new_cameras) == 1: + new_camera = next(iter(new_cameras)) + else: + # Multiple cameras in the updated container but not an exact + # match detected by name. Find the closest match + matches = difflib.get_close_matches(word=cam_name, + possibilities=new_cameras, + n=1) + if matches: + new_camera = matches[0] # best match + if log: + log.info("Camera in '{}' restored with " + "closest match camera: {} (before: {})" + .format(panel, new_camera, cam_name)) + + if not new_camera: + # Unable to find the camera to re-apply in the modelpanel + continue + + cmds.modelPanel(panel, edit=True, camera=new_camera) + + class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): """Reference file""" @@ -143,9 +217,8 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): self.update(container, representation) def update(self, container, representation): - update_panels = self._update_cameras(container) - super(ReferenceLoader, self).update(container, representation) - self._update_model_panels(container, update_panels) + with preserve_modelpanel_cameras(container, log=self.log): + super(ReferenceLoader, self).update(container, representation) def _post_process_rig(self, name, namespace, context, options): @@ -182,6 +255,8 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): def _lock_camera_transforms(self, nodes): cameras = cmds.ls(nodes, type="camera") + if not cameras: + return # Check the Maya version, lockTransform has been introduced since # Maya 2016.5 Ext 2 @@ -192,36 +267,3 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): else: self.log.warning("This version of Maya does not support locking of" " transforms of cameras.") - - @staticmethod - def _update_cameras(container): - # Get the modelPanels that used the old camera - members = get_container_members(container) - old_cameras = cmds.ls(members, type="camera", long=True) - update_panels = [] - for panel in cmds.getPanel(type="modelPanel"): - cam = cmds.ls(cmds.modelPanel(panel, query=True, camera=True), - long=True) - - # Often but not always maya returns the transform from the - # modelPanel as opposed to the camera shape, so we convert it - # to explicitly be the camera shape - if cmds.nodeType(cam) != "camera": - cam = cmds.listRelatives(cam, - children=True, - fullPath=True, - type="camera")[0] - if cam in old_cameras: - update_panels.append(panel) - return update_panels - - @staticmethod - def _update_model_panels(container, update_panels): - # Update the modelPanels to contain the new camera - if not update_panels: - return - members = get_container_members(container) - new_cameras = cmds.ls(members, type="camera", long=True) - new_camera = new_cameras[0] - for panel in update_panels: - cmds.modelPanel(panel, edit=True, camera=new_camera) From 945d31876685fbe1264732748e8f9fbeed8d8d29 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Thu, 30 Mar 2023 16:38:45 +0200 Subject: [PATCH 11/12] Also lock new cameras on update --- openpype/hosts/maya/plugins/load/load_reference.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index 235bee8ae1..82c15ab899 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -220,6 +220,11 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): with preserve_modelpanel_cameras(container, log=self.log): super(ReferenceLoader, self).update(container, representation) + # We also want to lock camera transforms on any new cameras in the + # reference or for a camera which might have changed names. + members = get_container_members(container) + self._lock_camera_transforms(members) + def _post_process_rig(self, name, namespace, context, options): output = next((node for node in self if From 91740ea3561ce4f240710ba0b0dea9e1d5666ee4 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Thu, 30 Mar 2023 17:50:09 +0200 Subject: [PATCH 12/12] Harmony: render what is in timeline in Harmony locally (#4741) * OP-5466 - render what is in timeline in Harmony locally * OP-5466 - validate according to scene start in timeline scene start is denoted by small black triangle in the left on the timeline * OP-5466 - do not force settings from DB Added separate menu item to set frames and resolution from DB to scene. * OP-5466 - added logging details to validator --- openpype/hosts/harmony/api/TB_sceneOpened.js | 19 ++++++++++++++ openpype/hosts/harmony/api/pipeline.py | 2 +- .../harmony/plugins/publish/extract_render.py | 13 +++++++--- .../publish/validate_scene_settings.py | 25 ++++++++++++++----- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/harmony/api/TB_sceneOpened.js b/openpype/hosts/harmony/api/TB_sceneOpened.js index e7cd555332..fe5e6569a8 100644 --- a/openpype/hosts/harmony/api/TB_sceneOpened.js +++ b/openpype/hosts/harmony/api/TB_sceneOpened.js @@ -476,6 +476,25 @@ function start() { action.triggered.connect(self.onSubsetManage); } + /** + * Set scene settings from DB to the scene + */ + self.onSetSceneSettings = function() { + app.avalonClient.send( + { + "module": "openpype.hosts.harmony.api", + "method": "ensure_scene_settings", + "args": [] + }, + false + ); + }; + // add Set Scene Settings + if (app.avalonMenu == null) { + action = menu.addAction('Set Scene Settings...'); + action.triggered.connect(self.onSetSceneSettings); + } + /** * Show Experimental dialog */ diff --git a/openpype/hosts/harmony/api/pipeline.py b/openpype/hosts/harmony/api/pipeline.py index 686770b64e..285ee806a1 100644 --- a/openpype/hosts/harmony/api/pipeline.py +++ b/openpype/hosts/harmony/api/pipeline.py @@ -142,7 +142,7 @@ def application_launch(event): harmony.send({"script": script}) inject_avalon_js() - ensure_scene_settings() + # ensure_scene_settings() check_inventory() diff --git a/openpype/hosts/harmony/plugins/publish/extract_render.py b/openpype/hosts/harmony/plugins/publish/extract_render.py index c29864bb28..38b09902c1 100644 --- a/openpype/hosts/harmony/plugins/publish/extract_render.py +++ b/openpype/hosts/harmony/plugins/publish/extract_render.py @@ -25,8 +25,9 @@ class ExtractRender(pyblish.api.InstancePlugin): application_path = instance.context.data.get("applicationPath") scene_path = instance.context.data.get("scenePath") frame_rate = instance.context.data.get("frameRate") - frame_start = instance.context.data.get("frameStart") - frame_end = instance.context.data.get("frameEnd") + # real value from timeline + frame_start = instance.context.data.get("frameStartHandle") + frame_end = instance.context.data.get("frameEndHandle") audio_path = instance.context.data.get("audioPath") if audio_path and os.path.exists(audio_path): @@ -55,9 +56,13 @@ class ExtractRender(pyblish.api.InstancePlugin): # Execute rendering. Ignoring error cause Harmony returns error code # always. - self.log.info(f"running [ {application_path} -batch {scene_path}") + + args = [application_path, "-batch", + "-frames", str(frame_start), str(frame_end), + "-scene", scene_path] + self.log.info(f"running [ {application_path} {' '.join(args)}") proc = subprocess.Popen( - [application_path, "-batch", scene_path], + args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE diff --git a/openpype/hosts/harmony/plugins/publish/validate_scene_settings.py b/openpype/hosts/harmony/plugins/publish/validate_scene_settings.py index 936533abd6..6e4c6955e4 100644 --- a/openpype/hosts/harmony/plugins/publish/validate_scene_settings.py +++ b/openpype/hosts/harmony/plugins/publish/validate_scene_settings.py @@ -60,7 +60,8 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin): # which is available on 'context.data["assetEntity"]' # - the same approach can be used in 'ValidateSceneSettingsRepair' expected_settings = harmony.get_asset_settings() - self.log.info("scene settings from DB:".format(expected_settings)) + self.log.info("scene settings from DB:{}".format(expected_settings)) + expected_settings.pop("entityType") # not useful for the validation expected_settings = _update_frames(dict.copy(expected_settings)) expected_settings["frameEndHandle"] = expected_settings["frameEnd"] +\ @@ -68,21 +69,32 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin): if (any(re.search(pattern, os.getenv('AVALON_TASK')) for pattern in self.skip_resolution_check)): + self.log.info("Skipping resolution check because of " + "task name and pattern {}".format( + self.skip_resolution_check)) expected_settings.pop("resolutionWidth") expected_settings.pop("resolutionHeight") - entity_type = expected_settings.get("entityType") - if (any(re.search(pattern, entity_type) + if (any(re.search(pattern, os.getenv('AVALON_TASK')) for pattern in self.skip_timelines_check)): + self.log.info("Skipping frames check because of " + "task name and pattern {}".format( + self.skip_timelines_check)) expected_settings.pop('frameStart', None) expected_settings.pop('frameEnd', None) - - expected_settings.pop("entityType") # not useful after the check + expected_settings.pop('frameStartHandle', None) + expected_settings.pop('frameEndHandle', None) asset_name = instance.context.data['anatomyData']['asset'] if any(re.search(pattern, asset_name) for pattern in self.frame_check_filter): - expected_settings.pop("frameEnd") + self.log.info("Skipping frames check because of " + "task name and pattern {}".format( + self.frame_check_filter)) + expected_settings.pop('frameStart', None) + expected_settings.pop('frameEnd', None) + expected_settings.pop('frameStartHandle', None) + expected_settings.pop('frameEndHandle', None) # handle case where ftrack uses only two decimal places # 23.976023976023978 vs. 23.98 @@ -99,6 +111,7 @@ class ValidateSceneSettings(pyblish.api.InstancePlugin): "frameEnd": instance.context.data["frameEnd"], "handleStart": instance.context.data.get("handleStart"), "handleEnd": instance.context.data.get("handleEnd"), + "frameStartHandle": instance.context.data.get("frameStartHandle"), "frameEndHandle": instance.context.data.get("frameEndHandle"), "resolutionWidth": instance.context.data.get("resolutionWidth"), "resolutionHeight": instance.context.data.get("resolutionHeight"),