From 7938f843f0bdd6c9ae56f6978d3e5f211b5495a3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 10 Nov 2022 20:52:40 +0800 Subject: [PATCH 01/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 6 +++++- openpype/settings/defaults/project_settings/maya.json | 1 + .../schemas/schema_maya_render_settings.json | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 2b996702c3..9acb65b84c 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -108,8 +108,10 @@ class RenderSettings(object): # function to revert render settings does not reset AOVs list in MtoA # Fetch current aovs in case there's any. current_aovs = AOVInterface().getAOVs() + remove_aovs = arnold_render_presets["remove_aovs"] + if remove_aovs: # Remove fetched AOVs - AOVInterface().removeAOVs(current_aovs) + AOVInterface().removeAOVs(current_aovs) mel.eval("unifiedRenderGlobalsRevertToDefault") img_ext = arnold_render_presets["image_format"] img_prefix = arnold_render_presets["image_prefix"] @@ -118,6 +120,8 @@ class RenderSettings(object): multi_exr = arnold_render_presets["multilayer_exr"] additional_options = arnold_render_presets["additional_options"] for aov in aovs: + if aov in current_aovs and not remove_aovs: + continue AOVInterface('defaultArnoldRenderOptions').addAOV(aov) cmds.setAttr("defaultResolution.width", width) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 988c0e777a..958025baeb 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -64,6 +64,7 @@ "image_prefix": "//_", "image_format": "exr", "multilayer_exr": true, + "remove_aovs": true, "tiled": true, "aov_list": [], "additional_options": [] diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json index 0cbb684fc6..9beea16b97 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json @@ -69,6 +69,11 @@ "label": "Multilayer (exr)", "type": "boolean" }, + { + "key": "remove_aovs", + "label": "Remove AOVs", + "type": "boolean" + }, { "key": "tiled", "label": "Tiled (tif, exr)", From 377e6e88e1182871a1fc0cfe293e8ae697777a33 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 10 Nov 2022 20:53:24 +0800 Subject: [PATCH 02/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/settings/defaults/project_settings/maya.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 958025baeb..09f3e61391 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -64,7 +64,7 @@ "image_prefix": "//_", "image_format": "exr", "multilayer_exr": true, - "remove_aovs": true, + "remove_aovs": false, "tiled": true, "aov_list": [], "additional_options": [] From 365feefb48189989976a95f65ec1d8a7fc6467cf Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 14 Nov 2022 19:13:23 +0800 Subject: [PATCH 03/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/settings/defaults/project_settings/maya.json | 2 +- .../schemas/schema_maya_render_settings.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 09f3e61391..54b70b4a44 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -64,8 +64,8 @@ "image_prefix": "//_", "image_format": "exr", "multilayer_exr": true, - "remove_aovs": false, "tiled": true, + "remove_aovs": false, "aov_list": [], "additional_options": [] }, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json index 9beea16b97..98d33ade91 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json @@ -70,13 +70,13 @@ "type": "boolean" }, { - "key": "remove_aovs", - "label": "Remove AOVs", + "key": "tiled", + "label": "Tiled (tif, exr)", "type": "boolean" }, { - "key": "tiled", - "label": "Tiled (tif, exr)", + "key": "remove_aovs", + "label": "Remove existing AOVs", "type": "boolean" }, { From 6a1846a36b06184fa16122c4c75b872baf29a012 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 14 Nov 2022 21:10:29 +0800 Subject: [PATCH 04/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 5 +++-- openpype/settings/defaults/project_settings/maya.json | 2 +- .../schemas/schema_maya_render_settings.json | 10 +++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 9acb65b84c..24c183b938 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -101,14 +101,15 @@ class RenderSettings(object): from mtoa.core import createOptions # noqa from mtoa.aovs import AOVInterface # noqa createOptions() - arnold_render_presets = self._project_settings["maya"]["RenderSettings"]["arnold_renderer"] # noqa + render_settings = self._project_settings["maya"]["RenderSettings"] + arnold_render_presets = render_settings["arnold_renderer"] # noqa # Force resetting settings and AOV list to avoid having to deal with # AOV checking logic, for now. # This is a work around because the standard # function to revert render settings does not reset AOVs list in MtoA # Fetch current aovs in case there's any. current_aovs = AOVInterface().getAOVs() - remove_aovs = arnold_render_presets["remove_aovs"] + remove_aovs = render_settings["remove_aovs"] if remove_aovs: # Remove fetched AOVs AOVInterface().removeAOVs(current_aovs) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 54b70b4a44..f97ea47b52 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -59,13 +59,13 @@ "default_render_image_folder": "renders/maya", "enable_all_lights": true, "aov_separator": "underscore", + "remove_aovs": false, "reset_current_frame": false, "arnold_renderer": { "image_prefix": "//_", "image_format": "exr", "multilayer_exr": true, "tiled": true, - "remove_aovs": false, "aov_list": [], "additional_options": [] }, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json index 98d33ade91..c1bafc4108 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json @@ -31,6 +31,11 @@ {"dot": ". (dot)"} ] }, + { + "key": "remove_aovs", + "label": "Remove existing AOVs", + "type": "boolean" + }, { "key": "reset_current_frame", "label": "Reset Current Frame", @@ -74,11 +79,6 @@ "label": "Tiled (tif, exr)", "type": "boolean" }, - { - "key": "remove_aovs", - "label": "Remove existing AOVs", - "type": "boolean" - }, { "key": "aov_list", "label": "AOVs to create", From b17eb8df7d42f2b5fa5680785e4f5570f8f7fd9e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 14 Nov 2022 21:24:57 +0800 Subject: [PATCH 05/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 24c183b938..3e7e62a7a8 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -146,12 +146,17 @@ class RenderSettings(object): def _set_redshift_settings(self, width, height): """Sets settings for Redshift.""" - redshift_render_presets = ( - self._project_settings - ["maya"] - ["RenderSettings"] - ["redshift_renderer"] - ) + render_settings = self._project_settings["maya"]["RenderSettings"] + redshift_render_presets = render_settings["redshift_renderer"] + + remove_aovs = render_settings["remove_aovs"] + if remove_aovs: + aovs = cmds.ls(type='RedshiftAOV') + for aov in aovs: + enabled = cmds.getAttr("{}.enabled".format(aov)) + if enabled: + cmds.delete(aov) + additional_options = redshift_render_presets["additional_options"] ext = redshift_render_presets["image_format"] img_exts = ["iff", "exr", "tif", "png", "tga", "jpg"] From 85d8edcd00edac8ab5b198b014f0f86acde6f1b6 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 14 Nov 2022 21:25:51 +0800 Subject: [PATCH 06/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 3e7e62a7a8..bc817c862e 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -146,7 +146,7 @@ class RenderSettings(object): def _set_redshift_settings(self, width, height): """Sets settings for Redshift.""" - render_settings = self._project_settings["maya"]["RenderSettings"] + render_settings = self._project_settings["maya"]["RenderSettings"] redshift_render_presets = render_settings["redshift_renderer"] remove_aovs = render_settings["remove_aovs"] From 2e2386a349c82d244ae5c0383a865c1d72237c56 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 14 Nov 2022 22:47:33 +0800 Subject: [PATCH 07/46] adding removeAOVs in setting to allow users to choose whether keeping the aovs --- openpype/hosts/maya/api/lib_rendersettings.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index bc817c862e..fa09e26e9e 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -173,12 +173,16 @@ class RenderSettings(object): """Sets important settings for Vray.""" settings = cmds.ls(type="VRaySettingsNode") node = settings[0] if settings else cmds.createNode("VRaySettingsNode") - vray_render_presets = ( - self._project_settings - ["maya"] - ["RenderSettings"] - ["vray_renderer"] - ) + render_settings = self._project_settings["maya"]["RenderSettings"] + vray_render_presets = render_settings["vray_renderer"] + # vrayRenderElement + remove_aovs = vray_render_presets["remove_aovs"] + if remove_aovs: + aovs = cmds.ls(type='VRayRenderElement') + for aov in aovs: + enabled = cmds.getAttr("{}.enabled".format(aov)) + if enabled: + cmds.delete(aov) # Set aov separator # First we need to explicitly set the UI items in Render Settings # because that is also what V-Ray updates to when that Render Settings From 6f65ea4f54590e0e3267880aa64454a56e490005 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 15 Nov 2022 02:39:31 +0800 Subject: [PATCH 08/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index fa09e26e9e..de849db21c 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -176,10 +176,11 @@ class RenderSettings(object): render_settings = self._project_settings["maya"]["RenderSettings"] vray_render_presets = render_settings["vray_renderer"] # vrayRenderElement - remove_aovs = vray_render_presets["remove_aovs"] + remove_aovs = render_settings["remove_aovs"] if remove_aovs: aovs = cmds.ls(type='VRayRenderElement') for aov in aovs: + # remove all aovs except LightSelect enabled = cmds.getAttr("{}.enabled".format(aov)) if enabled: cmds.delete(aov) From 6190e6ba111f66bf3be8beb52b54191aa8fd272f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 15 Nov 2022 03:07:22 +0800 Subject: [PATCH 09/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index de849db21c..f64a86ee07 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -184,6 +184,12 @@ class RenderSettings(object): enabled = cmds.getAttr("{}.enabled".format(aov)) if enabled: cmds.delete(aov) + # remove LightSelect + lightSelect_aovs =cmds.ls(type='VRayRenderElementSet') + for light_aovs in lightSelect_aovs: + light_enabled = cmds.getAttr("{}.enabled".format(light_aovs)) + if light_enabled: + cmds.delete(lightSelect_aovs) # Set aov separator # First we need to explicitly set the UI items in Render Settings # because that is also what V-Ray updates to when that Render Settings From 1b00dec8de85264a05dbb2cdfb5528c3864b094f Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 15 Nov 2022 03:08:08 +0800 Subject: [PATCH 10/46] adding removeAOVs in setting to allow users to choose whether keeping existing AOVs --- openpype/hosts/maya/api/lib_rendersettings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index f64a86ee07..1293f1287d 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -185,7 +185,7 @@ class RenderSettings(object): if enabled: cmds.delete(aov) # remove LightSelect - lightSelect_aovs =cmds.ls(type='VRayRenderElementSet') + lightSelect_aovs = cmds.ls(type='VRayRenderElementSet') for light_aovs in lightSelect_aovs: light_enabled = cmds.getAttr("{}.enabled".format(light_aovs)) if light_enabled: From a9e2e7392295cf8edfcfd1345c31a14b41a12939 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sat, 26 Nov 2022 20:24:53 +0000 Subject: [PATCH 11/46] Maintain time connections on update. --- openpype/hosts/maya/api/plugin.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 39d821f620..985cddaa08 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -217,7 +217,7 @@ class ReferenceLoader(Loader): # Need to save alembic settings and reapply, cause referencing resets # them to incoming data. - alembic_attrs = ["speed", "offset", "cycleType"] + alembic_attrs = ["speed", "offset", "cycleType", "time"] alembic_data = {} if representation["name"] == "abc": alembic_nodes = cmds.ls( @@ -226,7 +226,17 @@ class ReferenceLoader(Loader): if alembic_nodes: for attr in alembic_attrs: node_attr = "{}.{}".format(alembic_nodes[0], attr) - alembic_data[attr] = cmds.getAttr(node_attr) + connections = cmds.listConnections(node_attr, plugs=True) + data = { + "connected": False, + "attribute": None, + "value": cmds.getAttr(node_attr) + } + if connections: + data["connected"] = True + data["attribute"] = connections[0] + + alembic_data[attr] = data else: self.log.debug("No alembic nodes found in {}".format(members)) @@ -263,8 +273,14 @@ class ReferenceLoader(Loader): "{}:*".format(namespace), type="AlembicNode" ) if alembic_nodes: - for attr, value in alembic_data.items(): - cmds.setAttr("{}.{}".format(alembic_nodes[0], attr), value) + for attr, data in alembic_data.items(): + node_attr = "{}.{}".format(alembic_nodes[0], attr) + if data["connected"]: + cmds.connectAttr( + data["attribute"], node_attr, force=True + ) + else: + cmds.setAttr(node_attr, data["value"]) # Fix PLN-40 for older containers created with Avalon that had the # `.verticesOnlySet` set to True. From 0c54d8fcad1babdd9c03891e695db8da46eb7a51 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 28 Nov 2022 10:15:30 +0000 Subject: [PATCH 12/46] Enable thumbnail transparency on extraction. --- openpype/hosts/maya/plugins/publish/extract_thumbnail.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py index 712159c2be..311278145a 100644 --- a/openpype/hosts/maya/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/maya/plugins/publish/extract_thumbnail.py @@ -105,6 +105,11 @@ class ExtractThumbnail(publish.Extractor): pm.currentTime(refreshFrameInt - 1, edit=True) pm.currentTime(refreshFrameInt, edit=True) + # Override transparency if requested. + transparency = instance.data.get("transparency", 0) + if transparency != 0: + preset["viewport2_options"]["transparencyAlgorithm"] = transparency + # Isolate view is requested by having objects in the set besides a # camera. if preset.pop("isolate_view", False) and instance.data.get("isolate"): From 9a439d408bbdb1ed2b32a61b1ab63f1740a72f65 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Wed, 30 Nov 2022 17:36:51 +0000 Subject: [PATCH 13/46] Improvements - account for time attribute reconnection. - simpler data collection --- openpype/hosts/maya/api/plugin.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 985cddaa08..66b525bad1 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -226,15 +226,13 @@ class ReferenceLoader(Loader): if alembic_nodes: for attr in alembic_attrs: node_attr = "{}.{}".format(alembic_nodes[0], attr) - connections = cmds.listConnections(node_attr, plugs=True) + inputs = cmds.listConnections( + node_attr, plugs=True, destination=False + ) data = { - "connected": False, - "attribute": None, + "input": None if inputs is None else inputs[0], "value": cmds.getAttr(node_attr) } - if connections: - data["connected"] = True - data["attribute"] = connections[0] alembic_data[attr] = data else: @@ -275,11 +273,16 @@ class ReferenceLoader(Loader): if alembic_nodes: for attr, data in alembic_data.items(): node_attr = "{}.{}".format(alembic_nodes[0], attr) - if data["connected"]: + if data["input"]: cmds.connectAttr( - data["attribute"], node_attr, force=True + data["input"], node_attr, force=True ) else: + inputs = cmds.listConnections( + node_attr, plugs=True, destination=False + ) + if inputs: + cmds.disconnectAttr(inputs[0], node_attr) cmds.setAttr(node_attr, data["value"]) # Fix PLN-40 for older containers created with Avalon that had the From 505cf706f2041bdeecf6ff04c572276e3d446391 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 6 Dec 2022 15:16:38 +0100 Subject: [PATCH 14/46] DL: refactory env var processing --- .../plugins/publish/submit_publish_job.py | 89 ++++++++++--------- 1 file changed, 47 insertions(+), 42 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 45688e8584..3e3ef03e66 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -126,22 +126,19 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "harmony": [r".*"], # for everything from AE "celaction": [r".*"]} - enviro_filter = [ + enviro_job_filter = [ + "OPENPYPE_METADATA_FILE", + "OPENPYPE_PUBLISH_JOB", + "OPENPYPE_RENDER_JOB", + "OPENPYPE_LOG_NO_COLORS" + ] + + enviro_keys = [ "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", - "OPENPYPE_METADATA_FILE", - "AVALON_PROJECT", - "AVALON_ASSET", - "AVALON_TASK", "AVALON_APP_NAME", - "OPENPYPE_PUBLISH_JOB" - - "OPENPYPE_LOG_NO_COLORS", "OPENPYPE_USERNAME", - "OPENPYPE_RENDER_JOB", - "OPENPYPE_PUBLISH_JOB", - "OPENPYPE_MONGO", "OPENPYPE_VERSION" ] @@ -223,29 +220,41 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): instance_version = instance.data.get("version") # take this if exists if instance_version != 1: override_version = instance_version - output_dir = self._get_publish_folder(instance.context.data['anatomy'], - deepcopy( - instance.data["anatomyData"]), - instance.data.get("asset"), - instances[0]["subset"], - 'render', - override_version) + output_dir = self._get_publish_folder( + instance.context.data['anatomy'], + deepcopy(instance.data["anatomyData"]), + instance.data.get("asset"), + instances[0]["subset"], + 'render', + override_version + ) # Transfer the environment from the original job to this dependent # job so they use the same environment metadata_path, roothless_metadata_path = \ - self._create_metadata_path(instance) + self._create_metadata_path(instance) + + environment = { + "AVALON_PROJECT": legacy_io.Session["AVALON_PROJECT"], + "AVALON_ASSET": legacy_io.Session["AVALON_ASSET"], + "AVALON_TASK": legacy_io.Session["AVALON_TASK"], + "OPENPYPE_LOG_NO_COLORS": "1", + "OPENPYPE_USERNAME": instance.context.data["user"], + "OPENPYPE_PUBLISH_JOB": "1", + "OPENPYPE_RENDER_JOB": "0" + } + + # add environments from self.enviro_keys + for env_key in self.enviro_keys: + if os.getenv(env_key): + environment[env_key] = os.environ[env_key] + + # pass environment keys from self.enviro_job_filter + job_environ = job["Props"].get("Env", {}) + for env_j_key in self.enviro_job_filter: + if job_environ.get(env_j_key): + environment[env_j_key] = job_environ[env_j_key] - environment = job["Props"].get("Env", {}) - environment["AVALON_PROJECT"] = legacy_io.Session["AVALON_PROJECT"] - environment["AVALON_ASSET"] = legacy_io.Session["AVALON_ASSET"] - environment["AVALON_TASK"] = legacy_io.Session["AVALON_TASK"] - environment["AVALON_APP_NAME"] = os.environ.get("AVALON_APP_NAME") - environment["OPENPYPE_VERSION"] = os.environ.get("OPENPYPE_VERSION") - environment["OPENPYPE_LOG_NO_COLORS"] = "1" - environment["OPENPYPE_USERNAME"] = instance.context.data["user"] - environment["OPENPYPE_PUBLISH_JOB"] = "1" - environment["OPENPYPE_RENDER_JOB"] = "0" # Add mongo url if it's enabled if instance.context.data.get("deadlinePassMongoUrl"): mongo_url = os.environ.get("OPENPYPE_MONGO") @@ -309,19 +318,15 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): if instance.data.get("suspend_publish"): payload["JobInfo"]["InitialStatus"] = "Suspended" - index = 0 - for key in environment: - if key.upper() in self.enviro_filter: - payload["JobInfo"].update( - { - "EnvironmentKeyValue%d" - % index: "{key}={value}".format( - key=key, value=environment[key] - ) - } - ) - index += 1 - + for index, (key_, value_) in enumerate(environment.items()): + payload["JobInfo"].update( + { + "EnvironmentKeyValue%d" + % index: "{key}={value}".format( + key=key_, value=value_ + ) + } + ) # remove secondary pool payload["JobInfo"].pop("SecondaryPool", None) From e989db4e004a6fbc9487d74659787e02c7e2bad7 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 6 Dec 2022 15:27:39 +0100 Subject: [PATCH 15/46] pep8 --- .../deadline/plugins/publish/submit_publish_job.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 3e3ef03e66..5ed8c83412 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -126,14 +126,14 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "harmony": [r".*"], # for everything from AE "celaction": [r".*"]} - enviro_job_filter = [ + environ_job_filter = [ "OPENPYPE_METADATA_FILE", "OPENPYPE_PUBLISH_JOB", "OPENPYPE_RENDER_JOB", "OPENPYPE_LOG_NO_COLORS" ] - enviro_keys = [ + environ_keys = [ "FTRACK_API_USER", "FTRACK_API_KEY", "FTRACK_SERVER", @@ -232,7 +232,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): # Transfer the environment from the original job to this dependent # job so they use the same environment metadata_path, roothless_metadata_path = \ - self._create_metadata_path(instance) + self._create_metadata_path(instance) environment = { "AVALON_PROJECT": legacy_io.Session["AVALON_PROJECT"], @@ -244,14 +244,14 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "OPENPYPE_RENDER_JOB": "0" } - # add environments from self.enviro_keys - for env_key in self.enviro_keys: + # add environments from self.environ_keys + for env_key in self.environ_keys: if os.getenv(env_key): environment[env_key] = os.environ[env_key] - # pass environment keys from self.enviro_job_filter + # pass environment keys from self.environ_job_filter job_environ = job["Props"].get("Env", {}) - for env_j_key in self.enviro_job_filter: + for env_j_key in self.environ_job_filter: if job_environ.get(env_j_key): environment[env_j_key] = job_environ[env_j_key] From 4c102b51d6a50ed362ed164b76a72a67349e88f5 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 6 Dec 2022 15:41:03 +0100 Subject: [PATCH 16/46] :memo: add documentation about testing on deadline --- website/docs/assets/deadline_job_version.png | Bin 0 -> 32810 bytes website/docs/dev_deadline.md | 38 +++++++++++++++++++ website/sidebars.js | 3 +- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 website/docs/assets/deadline_job_version.png create mode 100644 website/docs/dev_deadline.md diff --git a/website/docs/assets/deadline_job_version.png b/website/docs/assets/deadline_job_version.png new file mode 100644 index 0000000000000000000000000000000000000000..0b78d6a35c9d1a9a26885511a8c171695285293e GIT binary patch literal 32810 zcmZ^~b9f|C`z@N8*qVuLV`AH!*iOf`CpHGLZQB#uw#|;y(dqfV-?``B=eg&Pdb+B* zYOD9&YrX4T9jUA+g^YlQ009AkEF&$h0s--<9(>Tl!GQ0mE!&lXKR&srNQpvJO%j}d zFQ6<$6ht5(YU2@KjiJHU@Q%{jE)WnXegBS6Lk=Zo5D)>~GU6g?o(314h(=!*8b3Y+ zU=0~pLH@vRBRo)FR;{l(7ociHC*t{`I*g!-?AI%p4Y;-qodf_ z!mz59)%koFxbvAYp`?3lO(S>dmkZq2*T$y%83SN!#)pp2RVtf{vjMzUM#z1S9pK@7 zX*_ksW-+aEX)x6y3-|DvIbI0c|NZ%>FaBdJb*El_J=O48#M4Jgs>N^b=2~4N1D;$e zE(W*iWea)7@N$#TAGBG@8t;MnyLU_HW9<5JV=64bajuo>a{XFC$TMlzJ^ZYjW928O zNQ$?^la*}u3s7RmrLx7v0pVj?J8JFC($lz?(?P|}DSax&iC;S{G~Su8y)T~0b)NM^ zcjvyl;K`!&vX*Mn9<`Xmi+IOn=|!XU=Z$=qTHktj@03c{hENyz>oZ$^-2KXZDqh#4 z)#R<~)23C%5cYe3bwF;MgMSW-ihE4LsGEDZ%L(Xw)?A32&)2Df-PJ$|=oaT;Fxfy} zjS_Gq6Ssv2esuG>=+_|OQ`QyGOTfAcH*-mXb*|qs+`;PUBcK0tRVlV0)B9?!=-tX) z&s91DpyGM*F|_oIy|Y@FJoJWax{=I!^(OvkEE@<4@n%YX3AvRgxQ9n|P<2}fuu-vI zYL$8n<13hrm+*hQTw*_DllK!9FidXo3+f7Et#*m=Co5!W{?-wDRcQxf@L$OWW; zvq@4l?PGs_Cv@*j<6=6!shc{kSae0eAI0>CtTdZm3T4EiO9cdnjb`s1cqq(@`yThr zYyWoac}^yKIak`7y^Ll{eeG=S+4?ysFxX9=H;OqMN;U(W?+mJtD3Y3vb z|6R<3`oZ!d=?lF5&FXbyW)}N_H0YmZ?L{4<6rbBNK39A7?4I%1iqCQ~E9WRN36;U- z{28z%i2aeXDz@~@CDar50mGE-#8%b8T{opCxM$OHL*}6;OR(6zRDxLN$njy2O%xk2 zzSO;RX_&bpwRB{nCt$<-ZORuP*28|_HozOd`)%wwg>xc2nt7}rI&*5bRmeYM)=hD8 z=;?}UYN&AuZ?t>xD=+L&;rE$;$=t#~ryvH$|v>_+mqQ zP>2noUoTIalIO97=ZdvAS&5SL!DfovQ2t%|yIAwq{7U?QTzmHy2D-V9{%)Qah008 zI@jLW(1iR1AO=li5X{UF$gSFUSNY^}Q2nY;$<<-<1aHP;?~ zUr!wFa)jFCZ@?CMZVs<`RvMBoqv&|VcN89&*3 zkUjBN+u=`#1otW*y7(6WxU=+7|p*y-?p z3v%J^F&}K5eYN#>S0&cZmXl7=50CjNHPd*8ivdu(vgsbkW=@T=VQ$C4#bo;Xd#WQS zfbKNi2eP{JN7EM3Kr6OkL^ShA!I`vOHaE&qz^;5pfG3;##{=bgfDeHn7c1u8Ue=PN zDvslRbM=nuZz_{>n$wEv>z&@8#bmF^*fX!M=)cLnr^UaVXDN9bWX{JKc1Ee5bPVeA z!|X|Bhoc5OLb-Q5d&##Pf5~ujqT=j&ka_LCt)?b*Yis+^k_NtUoi0}c$8RMqropJEjdT+8wU!( zYzJ>|>(>%y86$q55!uR;K_N>_seng#{AQKxgzJ?Zn-sFUbK7{}x#zN(<*()Ic#=EV zJ>@zO`WO8Nu7(ezPeiMBdC(%92#Xj+SO5GLxHyqtP zu%HMMIBIy!tsBBq%<;H8ct2U$UilF9E1I@j`0@0D&=skxSHi3Jw|GydBdU2J{Qht{ z4YZKok$DIBELRAfjDDh9c_G>jHN21OE)z*4a6u#mLQbJ8JAL63S^v4>GGHY|2qJ+K zBb-vovO+ZUU9|ceE(IL?3AtR~iWSS;MW2=mevrlN+ThNB+MV+iN8#hB`r5#or>gr| z!*d*hUjz+G1P8&>ms~1rB@)tQW?Z7>veCPNP*9GY4g8()@U}5*EI_wsYkHFJiXR;S zuBoh+s}SU-=*4ufHa_2Lg%#@#MY;@U^N|FAb&?+k$F=&54eDp}Vvpw3(wrUQpnw zbK@PY0E;Ydx0Co%Y1$@Ws==if81NEs*_&Zi?;0}nCI1g&x%6r+XP*w@%Scmp-c5M? z_BPv#I2$JTbx;U*@3>O$d9yVi5yLo9=b7>O@*_jjN7YyEJ@Sy)*6&tkdh_9f9Zy~F zd`HAltX_ACS_b#s5-ITD9{NcVu$dwl^lHuJUBAN;Zy)nXk?$PyrSKjG>|`@_YS+#cmV4dSzUTxvSm7{OoaJiEBiz*pGSM*f7F!`)OWbG*BFyhee3d-ManRDoXL zucR|BpF?IB)rcn3F~DHOJVbH&cSRfrMZ+{8@D?8vKJ4pXP<(v3DUI$Asb9;eV&$4S zoJaID*V;vsDCgNNS)%}z2}fx%j`3k`x0{ks;Jr`)Mq|2v2z3*G zWLlWp^7Xh~yq5=Qy-<`InGu zBa+X)EBJv&ZF^Gpc)8bnINQ4u{l}l?DfnC$p|=?o>ZoA|w93GH=$ZS(yyq5mSm@af zX{!4Kj0UY|1zZO9N0rulEfRnvcxH0n8L+)9M`v@g?{IZLJG@@p=es|>7;g1!87}QO zG`w-W+r)KV2N?8E;b$+bYV+&hfA^Wt%=tsP_^P@9lB;rQD7@4n>k7m7Qw3Djgh3!U+3ZsGxLQ}X3#dW(Poch3X z6MCgR^}kb{uL2LhlH+m&WDirvUHew~#i}>L8SMmWwu;rq?Gkh9>&Exn9)t(e1<+b9 za=^3Jns(?L^x)m$k%O$_1Rd<}cb`ukr&_pFjnlPR>9D=LHjvdX@cG}5S^V!! z(E#z^t}Y^t4VoUO0pkf=aInQ&(&BYtHbh+4gU|WK6WrqEJKJRYjU0D}N3;ytzh_Qj zv0s|<50hul;Qz1k{s*O`LjHq& z|IgR_X91gEx{k-^(B8LcHo2W4E~Z}5CSJCZbDzOY?M>+MnRy|7HM#w5`L=L|!+Pp0 zpUp)~6wgEVZw$mBlop478r$60A>Lw{tl9|mOlnSHO#G)!-y&eq{xxWr98&mSn@Qv0 z{)?TMQYo2M@BaW=6!h;L@PE$zEdS?x?|(zXKcEP?8=8B#B@PRC>kZgFSW@g6z^rHW z?~i_JmTJ0xo__8Ac)J3~p@HI*0zh-%li6sGEkA7HfLB&Q&@nkC`5ko@HMo<4=^NUF zFAxshKq>>i213-Ow>ra+6$k%Y{Ca9Q>d8b+1KM7BX*sQgH(-1~e|dG6wMoc3;4hUz zGz%sO4;>)dcJr|2u-E;5);*rZf;P-wpF!v9u0c9<4(>|^jfoC{CyaW^ff{ror)8*7 zV#F74?{klk(pbi{7a||>sP?`2uS*i5i_Tl~NdJL}03abmoA#3FHpg3phgTlSvb^K( z`B8=F^x|@mGD12ltVW|adux)4;`q?7LI;r_P(`|!>?i*j%BgL*`i#iy@U$9QvJrwm zd0tmgYC3qjmuxg;Tw4vk=EL^vz(A~hO-En46GUaP&lUOW)pI4UnKbP~zrunN08g^l z{g{;3srq0P{tW{u>|9fJ+p?GxL=mDjO=<{F{B_9yC7T)lH%%e6TI|MJqQKGCt2B7OSlXbp*)5F~pzU&EAIUQS=ZBq&Su{Ph1g0^g}wC*+BEX&VujiHaqg$b7^14D11;v z*h>p6RLy+Q)0`F3*2|>*dTWL>Z=l>a4|;-^^uy2OJ<;YAVsmUQUoHi#D4jGCOV!6n4WgPvV)5#Bi1SSqEK1 zeL`3?k+DnWrOO}LVo!H%HqvRy_9DL~@R$?J4x3zbFiqi0d5>NxG4QPHyfuNt_W+px zzK%&L=&84gY^7d-UiwYLXaF;*N$fdm*{VsM5oom*`@p)FU~Hwqx@vKC`=D5EkFYMO z?y>JM5;Y7gaI1$f4SaC(;L*!w8gla2$ZXGo(1#Ht(pUx_c3ic?n+|F%MTyH zFZ3*ptr##Rp8|{X>=CHxg8_hZEl#3V1qsXMiC}Z#IjY$?>+jr!c<*?aQ-KrlRE8cZ z@>{h?i9O%iyFl=yUT6G~U~0x`weCaMhUbEP0VGNtXxu79UbC%v_h z33IEw6E~cA-b$7;Zs6uc0hJ%XV9*-CYo&8B+<7Lr{f_IM4keK%xT1OEwol{*9sY|m zk@u-B-N}q{!MLHUZ^lbHB4*95q3X-2MujnYqV4?j)#6;zQQXdc#UA#q%5KaH(6kn!h`7)&X>6=vx?aaM4OH@d z%{XxEJZ;0dhzgm*!Se4qWBD5AT6^r?`LHWp)n!0rL5O5i;(G4=3*a^9Jk!-)>0yVh zh}W^)Ovu>nPq=wo?__sk_jKe!^H3=S1_c&*Zhin=m7JAYhy?y+>SS84y}V0WKM3-4 z_~J^V)W3L?Ae{BCnA+kGhU|92wh{$T#)W!dBdtrtlx5%LgPwf5AnKg+nn;~I8pf{v zgAwxS|8KSmf&T_NioD{TiN{v6cqw2*QQ{bOwQA8S48!TRguCpQ<(jLIz z*Hcq8_{KBY8sIffOnn!!_DQ15C4hlF6jYTS#Y))TZsSNDRqm$-E5~wgXGhnyO#Ueo z$*zt6br0$@$7zP0XnPGT>uzexQgoGDdzV42nKAyGrD@VuXf6KI;~U42Rx)j?2s-hH4jADXZ%=mqI^f}5_05)9Umph-79<#@zlMRy#WO`Dm%iWOZ`CJ z%N^P`rBxR-5VdTZqhTr0r{R-Rd%>8*#|Niox%-VP>n&qTp>ql|Vt)D0I;afBE?di+ z!yMs}E=yI_dx;qDi{^0yA*USqL~cX~O4rTYZvr#84zW?MtX5heZ$jsT%JyeCB6&4j z_~A||6w@iD=Qc))p@%e~m(5~Uhh5fJ_dW%!#~{xM>{()9+7*cdw7cS3>`5f$%yiJy z$ys%dE1V*_=j{X+a8`~vRlt}82TFheR$XLhSWF7ee))${jqC(2K1;t%7mN6a3sU=* z8#c&*p1{m=TWTnNX{5xIloCcH#Vu#uLGtU3_=z${k!PoO$j zBS}n8=+sr#j=PFz_fG@E;pL4lHh|XGW@tvqU>n+4OBeV|M2~2PKv|+nzm*p?dp}%w zWr2^F{Yv3esbSNJT-AXvDCQy>`M0O7$fq#i0 zdTTg)GdwmSkRgl}V)o~IfnyC;GpmMh6^2ST(bOFEMe0{h4$L`w6bx?IvjcYuvF*S6$=MQ?lvC(%d{=(DMhn?9&RafH9si(w;j z`OvzHCnHqzutHB?^vMrtRP$L?!SH*Rpya!Y$$eH)?|9jIB#ZNdg*{Z8|ETvna5UA? zCLhZgpp8Ri!8E|v$a{ukWi@fSr^{$%(OQB4V)-ukFSIKV5L07|KGItz+%g~%&G{j& zEyaVS@p8^Fby^?HZ7I8JirPG>HWcKt6;@oa@ni!Gr-a=rNtrV{a?l6Hmyug}|fQ zLCj@>F2#xD4OU4_&|Z=>O!v=FY|C~3QI8}2fL(*05l{0!jiI6MOfT$qYU&*>-Qacl z{GOcf07s}$mIrt8{!585&4xYZr!62nVTI_oG*o9yY69?lnd~XMH@|*nkowyy zD;MR?a_)5CAX3Wu()wV^gQsyqh7zmZ`Dqa&p8zer(8~4Qc74NZy`UK6Vwysrpv?q3 z{Ey*v{}jx}l`%5s!dp^n65Byx&@D-h{2upXtXf#kr>U>U@wYq6I6(IImd&%;{u|?Y z8eL>My}MB@k=Cf|D4N4K}AoM_4W_H36c@q(&#KuI*&Ni*tMVHw^;& z_#RyA4|YqQ*OaayVmfVu_C8_BgdKV?h?$pjZa|m&hX?6hNI$ihk0KVabkqOLH@5EE z+ye+pA=j9_eiN{sIr-r^@?2nCI$w2nA)%0>qh*1@;^zLM=0$KGNd9lA19q%lo>BX{ z{da_bH#WuFyOAq6Lc0>LYvgN+D5xa-H`A@$B`gJKs3buoTAo{fL!ZuL@L3%Uh^p}1 zu;RKNvv?@}!|5TlKTG1&MF7Ctg#>8)Ke|zf!8hL!ZL4U3V^JSebZ~zZv0$W9fR=-M z{Jb-)lS-{gvfpl|PF$A{ezbgHg+MNAfHJX4P7nA^H2%qJdSMbs?;Ry_yRzk{4 z1wv@3!F(P){49fo!(!g{EC@ z#$AGLTx@HG#sv;fGs3;O2nT$|7^-U=c6ZE4@6TA8RDZ&%_DO{19Ht`3X{eA>$1z4X zIAqFDfd)h$R_G<|*!+@ZYyPQ8Z?ST_ z;yyxT1-OGL)>UoP;nZkR@zGi*YaNc~9|2?wgh%SSjg-58wRo_KnrK$eBAN-w>-p#l zNv)Bqnrf6^zZJ1b&e3V3&n#=~1EUcJu5>Zk4?#kDl#Yg3X{n?KXcW5EbTg2)hoGagSP0iu4eRb)ZY&> zz~+R}6Ez~SYJ$NOr&Mb`2Wuvj?z}6I^2TTVIJ&d1>mAe5D(xtO&BL-^a@%xSHWUMJ zxENauh__u@4Vz2N$Q|c8*QpS@I9Vq{q1HRO2z!F5-ocDrv{@O=duSVxEzfkNPZ&4g zahK42v3=fsFZfDyh?PYv2HGWj<;Oq?Yfc{-xPE9l}7_QD%lY8t8tpY=Df*^SuTxQahh%#fy>rcE9yyl=G&wi|Lfhw9hew#o4eHgo-qNo%f=SnoRue z-uB&!)sub=R`kCmmZ%n63HEJzfI883?T-eJV_Syx&DRds;9@R+%p)`>3wHNQ#O-i03l!=J{6>%MU>>`?c+zi1y_s7St@Ko&vY zXA;!8K@|%>manBV;R(XVjAK|`l5(encFP-rSbH~Bee>j!eP%ssd|!QJ<(~^wXhrZ) zv3%WBYq^XXL}dfG7vwO`^m^@Dq&oG^2iYl)W2`jLyd(cF(osVP@BH=i>Sxai z(tG}nO{BaC1JsHp;h~qKsd%Iw50s(!&8D##Na2dtvY4RHOK84=gNIV(wqK|E?i9S+ z87Fyhd}xGh%;Ijw))YP)ANOpf4H~URS>d!>U}KEdP1AGp9|E*Ac(>eCS&RI*OlY}i zMGgp^{v>}(dcX>9+6Z^L)#uu~whs@pvI+^gYNIVcrs~NJEOm(iu@9Db7Rw~Dvm7IKYZn7~*_xTURPjIArEf zi$Jvf!Niv7dauMmc_SAkl|8Z6RHune+URn*p?-ekb(4N< zteqTC5}kBW&5SJXoA0Fe7Hm^PBUp|Lv)FoJKUClk+p=$gKQlm+>JtT#$Av+Q)JR8v z0%IdwkRutApK+3E=%gaBffRiCjg7lE26`IE()<1LLT*Li4;XI5PY_9uoB_7djd~Wm z=q=#a-bS~r0J$0sAbPU6u+qNj>u``ghD!zdZ$FW;g9pvGe;CaLGc)c95vw3PqsKTQ zdqpc&6G?_tOZb`X`(&_%3O`{A{=wbSV%V_*fAQZ8s$KDAZK==B0-0}ZVCC} zmm#kCFBfZtB(d#`R+^x`p6XC1P&xP~^7C0O->Px+#6t{sv#{WtdT zTjttn&OZrM8L5ti+^H!KFV~SCkI}gA`fs$q8=Nf(X>n3)tymz2J$M9rr%k3qQ}Jka z+}bNt`kmp{YvC0lxZedx^D^Kb`2-d~|H#%KTwi0X=s0sHg3m(5T|(M%0SiWmY!C%U zEtzois-_iIpD3;?+_mJ|?pk;;mchh+9_5!g1UM}znr+%%Z_?5SnB-Gh*M>idZ>h(C z>Jbe|WdZ96EPF3XXdye%|2IBQHXhPYT-IDfnWGNnQ|C z>}KlrgzaO{-;Qk%Y*W<+SKM(=*5zkN_>B#mU^`Jz3SCKImC-!M2oX67LS*`zD;Dl} zm}-%RL;6*czuRuA`@$FK@uVfu{l0K( zcvMt$s7$dWA@6@8hTlndxM^G8QM!dVV7oHn!p9Irm8R$DDWq`*cj}%!&ugDskXYl8 zZxaN2$7jd?EFL;;;}1(Dc3#X6Hb5F?S0nkv6Kmc!FY`F{@|XrCI3W@RykePYH4kE6 z4JK9UIz3`fbdexIEE)JzBFN;v+}92fJko!295apINkXcpU+zZ-1i$Y5Bz$7JrYY`Z zTdIJqxNxX;P9eRAI#n*gQ|&N#;+l}~(?*N7O4nC~4q9pHE%*|WQe&jci6BIu9t-Pl zybG0^T??fx`}ty;sN)B-(W$v)nz?*oCw9$I!sb`9|JE?mQddXtw7M3_5PhB%MF>mm zpkcskjfkKuhnGg8MH8#fBc1QK;>+I!vgU7gg+E0-E%fQdy#+2ORW8e>tu9u^oBC57 zjr@HbYTo55Xf0*mVcxA`bY%!`rj$O`PT{mmLjXRshclgf5k2+(8M}LLnfZI`GcB=( zdrPdT0loBg+R;s%9gkE_(AK;lSiEg#(Piw+JcJH_WPvM~DwX(TWk#e#epvF`Mnrf# zCJ54R?sk!*M9U93tKE+k{@a=H6WOJK0F2TUo#=P;(6#Kog{|GmZIaV$Zz99tR*m8p z6O=0d9a9&N^->9Gr!bc2C)KCB-G0FG2sT9CExSt=Df$9GS&sIE_{*Udfki^krRVXeW<|gOIM>Fq;zT{4ggxl){Fht`-azP^$QQF{K|Yb=k_a%MDskXnBLV9W3ib zI9Gvn&)s`wCV6Z-OYmvTXG0J96nNGB9mi)wP4Cv4Z~j6m$o7JKY5TbjKPIdZUP`5t z@ma9>%E=`gHCT7`1%|2L!eTwb>-NTRp`_mNuJds`*I%6R#iWvSFc+e6aoSgqa}#MM zzR_-0TkO^b@h;8c{pKYm^*gNgjJC9-=9}0uJ4jcno+R2GWp81|#pxE?G`+|}VCBcm z76?nyVYP%0Qv^rY-K`_4bt^4ebIqf)+62L$_H5QCRkgb3_*i!-*Qs>xZpmeM{m2%8 z1MtM2$PVAdcj#YlH5{l6q-?P{n3^CJ!MSwJ^#`Il7I<JNA78l7*I6_?hxX}& zmTMWq zLxzRNELL8=+41j5twR%jSsX}V*bz&<#>2C!TQSK7-lZ#N&`TS!MPAjr4+HlUpP_R< z(6(Ya$^EDl5JmA^^d}cQ-)Yg!f)c7C0E0wQi;#$w4lZDCMRD570Jfp+0~D#B@x(c5 zz*Dd@H$%bXHXIukiO<-!$Fh|!B+-}ow9LQ)=1}cPI;b-Nt%Rs}nVpc6QkIvez4(9L zkiOU+On~C2UeTORf}S2U%e+)%ZEw2q{q#x_B*WRgbnT&UPcG#<)hu#>kwHWcG(a@&T$sh$QH+LK-Y!D%S^q@M{NGS2KP56?A!f-1$M1GV| zx?rOTa8(E8$YS8OJ22E&ptN4ay%am}`sfZUmjTEgc*t`sHY=4vOX>pgV#Oxk8%(SsxA&b$l-qzZrl*IfC_Y?Uk*Y1j z0KJ~UDJ(;y1pAi;NHYYy>8;NEpsKI-$4xAPM_!csv$_R1lDRuOs5lk(`Tl!v6NyA? zF>X@*@DpkynN~yB5uvvt>q6C<{`vTsul;A^d97Y517H4Mjr5CdrZk4--Ji>y$q3h) z-(c_MDCRC&AM*7C)ru*9*J&rs#Eaqg3}^^p2_LEW8UAS!uTW`S@UO69s%0CLbr`5` zrg|fom%98d*!!|P2xGgs{sY-Y!wA?A?RvgUf4}ufEd4zw@!(kbaImn2dgqM%J1_oo zMQLRKZl*SEL9_CK6mMWgtHd>sLmg<|!gt`z`5jy8WWwQ?%s~6jF`8}vE-=7{y;9he z1yKUsDojCP`o-7qxH!$^zWnFt+$+QZP-3>f;EPAHmvZM{o|*{%$93xv#OPQSo*%Gu z!8CHuhYQEe0DG>+9?A)VnuFdty7{ZOc3RFrUbGK*mY*t z3xsrKy_X);`Jz}F);-88+2j4&^{^C3k`wlqTACR1RQaxOpYp|Yny#+;>cO@;7KP>_xU4G-#eT#rh`gkW!Z*0oRYypVUuhj@{qj4+ccd%`Mt?^n%EAWX8}8OX1|8U{P=4o zpBfmq#{gIb*yAMP|6?9_gXTkiNJA_Y{nHvK#kD#_qjlS)2S5miXVLI3{%sOAr*$x` z8?-ck#Y_{?FV#HuXV2BvmXE)wiSPvRl5O&rDZ$*)Up#FJ#SBtZvQf3-Pz5b3dX#!& zJ93@dqnwbo$Vh*0$U=ODv2R0S!&U@%?~%&wy)pZRK4i3I8%4p}oMt@oekjH>{$gy- zl|HNnz8EG=^fPX%^Cog<^7C3rSVzc2b^v*Bu<_Hj$K;5sG|jiIDXB>Oad@1kK<)&) z-Y$vvD_iILSN#*)Wp7E3&B`&A*NNT2C7^Y%X-;YPg`y+*pa!yHQ>S{75W39d- z-t3K$B@$xAdSgaB-M17i(O!BSFEMp0tI>K*zb8(wT^Y9fCcJxvNGD(Xrd;f7Xa$KU z#o866AJ)x6vzMRat+@8SU@3~AGYjIfu6})N;~7|iT!8BVVvyW1Q=|kja2KUHs6W8j zNp|av)4HX=U=|%=x1gcCPM*_AL(rb35|6E#zUFOQo_Lx$k6-!dU zQA4Gl`i`E(c&G3{tpoa22T78uC@+G1%%IbkT(cs)sJc?)`F_Hd_0iN9MbbP~HXvmk zhS@(lNqJG$xY9<3i66T=AacWCLF=@ofs~n(qR$QH=oWNsl@wj!YAuNSQ z5K(3LmcY8ZnXSTL+Hvmt6+xsH_+5x8}%q;!0g_%L%T=O}r z*a7(-1QNd}*O%FR%;!Ue1OwDdCsfaypAUwTcuDu|z#7nM5JazykjBe}xd;R8JePUL zo%`$NF!$%ByLiFB?iL*XpFEpr8ZX{qE5q)KGD`#>y@+(+EFgrQR~4k8vx+g8A&H8R z$!sSU(layuXB7A6Ixj`a_z35wkx;9D)C|_zg*usHfx@Ir$p%#cLeQFm4uv>st{^&0 z9ttTTO=f1i22qUZ!=7nZIkJezAW|G)@N)szq~D7eTeLmml5qwRwJ)EsvBuPM678H! zJQ{Mn(s3!^VNus1RRC=1!EXXI9lTd>7p2?xKI+Q%lc2lY7&c(_e=eEJozPm1ja*U; zjP*dCJY!%^Mc8-sCZO&Px2`HSdjSKk3^S-8Y7P8xzZ2(7dvdOm{IXv=SQ=yw#n3 zzh6F?#0(!9^Dwe8zz3L{k%)yNxI#CXgj4=Sxe(Sg;P7UkCb(d#@u52{X;PN6;5p61 zE_(v@=i*7Nam)847pGllbIk8Z#3>oJDjlKEhV8l~Ua$Ww^v~AjNPY6(NS;9VyCURO zi^OfP+aiUZMTMP}OJRkl`e=2ulpduITydWP`qcCpJ|w4s_#(2F%k+Q^^{uQT{?@@d z@$#vZrrcN>M9X{o9u0=MqY>Ql8b|YGok|hX=fqUlho9`qYb(#b?MoEkrmf{XEI1@7 zcxdRdk=4cA*an2$n2Ce&9;Z3kTe;qqGSPD8hXe&h?-Dl71$~GV(Uqu?6+)E|fjm>k zW<&a_^7fw)eYlmx@A}aULlMB;(A*#_MM+hSRUcNsq$7&&LeP{wS^bu(3nUF<3T?pi=AkQD3h7|_;!25mx0Mg zNQLi0lYGWcUEF7u`-pR!i@}LJWg->UXS-a3%m*0nPcF52G@o5#p#64=?U6>ngM1K~ z^6ahDcZz4WdHCA&6TG;P9jZLda6^KYV?;`7%cv6 z>|bsLhQKRr(P|p7EqI8NKQwG2z4oLSU-|aBv*lp*J6NkjGF(GIXWR#I~S^M><8}GfL#+U92`95Un9&EYb>g7mpUb_5pIT*dBrE;5S!7P zs5{u{+2Uu_2160wlTAS#&jnvoz@8TdV^w_^cQx*YUkJ@BHO9Kwvcw2E(F@<8({bFg z8;k3eBKF1DSN66WLnoY zk@P?V3*DXE+DTCU*)o6pxsAZ;r04c0mrbwWW6PAI)ce7OM8{du%L=fm8fSebrjXHl zKl^LH(r*&9$&t$MX{r^eD_{?379gp9JfvikM z|BFs9Wi+#BF19}DqBBfnLo#C*{Bj~{ywc(o)GprZxKfX397l(>@ZoS;%Vjz0A9~_< z&Oh7P)> z{kv_h2TH0}<#D=&kxz&VFKg%g_CI$d{jiy=ow>_U{u^`_1^*}LG=Pu% z<0Odr$w;BNR*-vdC91YqyRzjkg&iz!jV=E{p~Z+hqSS%JtjlzkQ&nzVueEyqa4p39 zCuSG_&7&h$oRKqT2QFv?(U0B#|Gzk#D*e~%cmen%3yBJ`kKDf zatBzGI3d{Q8~qw4(C9SQ(a8xY?x)2|Lt2frT2DFcDum4I7LxA9g~>%#l6j`0`k?K_NW;ug!J zP98#9Uh<}#JH!$qcR1U^<}JZYl(1*JxgC%1IG6jvBXtUdB{sI9)s|HowH_S=1&_px zWU@#5~r`^m6=jP(i_TSa8_(hi1)t^(S+SX3s&autgpW-szcwP4zeuW zMyGzww&u%o;@RSyGLYSB3+*Z{Mtp3W^O5G}e(4zA9Wds27cTt%%=f!nE7b|c-H(6r zM_#25*Mnym${)=plS6{l!w}zqCJhs9SZ4oFiG20i9%fAAmXLa{l5mDnQ?Aje4}2>L)5O4w&4E`^GqVz z7HXd86@7VJD`FWRq18APyPs%qN7RX3(G~bp0oP`2xFQFt)IIj`{JE3G zu#Vq2U5#krJy?pn@C9N7OU%6s2j~JRL={(Tcedzetvm@tdhHnBw;0VgK+}EBZ3~;C zpWGdo^mG&a2}C1IKYlH(u&m{4`CSBUoS=L*@DpNsRSNlLhaG=0uQrir76ZdT#E#ME zPvj~V9+eWm71mXIjWiEfp+h7 zh{Df{JMSbLD@hdODy|x%7{07rEL|N76Ga)?!~JyZewme8q363_zco`vROqN#UoVEj zHO7$oNVhrh7dc^SUF~p#Ugv3-`%7-c$7w2u>7pJtMtrfWJmM7R4>6Qn#F}5K@;flJ z+V1*^?VFULel!y6LJE6N#}#DCfhWDIK#0F6yt7en|{$}hqkzBWs}hMl5~`d02mnebOc|3(M1Y~AjVat^plm6qywlRF;z z9gt#KPkJ@i9l>B)Z}vwfWX^1+Zy118oI2&(ps^Jyvlr#-qtXY#DtHLjt@DM+o@0$# z+U`?P$$-s0?AsAWQ?Srr`V(F^5sm1Yui(!+0s`}ar$v42cHOU_kSwP4u}2l^PS@i* zCv4_JiJ;)0TRiV%Lns-K60uUTY&C`v#}afqo-jnT1PEnU^JzL?pn}RWt*7BSjRvra zE`gZ;iRLO)?|FvA3bONeEVaH?JsOEPG}37JovkUA;^93}6yrQYhI} z;*MR>TG!0D9_E8;5U&Q7)p&urgJ*u>v0Af@VrO&50-09d44f{Ry=XPlqcO_ zF`s6yUlnD;&UHc&eAhzc5E!k%L!D0*$C`w9os0}Tk651lr3Gmk4+99&ACL4b#i;JW zWYm;qqcVM-6yx4MhiG$y%NT5>p}P1NWl=A-rT$L7a%HS(b$K?cJa8du{J>3A{8_{H z&Cc!50mED(RU2awlcsl+i(A5g+bIrnHSr#Mh$~5tU(y$gO-x$qSfF52?Wc4uE~CD* zuUh;UWQ2SVvTq(FC5%6o@Rf{_|J0!yl5J{ z@BJn$T`tSn?JQR;F6mdhiTF0Wc3HfhQEVq{`YK|O%u194tNv=7*FY`j5+0A1hcQND z)S=QBr#k}{61Gcg$1=N|vlVx_vx7!7l+Eg}wTTp1SzwNg#V$aAH%KDu=id_Nbk?zD0GeB;(zdv_HKYc#nW0bq>uX;ixcUl$9 z6WaQ3(wH!MEu%34y$U#ZvSB|>$DgNaY~h%%5KqHh4N8!3D>|ntHF%vrwAo1IT-(?? z{)u$=mcJvpR>Uvy;CL237`fxk! zTEVcrM?V>b?%}&gG3cr}vFyrLCO|4{!b3pOf8$rXl?hA-^cB{4MfSH0xJr^IpWmmt zEnEDjf=fgXzt6lZ43O(Vw(TDg)qQLO2|+HjCoVQ8E{YWd7&?1RfRafideo0X7pBqx zV9$?Vsi;XcmLAwV%milrVYW+5CKO$=ag7Yla7|i89L4{vkP%$f_pB9FLPbX|vZD5i z`;({pJ|(s(ViU!=WGe2`t7bb}LUePVaLHb*Bw2L%Ub?bBTF-q~MphqUM&Q{+4f%;g zqVW{W&6kwzSfW0FO8&vo;%zFQ0q}qjjFj7-6AO^KQ**y}E0xdw98?OWfyDTcn@ zs)a&7h4`qd3CJ<+nt&3ScF>(|9zE2d=Y;yM^4Clg@0z~hop+#>j@cidu0PYD-8>_7 zW)_;n95cs#qjAT*uVZ;__{X%*KY!ds1B^`ApF?e^{o%XTA{dV$J8q&Y(}sUCiQupg zn;M3jiZfB*7XRPUi^%jRljqm{4hy^sNn1@zzWCi0-apG5I}fo%%gtAgAu=-F%Tk9; zrxlENsaC802iM!Zgm>X+eI&A#_cgvWDS7O>Bts>VB$bb8O^7buO48zCsJkjmW(j89 zv$@NtSYU%2fOv%Lv#EF_JN^~_E4bas&Lp1ZM(a%Ux3Jo+k+e?*@hY5Mc+)$Zpz5ke_umqZNi?K8%UQ3AoWRkVfs3W)8mx8C2U5|4+NF`|t0 zmnuJKp3sSovvt@+gAt?*LJSojI<-ETj)Xsn@e%zH(_uBd#8xSe3sn-fqL^8<}s0vdN0J8_mRq=&lf zi5*e2{^S_d*g}8pgcg-{9~LL0Dep)>iV-$_?gQSRd@M*@d4Y<9M#g;a5@&ndm#Rqx z?`gdBpcfoFJz;@2riDnC8)!p>cOv-xsEj)~15J?ZOk)e%w4`24*29`^qDi;VU$<=7$1DX;em;ldOc zXl_R{=pOru&rR2A_$jNGINcvicY*x}uvYq-r2A9zibc}SqMVV3`vqRqh>~rkw)z|4 zu?m+~3~X;~)uaS21(UuX#7>p&jn(Osu)^R)ZbFce?LG9~d@#Snbe<&c^NBULoQjkxd zz!iEh#%H#GJwzK$D)kcDIWIOWp9&cKqKJuC0XLEoL-W8eKd+o5f=Yq}W<ZnXPYKnhKWEk}_3?LUnc$m{`Ll8^{4GkZRrA2dg1YJiwt%Rt+VEf*B?E&H!yE`# z7uf?H@fbYYrV!1O<<+tZ@;5erwda4=Z#xovpOJ_S(<}Pgj2o(_a2YlApM*#Ek}ynB zMjBHj?gZ5fHTU}FKw_kl4s2he&YBEtYl!|Q{+v?o2xfhfby0HB`Pqs})CylEz5#Xd z@F`0MtG>C*(XXd6u;w}kUQ41GxP%}*a6R$bErnfy^&wQ?{gE%z?QYpDE@WBkJpAJO zxI*5oMzzVWl2In#4WBm4aU~%%*5r#_dqpJ*UUnvJ6`?+>ns_EievrOSHNFkDfqKMR z(btCNL<-+CRlc_pFIvm}PuvTm`U*KsHq;D?w#&1+UwsAfE{@72#*%*^ZrCTU#rXU0 zSiW3rJFRtgA&;|_9|$o?%%;Vf+QrDBeSm5rphd|aWS6OnoDN?IXo8_M!l;oAaMctV zk-#=dAf8m6X}mn)Y+pU2)@A+tsQ5GC+p zL|H+`&Z*0LM-ctKx;aLKzye~<^!K}ySi0E>Hv{8&sdGQs3$eYB^N!TnU)9>>Y*8@3 zROb#^E^>D9%zHG6r?K)Vo}uPAA7(w+ttUp-f_L3w^9f??@M2P;^grd-d z(CbM7V*TpRpsb9s-PftzXayfA^DIw_3GQPRD!xhDV$I*(S0lu-(Pj=IxTxdj?3Qc` zqH~x5#}4u^F<;Hq04s-;%U@N289om1-G|}|M@v|K7V8mq5x5VyzIbLzG_%P`13c*waoU6!DBE zd7Vk{uhI&kX|#}}@ck*A*JJW5{%|rVXF&6Cuk#bBEI}=6z|#+lsp@8=E7*0fels;?A>QPX{#$)5sGL zBL$(wfvwv%nZ9>iI4ourh$cgNVU8)LTXoU0d*r0SZ%%8ewYzhdO8G-2yr4|ys;dG= zW+snxt%kJtaQ*~wmPqb*u9(4T#^>^kS$KO$N$2!n@m*TYJ@ZOy62(pZuq|V01CtpI zf+@U|BnoX76C*5@cH`6Nqf{pdtWr)!w>>saHWuetlF>zd%lfSBh5$k`^IaouD#G=T zoP5IYRHW%?jG5a~v$O^BA*cc`Xy-94@GQkXP~ARtg#J6tUVf2oHwF#nwxT<(%)sP( zIo`OuJrg3+yIGg-`Mw)F9utMA-WPY%&5kRj#oPUH{J+A9eInux&WDKoE9wldoKAF+ zX@NwYh+YK71^2NrR2^~Y-LH~21!^YgCX*jnKolh~;EV)Bqngf7ln5CcV{bZ4>@Z+3R99AFfheqLz zi})H=_f{lva1Ml)ruQ`06hpI(*C!4*3ElWrBY{;dKu!MTL{k>rQFoW^sfoP?EU`;& z7p`L+4h@0m#07op*#a#Mo4Z|%d?NbM`7YPgQN9QoKf)dC@kJ8})pogORbACbp2t62 z3eDD%i>BCxt^-4D>cY$|{ya)TgEbsa3UMAtlYI9Qnc{fsoZ)8Xq0!N_gv|9n()MOa zW+f1jVY7+(QQj`8FZ|S#1%Adtfp%Zq(sWT_3&oUic+{<9Q^0y>Qm?;&`<~jvkbfJV zhVL7(;{aB|w!rTF(%lJ3rq>~*E_YPF1^JlPtZHxVc>0l~y*uvSzi*V{ky&ZvtZ-y- zKPiu0CMbGN{Ne$GmQ9U9V$;fIW?|B58it{4xtnodc`P-ufx_Y9mh3qZO2u-yQ5}7F zO9;w(!KJMieC352ZMt2P`Me@PH+VVC%l|2i1MSSIAbUQnqf)8Q$cdzCNd82S2$2wY z|7VY9Ub@HK%&|E4S|j8-@9HN+$(ZPArYxD>6o)*Y55KxM3w6Nxc?)L3edR9~?iBj@ zJF$ax?cM>+W^z>9df8=Fj}!(S;v+ZYVv{`*F9estzb9C@MS$!4<$8SMA}sV&EBoow z1kYaeQs=W;rdi0QCVK|nY$;;wDFPw}j5APs>_ixhE|JDP>s_BxGI~>PF=e%XV z5(3f`q=ZxrYxiC`o)uYKU$&}D|J~;DNFwAscfpEtJ!jB zNKGi)$%pnM$zAA_DLdU?)pC`%_ir_AE|WIAb&#(0y=FMoGBxby&j>>!p{ArzScIUI zpWPqjz{2EQLheyy9jpajlhKeVKTiBCoD0dfRX@C%5`fIXP>Z^-@dPfSb#ftOObkh; zc+g~DyTu#tr%eyi{fSp_X8ba=wCLsODHwl##o?7$udZ7N z|k%y9bb8j_|cw@xB<#DaI^M z|1cb!=`7lCTbuGJrv)wjt-q6&1LdsPKjq4dY$g2_2 z@v-Vdse>PB4be` z+mklJ@K%?QWQ+;{-pLowad#ffh2BFO58Rh&vtI|iFEKGYHpTtwctZhkE5f$Ps>0Mq zZwH#}{L0v{i`>dp=bmS7q69b+QeQNlDN&opxgLJGb(^N)x@!A-wo85aNVzWiO=`?x zBKEl{ICbwuaauvDt5ZL_vd0lo{YI^Gt$Q|U->J32nI zZ0R+*!2GeBd&(^1Wh$4qj0(LDKUI?ul`Kv;NU7mKh3CeDAge{#DYJEWJ z4@8rK2&HaE2-Nx#cvA57RK5=rz$LtcKEgEeJNNpXHtwzX;Fj?!k(BsFcKlh5u7Vkt zp)x?ik1pAMNh2yxau{R(le}5g zxN=!Nw|Xl=bX(0M2G1vd zF(IJn@uev)Z`eFPnla-*Ov-91iS;E`m#^;Woe}3d;lmzD)C!jHGlRj+|KRmw|Fb=l zF*dIbbb(y$GQ%`S?}x;(eWmb0R!Jl44Yx64$foMQ5@g*j>ZM^)p}3-$Kg;g1kgcO- z>V&oFqzIbwcH`n(h%ZBD#OCQ{xPZ@((B)0dh?$>anjId96Uc5~AKpaA=q3i?;6ym* zTont4v(o}i{2y61xLh9|9ij(nIrKSn^3o7QQuVFPf*de<{7@!2cRwO#_teJ4QAu=J zT?9PpSGO7aT{AjbrMzDjk!H=VC=$pZBx4bbN~uPxeIVwr{ItOSO6WL3H9~`cIwbJg zFzd+OSlR4A2qz-c@z$nqnvP3g|~ap%qVE!0o$ ze@aaV{@QzPFoOYOcgL|C7*Imk(gX@nTm6g8q?w1qS)PRe% z=ZEJL7RH$qYR=8Z%=6h#3Vn8G?^`#-2Tt@f0$~Dv@4+Q5MK8q4kF*DOg#DKHX)RaX z&PH?i2(u9%~yuVR|vd~bokRqM(I}yJHyk>8-~<{y+^W~cK(~mXKP7-4fHXy zcF(u6c7TdFL5lP0o;%jr?wW}n^?WBTd5c`=ksqNO^%0C5k6ne_gmyMAjUs3n#aS;C zoBvH+$f2R%siY7FHxP*8PSe6PoE;VxF%C9JQdy@_OTL%5(M+=I#;R2jmiRV{4;{0Y zue7;}uieS3(w&HD^=&aj1W^>XNVY%K-+{EBn@Vj0D8*!Ai04~Z9L0M5?pwWT?Rm8Q zUb#C!=DRC1s~3|X#S$dxzmttgg*G&D6b4dkR>^$no5wUj&$ za|^;Gdzc+|2w31mM{a`MgGRrzgi7JHFUpIv?H*5aetjAi( z2}^2D(9c7&IRt0G&3Ab)z*M|-6bywsAKLR`;7b&^`CtFOU_?J$arEd%=N%b-zRX^eF(8b{3Qr zhSPG_lp;_z6yV;=kH>SI7qpCEe28jY$9^J@@#@rPOx1gWEw^)J_%enadJq~mzcY|H zTkC_RgZUsPw*Gy+;Y@jK0=4v6UL}g_(Sq`pyRAPHE&OvpVU zAGzqZ9I8BQ>9m~)r~-pz&Uxe2G)g;)OFNt-yesW}F1OBo>KiSUKLiwz$eYhl-xyM5 z%`E>$CG7F5A4RSCX^Q-h<{YO%t1&%5c{Sjl0COmEJT6>wa>P=rStge6=u|nDD4#b; zo}4CC`G%&oQ}Pd-?DZNx!}SQ?X|pjW3z|x(3xN#qOF0qG$A#1WVbEJN@HaxC68;7M zaTJVv!J?N#>3rI{-t7_2w}jJXa+YI}mhzZOfvsJ#*a|cZN)mi%-dMo#eBANwRyz-G zJ%Np7pTA%cwe@PjdUPI}Ett{B%WQaaP>*h^sj;3M>`&ecYIy4-=F(uTEfL#J{N3vH za?K=gqzh*b0q=TalI5I!!kHOf{~o{dxSDo*;=m1>a@%lEzpvOe$)91W;-*AR!7cAN zc$r|GUY)pe^69u5JNv!IUHK70N+i>a1?y);9Ox5HhjELRta|R4i&t8X!zp&dQ$wlJ z`XGJo=TKCOGL*au{>HfHpsDev=ig> zX4D`z;rjSksvv|mW9XHLp7nsB_<@yuIlJLK`syXZq3W@6YS6X zhRca@3*xhA^%1o}=ic-g=iVC=An$VTCp%lMRKx8(qQ7b-2^MW&yiSZ^^0Sc%X1?j! z)?Ub!lr)vfu5-5rQtwI-9iCrH3f9-=QutHaRAY)LAzP9{Ua4AzesEgZu)=p31Yhij ztSHy&0mQ0jhGOcqWi2cU++FHPPhOk~L=}+jdHYNX`>f12nbZwlO96l`Rzat7NGT8F zkWQabfhPp@HwIqwn8)viHvI_&(Ir@Z*d!(;I#?AUlkg^rsx?CX6JqC#DjJLVu zS#chnOJjNrCb#&9S)$IVL=0Zj1ckUQ)DA$lm*UgRZx0_>2AI*mEgg}+EuBtJx12R% zLC_4}`e)z9E%b=D^xtUyM67i=1cVKz%#dY*rz5dmvsHAArw7rpG>S#J>bLtg&Fc${ z-kQmboG!E~NFR>HBAg$?zSDl`_~UbbKAdkg#2^C4fTp`(cUJhfz1UNSvcfK=EsEN^ z7@Udsb>9`_tFf!}9cOju!4Elf>f0(-q^7MAU2QQEgN`V${B*+Vu2aEeC`yQ}^pw1g}xvpSgQzfP*-3@u$-0RH__!l~C)SlOmi(kk&p z&IstG0E-)dUp5@7R-&AM;o4ax6*}C&8wRUhtQLmirTk?wpE7vUMDDI!*v?L&fg6k| zli*sCjky#PlR@@4Th76`Srf&iWft$|g7zp6|MWaE&0yeVao;+ko8ISyjHll&z|5m0 z@&NFw9?M526EHf>G%5XC7VUy5VS+Th+#{<1=tUoa#aJxe;|cFKa1%LuD8ui}UG?Ur z+zRq3I(sUhfA(8hH|S2jwq4gU??_(VK=%O8)m7|@ zP@7|sV9GX{ewIMeVFTfcb7$Vw6mgKU^ycp z4XPtALO_Sr8m>&sFY0n5bm}&!me)~k-^&>Y-bT}+3Zl97{`uSlAO}(wo#!gkP?b6M zN*yAGd)EG%9#qedk}gpwIfNeRt%(ZR1O{lVZQi31Qt)B3#Q%^@53j29wNb~vYN`@p z>K45i+0?nN@r|92MI;!*o8wikFnIu4b}yZcvH%*zj=7V@)OJCVtxqv zf6D%nxpBY;+H|$xi(4k{Gq6VNn1;G+#=%a)d*$(2+Wx(6IW9QAB5a=Rx2AAV)W(Z_ zMlE!lzrYM$M&glt(l?Oa$DgGobkF=>nVpE$lR0OHgtNU3slMX@RQ2KSm%@stYCKukUtOTBh`K&E>+*~c94Sao+bCpRo80#O{=?-jr-|HQ!GQGD&=c0( z2i2OvN|=5~;yq`2b8IdLnFvCd!zL#nSt&W8G?c7B_e!Apkw9#OT-xj930&y=jh-lqd#=0tMEoC)A`~BsSEOBjbMPBdGLrAE3cYS5#d4lArL11IW-HxT| zZp7iW;TH+#k}SJ<*ff2fobT+qwoE^1KS_ z|B3o4ZZ1hzD`5JIO%o{D|M8@ZKFgiQ?>H0%2IT{UgBvOfZ9O%$CGn!>OYa*hHWq-< z-$1sppD8UHz?6;3D<6|}nsc`vPn*&$p|oQ5f{!s;H88q72IYj=cZs4}SRKQGwSASPh z9CRQA^O)b$kCP63!4WL!^7E6l#~H|M@0NzSOrE5alCBnEQol+Fi;Ve#x75_SUA*CPvJXI;dBEY_IA6B%&0V|MLCG3tDL*cZr@ttR2i z^123j$Ni_NY6+3&*Ui)k%`>y&g%T?`diys?&n{_9lRQ#HfP%ooHg`j=^yy?R+_bMf zr1+yiXsHh2ZYL`* zMBT1&t)nDO=gNss47*mX@ypY|2mL7eFP0iED;34Bw7-%8$+$Kx0~_9K7f~k7h@>WY z$3q{t6hKc1@cP<#lz98+s=xx&Kdv%l4eCewiW2y0tuMhj>O`QML!sfkdb7s3 z&Q7k1AYi1jrfJ%W+> zmuvKxeEMf_wuw7(c{C}(sbQ}4N^TNEGlJO3FD?xOd+ZVd;sXNWO_eBcE(qS%|4%^3 z#ESwG7kYwJbVXX8D62@-P2lN)uIbpMi(cZw*br1ty1f1bfLb3`V8nC5wgjs; z?^ZJjGao5NP2Cm}s+U<4(dCfO^rAxFV&q6@J^4OUQ_<`BMf2FsUI@WfXGs2l_kifS zlB+5t%yrC{`0%Q)ik&xq<;RQukzi}~ti+j#-{q3Gh;#F%OlLsNlG8lquBkmvjzO2z z!7?j)5Yl9fDQC$9&~DG*I3ll&tf}zk*$KUOZ~&w38O6FuopiO=+p$;DhKDnf_+Gm> zTqCXZ$Ov{_8!s422S8!_VSZTx_3EI)miDpWBiM;RmcbWY&9&Fc=D%;Q^o53Kk12y#$T99}3~nZ?N5T(`chD6(4h^ z=dkHxI|{k%PY&$OM#gf1sNTsnhtWjvZ(R)%84Rs&;X3Bj^*Rp2k7spDOiYdA)N!i| zax5w<8T!3m=a*)cd_^ICjE{0Dqh^3n8N}nUT8|$&T5Dy*iyn(~R8OnGy)`X8Qg&ay zdvDjyTQ=(<c`Z04R|G+PaS zuJs1y+FOgkntlIX*&3hwxcV}GrI9n&ftk?-Acq9t>m*8_-1IP(@75SZ-?&r#7?{Oe2cbFXN(*yjl4QCE`uqj-3DcDMOlbX5kwJa0 z%E<}ndb7{lwzvJcpUYyb@L0?eThu_IYXTf#(fp^f9=WvVad%-n_380`=P3cW>Cn?g z0XTHY6b1WWxBrNAPJcGCYdFebg~;csL96XTRRW|r6-(mr`cHP4S3PD8-~3(p36YUd z=}DWVDlVrtC!6f;!n!(l^UFC(cc+GqB}jIxlal(E#W=W;=oJ{g-r&vH z)v;a>A#&49@rJT$>nibvZQW&lM_zk0A*aMSkA3j?eTc`^+uNC_iWlo3lUumes6JM# z%Cvwt<)ng6)wYD`GGPAQ5dc#6F2gfvv+d z-d-h~TSUDSHwb_(m@(q9&4e_jPvQr1LO6XNcR1?5=r?r}ELsT-2K8{c4;E6H?w-jX z%T082mfj!`9CEX=q|gwkNN||9O+0z5x()0)P>CMu#s<@+@Lz68RhxZFTJ^;MLaTji zoOZGp(BNUV!oFB$woN@$|s&dUkseU!C&EAa5c z_#cHNp}54T!-qwUuoF77CDwVC1U}9KQYNJY{qf&rsj*S5;`Az9q-NO(+GP2+8+P6OWqN^tm8i;@f^P*Op1mF+S-k4RFsM6hYoQ1 zWj(G{yJNyN)41gcFx)O>Bi`fG7~sl0qy`O4kv7l0Byq<26JC~OX(o#dl`!nRPvU6} ztRxk3X~jlqc`2vShr=e)s}=Ve9qXC^Nr#Xe(>e$^MHik-e1RMw!c}%q9fPXYkPmLpHhI^Z%taMw(76uKx=H?FB>dU+hNmL--q+BrimM6n zfgh>pzynjAXy#H+bpu!%B2!U^7Z63ib;oc_HXw7jv5H4Uv)5*@1I@Gq*D#$eT+Wf- zJ;&SNARw~GIjNH*V(T~nN9ijkDp;9+${tle<9_+4{rSdXv8ffzLg0FJ+ogO04(W1W|kn0O|DH9e=YDZtMP ze>~ZBv#-8Pu?%%n39YC~$41d1M@P6Lx1sM6gr_)fb?vzw8CpvQC}!K&M{w_7+=@GJ z=IVP5;l9kXGsW?uByQNb?QBz)8?m|K$dvGxT{Mjb4s};2v`E&TX|g7;j?%CShaly= z`cie`pt~4pc5xwa(J$nQxl|e_HYQeC+iKk(kNkA0YmL*$I2Jv(5-ywat%=yg{>a}3 z$m|Zs#Fk8Z`Dt`Vr}>+XOOoM>%Vwcy-ZL{YZYJax!i=du2Ib=x1S|G}nBI)%ltV#Q z0tT+#6vqPWr+?HNlv3feU)st%=QX>9)_l!CC^&zI$^#XGBiojqqN;kvVxtG z)WgczEgTSMMJDt;`OOcrE(xHoi+K;>1E38Fx$zeD_ahw<3==k2dcB*4*Ls{j60P;fG3V!l52ITg6w)fZ2}d<{oYdy!YT_ME z2LvZxk+wHs`oor(Y0VF9%2~;pi%CZfpl>S0V~eE|7KOq`HKnQk^|m*8M?Y+(wx1(R zmr^9B3K4aXYS`|4(_)uIuK!KO;_PwmW5Rm?;rtCfi^y#~{ZUE2NAiZ1eL0Dc;ZCAw z+)NiM!jcpp6v%t{F+c@iHWk) z@c8hFxMWwI+(F~!`I%z}L3-snpr3P?jlEuYpoW@-jE-#vih$Gq0K_*pbsx<973y+) z7nTy)`-H)pWHD5q5kk78&W0GMjC)$!;$qX=rZb!x@jX&x$~e}Z0w9LFoi4!jXNA-N ztF1E0S`}dm^!g{7uByc9FAJ`Pb%f>Yr46R5x2_mou}^x3aMJV2?LW^*T?NuMHGDw@ zpCeL(qAAUsxhzdPF~0=|!?SD`{6Y6pgudB7I&t^>5gg9F}L?BVX*vl=ji+(r8gtu853EvY>o*ey1;nM@ zFr()+S24b`FPzWeSG>rVN;=9^eW|Q~qZoD(3`uiP?jt;;Ju(Dt#(Fd?MSnwOv?QuJ zSO1hebP)4dNei69{awwyPATxlsx$b_#<|N_g{#WmOjo{$%S`CdJl@bauql(fjh)-B z7_dFpl*lU1PE%(&)9{@~wX3S$M0fG<6Y;Uvg)7F-dInJj1D8tRB5PJ;Jgh;=quztN zCb(-U8NYY)bBNSB{HOZh@10D(PzmFa9S=*P^K~uc30@o_PESrPu=XyvCDp5hStzqy znBd4Z4-n;I+0R+iP3vbmEOp-TP~<{)*F2HrS|o^oHoz=SFfr$ODw7M^R+Zq)?vq6P ztc)WQNGyzUf*ig(OT73^TOxu3RSGSPG&nzv>XZVXBn}*X`A{28)WJ9ad;I;tP-TgiIAkhNK6N<(vMY^>g%GGlt?s3p_DZQ8=$(p&uF5yX$zy(IYL^p$f&iuHMDhi_N+>2n=}!ST@&-L_0C8oEHs^rsB-A84jEu*p`Gl=p zThqb%+0Ut0`M;^e(epAPSO%GDzOIzk1`<-yKrV4gEKXzOTv7B*PQ=8xqjtiyIi_Y( zPrH^oyYq-Q)n-x=+fz77*n*EkwHll?>R>VzzQ0)Y1(|FOF($mkTUyw0np*8lcVHD`?uPF{O0F5Y(+xIhOx{_n5a>NTErEdcZA-3mHNZ5S5_xN zdAL#9ZLlLS?DM}P#`mWnrj=qZH*g5Opo%+aA$jks_@{W} zOnX-vB&5DhMJE9&T#ERN0zBA~u2t}O*_Yc(9rxt6SB1%W9xF-`}X*+VKt zCnYzSjXWIM1gnDNo@|bo9Vz*P76c#2V(2H5YVBpNlPCHlAIdd(b370=r7^>;fyR8~ z#a9U&1kkcQjK{@nQ>pJ}v>`0(eF|85JkmPkvutaC9il-ojQXe(his6|6?1`|Spx|k z3HNtCm8J)9)Zy*F!c1>M;rwjMzsX6|Y$1T|(0pbD6+DLV!1oi$uN+i}L*zzSa718K z>llIoru7p9Dz(vd0r)Bp_x5dHkoDeDao$;4b`vz}n zZ&Bie`m*+Zy%cY1H-`BjWo&|p$eB-bl!C>)N}i-co>^)gN|%mY=t5X(0?iC0nH#Qj z1g_tEz~?(c20S!CFj&xOKM%h0rW*bvPYIj?!&bYTZZP27^?PjUcgXu+cEn@n6q z3_A{0#$a5G1rTz-5Oxnfn0%y0C|cLPEaBU`XM}YsqmG9AfiaUlg7(p(lB#(m98c!! zkBg~TA5YO7H;6G5|7F;u?hX+y)+VrLTy(Ep#-+>7!o0uD7sdXIv`I#Qbb0iec|*4( z#-tr!NWf{abKf-~o6%PFw1$w-xi#LoPR}JiK;Hmc*{*_89fj1|#ad06%X@S3bEQ_Xl5l^f*eu6E8_w>sr5jiGt)7fv&R;{+B?>w(A_?4hfpQqR)Uwn?Fu`O3m{5|cw7MdJ)6|f zvITx?BqXUZ@T`-M3?1M1Cq*t}IE>HMs&^K8FxDEcK>LdCc`qa@K}BJ0?%AD9X-{^8 zeWuFn!a5#T_HgX+J{cb4WEhrkk_}=?I+DVqhTgO8My!P7s`7It@Th%;i>fO5$=Xul zwvZkA>-;i?E4IqHahb>xNKRsOh)E{95%os-!GFIT|AS?g7E082AB#p=V*;q;(s=K0 z>?BW0O4~z_cZjkz8NGc^h!2(LrZ2v~-!w&+phc7gk(ss12;fK=}yi4atamT%(hL|A!H z{CPb1IqeVaMK>Gq!7;^f_V6=*?AaXmiGWAJir<^v9L2e_IIo^A;x?_K5uSyb>9FA8 zDyWp5MhQuJtmO?6XF` zQ^4J0%o7Am*@z7b{gcQ}%4?3q+rPA2!-t7doh7jKPL8?cEFrss|7j;hs zcV_=RLSqDZd*~4jNskJQ{G8aQ#`#k;uCxr=zwutf;4Jcq$o{|@Cx|srx_Sv#=o`>`413 z)ck~XsSw$bxzMsPCp4wVF%ig_1yegspobCwE#6+&Ac~niw_NQcWXia=a%f^1L_a=} n86M@9Y2e>M`*&0bY|lHYF~TK}rd*2y1o$N-CNEkgY#8((aTkC3 literal 0 HcmV?d00001 diff --git a/website/docs/dev_deadline.md b/website/docs/dev_deadline.md new file mode 100644 index 0000000000..310b2e0983 --- /dev/null +++ b/website/docs/dev_deadline.md @@ -0,0 +1,38 @@ +--- +id: dev_deadline +title: Deadline integration +sidebar_label: Deadline integration +toc_max_heading_level: 4 +--- + +Deadline is not host as usual, it is missing most of the host features, but it does have +its own set of publishing plugins. + +## How to test OpenPype on Deadline + +### Versions + +Since 3.14 job submitted from OpenPype is bound to OpenPype version used to submit it. So +if you submit job with 3.14.8, Deadline will try to find that particular version and use it +for rendering. This is handled by `OPENPYPE_VERSION` variable on job - you can delete it from +there and then the version set in studio Settings will be used. + +![Deadline Job Version](assets/deadline_job_version.png) + +Deadline needs to bootstrap this version so it will try to look the closest compatible +build. So to use version 3.14.8 on Deadline it is enough to have build 3.14.0 or similar - important +are the first two version numbers - major and minor. If they match, the version +is considered compatible. + +### Testing + +So to test various changes you don't need to build again an again OpenPype and putting +it to directory where Deadline is looking for versions - this needs to be done only on +minor version change. That build will then be used to bootstrap whatever is set on the +job or in the studio Settings. + +So you can either use zip version if it suits you, or better set your sources directory +so it will be find as a version - for example with symlink. + +That way you can only modify `OPENPYPE_VERSION` variable on job to point it to version +you would like to test. \ No newline at end of file diff --git a/website/sidebars.js b/website/sidebars.js index af64282d61..f2d9ffee06 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -157,6 +157,7 @@ module.exports = { "dev_host_implementation", "dev_publishing" ] - } + }, + "dev_deadline" ] }; From b6b7ac29226f9c6084cad6ad8dba434d50bc96af Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Dec 2022 16:55:47 +0800 Subject: [PATCH 17/46] adding options for creating renderpasses in redshift and vray --- openpype/hosts/maya/api/lib_rendersettings.py | 27 ++- .../schemas/schema_maya_render_settings.json | 192 +++++++++--------- 2 files changed, 119 insertions(+), 100 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 1293f1287d..f9d24c3780 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -150,13 +150,23 @@ class RenderSettings(object): redshift_render_presets = render_settings["redshift_renderer"] remove_aovs = render_settings["remove_aovs"] + all_rs_aovs = cmds.ls(type='RedshiftAOV') if remove_aovs: - aovs = cmds.ls(type='RedshiftAOV') - for aov in aovs: + for aov in all_rs_aovs: enabled = cmds.getAttr("{}.enabled".format(aov)) if enabled: cmds.delete(aov) + redshift_aovs = redshift_render_presets["aov_list"] + for rs_aov in redshift_aovs: + rs_renderlayer = rs_aov.replace(" ", "") + rs_layername = "rsAov_{}".format(rs_renderlayer) + if rs_layername in all_rs_aovs: + continue + cmds.rsCreateAov(type=rs_aov) + # update the AOV list + mel.eval("redshiftUpdateActiveAovList;") + additional_options = redshift_render_presets["additional_options"] ext = redshift_render_presets["image_format"] img_exts = ["iff", "exr", "tif", "png", "tga", "jpg"] @@ -177,19 +187,26 @@ class RenderSettings(object): vray_render_presets = render_settings["vray_renderer"] # vrayRenderElement remove_aovs = render_settings["remove_aovs"] + all_vray_aovs = cmds.ls(type='VRayRenderElement') + lightSelect_aovs = cmds.ls(type='VRayRenderElementSet') if remove_aovs: - aovs = cmds.ls(type='VRayRenderElement') - for aov in aovs: + for aov in all_vray_aovs: # remove all aovs except LightSelect enabled = cmds.getAttr("{}.enabled".format(aov)) if enabled: cmds.delete(aov) # remove LightSelect - lightSelect_aovs = cmds.ls(type='VRayRenderElementSet') for light_aovs in lightSelect_aovs: light_enabled = cmds.getAttr("{}.enabled".format(light_aovs)) if light_enabled: cmds.delete(lightSelect_aovs) + + vray_aovs = vray_render_presets["aov_list"] + for renderlayer in vray_aovs: + renderElement = "vrayAddRenderElement {}".format(renderlayer) + RE_name = mel.eval(renderElement) + if RE_name.endswith("1"): # if there is more than one same render element + cmds.delete(RE_name) # Set aov separator # First we need to explicitly set the UI items in Render Settings # because that is also what V-Ray updates to when that Render Settings diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json index c1bafc4108..512e45f674 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json @@ -209,74 +209,76 @@ "defaults": "empty", "enum_items": [ {"empty": "< empty >"}, - {"atmosphereChannel": "atmosphere"}, - {"backgroundChannel": "background"}, - {"bumpNormalsChannel": "bumpnormals"}, - {"causticsChannel": "caustics"}, - {"coatFilterChannel": "coat_filter"}, - {"coatGlossinessChannel": "coatGloss"}, - {"coatReflectionChannel": "coat_reflection"}, - {"vrayCoatChannel": "coat_specular"}, - {"CoverageChannel": "coverage"}, - {"cryptomatteChannel": "cryptomatte"}, - {"customColor": "custom_color"}, - {"drBucketChannel": "DR"}, - {"denoiserChannel": "denoiser"}, - {"diffuseChannel": "diffuse"}, - {"ExtraTexElement": "extraTex"}, - {"giChannel": "GI"}, - {"LightMixElement": "None"}, - {"lightingChannel": "lighting"}, - {"LightingAnalysisChannel": "LightingAnalysis"}, - {"materialIDChannel": "materialID"}, - {"MaterialSelectElement": "materialSelect"}, - {"matteShadowChannel": "matteShadow"}, - {"MultiMatteElement": "multimatte"}, - {"multimatteIDChannel": "multimatteID"}, - {"normalsChannel": "normals"}, - {"nodeIDChannel": "objectId"}, - {"objectSelectChannel": "objectSelect"}, - {"rawCoatFilterChannel": "raw_coat_filter"}, - {"rawCoatReflectionChannel": "raw_coat_reflection"}, - {"rawDiffuseFilterChannel": "rawDiffuseFilter"}, - {"rawGiChannel": "rawGI"}, - {"rawLightChannel": "rawLight"}, - {"rawReflectionChannel": "rawReflection"}, - {"rawReflectionFilterChannel": "rawReflectionFilter"}, - {"rawRefractionChannel": "rawRefraction"}, - {"rawRefractionFilterChannel": "rawRefractionFilter"}, - {"rawShadowChannel": "rawShadow"}, - {"rawSheenFilterChannel": "raw_sheen_filter"}, - {"rawSheenReflectionChannel": "raw_sheen_reflection"}, - {"rawTotalLightChannel": "rawTotalLight"}, - {"reflectIORChannel": "reflIOR"}, - {"reflectChannel": "reflect"}, - {"reflectionFilterChannel": "reflectionFilter"}, - {"reflectGlossinessChannel": "reflGloss"}, - {"refractChannel": "refract"}, - {"refractionFilterChannel": "refractionFilter"}, - {"refractGlossinessChannel": "refrGloss"}, - {"renderIDChannel": "renderId"}, - {"FastSSS2Channel": "SSS"}, - {"sampleRateChannel": "sampleRate"}, + {"atmosphereChannel": "atmosphereChannel"}, + {"backgroundChannel": "backgroundChannel"}, + {"bumpNormalsChannel": "bumpNormalsChannel"}, + {"causticsChannel": "causticsChannel"}, + {"coatFilterChannel": "coatFilterChannel"}, + {"coatGlossinessChannel": "coatGlossinessChannel"}, + {"coatReflectionChannel": "coatReflectionChannel"}, + {"vrayCoatChannel": "vrayCoatChannel"}, + {"CoverageChannel": "CoverageChannel"}, + {"cryptomatteChannel": "cryptomatteChannel"}, + {"customColor": "customColor"}, + {"drBucketChannel": "drBucketChannel"}, + {"denoiserChannel": "denoiserChannel"}, + {"diffuseChannel": "diffuseChannel"}, + {"ExtraTexElement": "ExtraTexElement"}, + {"giChannel": "giChannel"}, + {"LightMixElement": "LightMixElement"}, + {"LightSelectElement": "LightSelectElement"}, + {"lightingChannel": "lightingChannel"}, + {"LightingAnalysisChannel": "LightingAnalysisChannel"}, + {"materialIDChannel": "materialIDChannel"}, + {"MaterialSelectElement": "MaterialSelectElement"}, + {"matteShadowChannel": "matteShadowChannel"}, + {"metalnessChannel": "metalnessChannel"}, + {"MultiMatteElement": "MultiMatteElement"}, + {"multimatteIDChannel": "multimatteIDChannel"}, + {"noiseLevelChannel": "noiseLevelChannel"}, + {"normalsChannel": "normalsChannel"}, + {"nodeIDChannel": "nodeIDChannel"}, + {"objectSelectChannel": "objectSelectChannel"}, + {"rawCoatFilterChannel": "rawCoatFilterChannel"}, + {"rawCoatReflectionChannel": "rawCoatReflectionChannel"}, + {"rawDiffuseFilterChannel": "rawDiffuseFilterChannel"}, + {"rawGiChannel": "rawGiChannel"}, + {"rawLightChannel": "rawLightChannel"}, + {"rawReflectionChannel": "rawReflectionChannel"}, + {"rawReflectionFilterChannel": "rawReflectionFilterChannel"}, + {"rawRefractionChannel": "rawRefractionChannel"}, + {"rawRefractionFilterChannel": "rawRefractionFilterChannel"}, + {"rawShadowChannel": "rawShadowChannel"}, + {"rawSheenFilterChannel": "rawSheenFilterChannel"}, + {"rawSheenReflectionChannel": "rawSheenReflectionChannel"}, + {"rawTotalLightChannel": "rawTotalLightChannel"}, + {"reflectIORChannel": "reflectIORChannel"}, + {"reflectChannel": "reflectChannel"}, + {"reflectionFilterChannel": "reflectionFilterChannel"}, + {"reflectGlossinessChannel": "reflectGlossinessChannel"}, + {"refractChannel": "refractChannel"}, + {"refractionFilterChannel": "refractionFilterChannel"}, + {"refractGlossinessChannel": "refractGlossinessChannel"}, + {"renderIDChannel": "renderIDChannel"}, + {"FastSSS2Channel": "FastSSS2Channel"}, + {"sampleRateChannel": "sampleRateChannel"}, {"samplerInfo": "samplerInfo"}, - {"selfIllumChannel": "selfIllum"}, - {"shadowChannel": "shadow"}, - {"sheenFilterChannel": "sheen_filter"}, - {"sheenGlossinessChannel": "sheenGloss"}, - {"sheenReflectionChannel": "sheen_reflection"}, - {"vraySheenChannel": "sheen_specular"}, - {"specularChannel": "specular"}, + {"selfIllumChannel": "selfIllumChannel"}, + {"shadowChannel": "shadowChannel"}, + {"sheenFilterChannel": "sheenFilterChannel"}, + {"sheenGlossinessChannel": "sheenGlossinessChannel"}, + {"sheenReflectionChannel": "sheenReflectionChannel"}, + {"vraySheenChannel": "vraySheenChannel"}, + {"specularChannel": "specularChannel"}, {"Toon": "Toon"}, - {"toonLightingChannel": "toonLighting"}, - {"toonSpecularChannel": "toonSpecular"}, - {"totalLightChannel": "totalLight"}, - {"unclampedColorChannel": "unclampedColor"}, - {"VRScansPaintMaskChannel": "VRScansPaintMask"}, - {"VRScansZoneMaskChannel": "VRScansZoneMask"}, - {"velocityChannel": "velocity"}, - {"zdepthChannel": "zDepth"}, - {"LightSelectElement": "lightselect"} + {"toonLightingChannel": "toonLightingChannel"}, + {"toonSpecularChannel": "toonSpecularChannel"}, + {"totalLightChannel": "totalLightChannel"}, + {"unclampedColorChannel": "unclampedColorChannel"}, + {"VRScansPaintMaskChannel": "VRScansPaintMaskChannel"}, + {"VRScansZoneMaskChannel": "VRScansZoneMaskChannel"}, + {"velocityChannel": "velocityChannel"}, + {"zdepthChannel": "zdepthChannel"} ] }, { @@ -366,46 +368,46 @@ "defaults": "empty", "enum_items": [ {"empty": "< none >"}, - {"AO": "Ambient Occlusion"}, + {"Ambient Occlusion": "Ambient Occlusion"}, {"Background": "Background"}, {"Beauty": "Beauty"}, - {"BumpNormals": "Bump Normals"}, + {"Bump Normals": "Bump Normals"}, {"Caustics": "Caustics"}, - {"CausticsRaw": "Caustics Raw"}, + {"Caustics Raw": "Caustics Raw"}, {"Cryptomatte": "Cryptomatte"}, {"Custom": "Custom"}, - {"Z": "Depth"}, - {"DiffuseFilter": "Diffuse Filter"}, - {"DiffuseLighting": "Diffuse Lighting"}, - {"DiffuseLightingRaw": "Diffuse Lighting Raw"}, + {"Depth": "Depth"}, + {"Diffuse Filter": "Diffuse Filter"}, + {"Diffuse Lighting": "Diffuse Lighting"}, + {"Diffuse Lighting Raw": "Diffuse Lighting Raw"}, {"Emission": "Emission"}, - {"GI": "Global Illumination"}, - {"GIRaw": "Global Illumination Raw"}, + {"Global Illumination": "Global Illumination"}, + {"Global Illumination Raw": "Global Illumination Raw"}, {"Matte": "Matte"}, - {"MotionVectors": "Ambient Occlusion"}, - {"N": "Normals"}, - {"ID": "ObjectID"}, - {"ObjectBumpNormal": "Object-Space Bump Normals"}, - {"ObjectPosition": "Object-Space Positions"}, - {"PuzzleMatte": "Puzzle Matte"}, + {"Motion Vectors": "Motion Vectors"}, + {"Normals": "Normals"}, + {"ObjectID": "ObjectID"}, + {"Object-Space Bump Normals": "Object-Space Bump Normals"}, + {"Object-Space Positions": "Object-Space Positions"}, + {"Puzzle Matte": "Puzzle Matte"}, {"Reflections": "Reflections"}, - {"ReflectionsFilter": "Reflections Filter"}, - {"ReflectionsRaw": "Reflections Raw"}, + {"Reflections Filter": "Reflections Filter"}, + {"Reflections Raw": "Reflections Raw"}, {"Refractions": "Refractions"}, - {"RefractionsFilter": "Refractions Filter"}, - {"RefractionsRaw": "Refractions Filter"}, + {"Refractions Filter": "Refractions Filter"}, + {"Refractions Raw": "Refractions Filter"}, {"Shadows": "Shadows"}, {"SpecularLighting": "Specular Lighting"}, - {"SSS": "Sub Surface Scatter"}, - {"SSSRaw": "Sub Surface Scatter Raw"}, - {"TotalDiffuseLightingRaw": "Total Diffuse Lighting Raw"}, - {"TotalTransLightingRaw": "Total Translucency Filter"}, - {"TransTint": "Translucency Filter"}, - {"TransGIRaw": "Translucency Lighting Raw"}, - {"VolumeFogEmission": "Volume Fog Emission"}, - {"VolumeFogTint": "Volume Fog Tint"}, - {"VolumeLighting": "Volume Lighting"}, - {"P": "World Position"} + {"Sub Surface Scatter": "Sub Surface Scatter"}, + {"Sub Surface Scatter Raw": "Sub Surface Scatter Raw"}, + {"Total Diffuse Lighting Raw": "Total Diffuse Lighting Raw"}, + {"Total Translucency Filter": "Total Translucency Filter"}, + {"Translucency Filter": "Translucency Filter"}, + {"Translucency Lighting Raw": "Translucency Lighting Raw"}, + {"Volume Fog Emission": "Volume Fog Emission"}, + {"Volume Fog Tint": "Volume Fog Tint"}, + {"Volume Lighting": "Volume Lighting"}, + {"World Position": "World Position"} ] }, { From 5b7a4c1704bb4114380cc0b99ef00784d22089df Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 7 Dec 2022 15:36:43 +0100 Subject: [PATCH 18/46] settings UI is using 'qtpy' instead of 'Qt' --- openpype/tools/settings/local_settings/apps_widget.py | 2 +- openpype/tools/settings/local_settings/environments_widget.py | 2 +- openpype/tools/settings/local_settings/experimental_widget.py | 2 +- openpype/tools/settings/local_settings/general_widget.py | 2 +- openpype/tools/settings/local_settings/mongo_widget.py | 2 +- openpype/tools/settings/local_settings/projects_widget.py | 2 +- openpype/tools/settings/local_settings/widgets.py | 2 +- openpype/tools/settings/local_settings/window.py | 2 +- openpype/tools/settings/settings/base.py | 2 +- openpype/tools/settings/settings/breadcrumbs_widget.py | 2 +- openpype/tools/settings/settings/categories.py | 2 +- openpype/tools/settings/settings/color_widget.py | 2 +- openpype/tools/settings/settings/constants.py | 2 +- openpype/tools/settings/settings/dialogs.py | 2 +- openpype/tools/settings/settings/dict_conditional.py | 2 +- openpype/tools/settings/settings/dict_mutable_widget.py | 2 +- openpype/tools/settings/settings/images/__init__.py | 2 +- openpype/tools/settings/settings/item_widgets.py | 2 +- openpype/tools/settings/settings/lib.py | 2 +- openpype/tools/settings/settings/list_item_widget.py | 2 +- openpype/tools/settings/settings/list_strict_widget.py | 2 +- openpype/tools/settings/settings/multiselection_combobox.py | 2 +- openpype/tools/settings/settings/search_dialog.py | 2 +- openpype/tools/settings/settings/tests.py | 2 +- openpype/tools/settings/settings/widgets.py | 2 +- openpype/tools/settings/settings/window.py | 2 +- openpype/tools/settings/settings/wrapper_widgets.py | 2 +- 27 files changed, 27 insertions(+), 27 deletions(-) diff --git a/openpype/tools/settings/local_settings/apps_widget.py b/openpype/tools/settings/local_settings/apps_widget.py index c1f350fcbc..ce1fc86c32 100644 --- a/openpype/tools/settings/local_settings/apps_widget.py +++ b/openpype/tools/settings/local_settings/apps_widget.py @@ -1,5 +1,5 @@ import platform -from Qt import QtWidgets +from qtpy import QtWidgets from .widgets import ( Separator, ExpandingWidget diff --git a/openpype/tools/settings/local_settings/environments_widget.py b/openpype/tools/settings/local_settings/environments_widget.py index 14ca517851..5008f086d2 100644 --- a/openpype/tools/settings/local_settings/environments_widget.py +++ b/openpype/tools/settings/local_settings/environments_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from openpype.tools.utils import PlaceholderLineEdit diff --git a/openpype/tools/settings/local_settings/experimental_widget.py b/openpype/tools/settings/local_settings/experimental_widget.py index 22ef952356..b0d9381663 100644 --- a/openpype/tools/settings/local_settings/experimental_widget.py +++ b/openpype/tools/settings/local_settings/experimental_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from openpype.tools.experimental_tools import ( ExperimentalTools, LOCAL_EXPERIMENTAL_KEY diff --git a/openpype/tools/settings/local_settings/general_widget.py b/openpype/tools/settings/local_settings/general_widget.py index 35add7573e..5a75c219dc 100644 --- a/openpype/tools/settings/local_settings/general_widget.py +++ b/openpype/tools/settings/local_settings/general_widget.py @@ -1,6 +1,6 @@ import getpass -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.lib import is_admin_password_required from openpype.widgets import PasswordDialog from openpype.tools.utils import PlaceholderLineEdit diff --git a/openpype/tools/settings/local_settings/mongo_widget.py b/openpype/tools/settings/local_settings/mongo_widget.py index 600ab79242..9549d6eb17 100644 --- a/openpype/tools/settings/local_settings/mongo_widget.py +++ b/openpype/tools/settings/local_settings/mongo_widget.py @@ -2,7 +2,7 @@ import os import sys import traceback -from Qt import QtWidgets +from qtpy import QtWidgets from pymongo.errors import ServerSelectionTimeoutError from openpype.lib import change_openpype_mongo_url diff --git a/openpype/tools/settings/local_settings/projects_widget.py b/openpype/tools/settings/local_settings/projects_widget.py index 30a0d212f0..b330d54dec 100644 --- a/openpype/tools/settings/local_settings/projects_widget.py +++ b/openpype/tools/settings/local_settings/projects_widget.py @@ -1,6 +1,6 @@ import platform import copy -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.settings.settings import ProjectListWidget from openpype.tools.utils import PlaceholderLineEdit from openpype.settings.constants import ( diff --git a/openpype/tools/settings/local_settings/widgets.py b/openpype/tools/settings/local_settings/widgets.py index 2733aef187..f40978a66f 100644 --- a/openpype/tools/settings/local_settings/widgets.py +++ b/openpype/tools/settings/local_settings/widgets.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.settings.settings.widgets import ( ExpandingWidget ) diff --git a/openpype/tools/settings/local_settings/window.py b/openpype/tools/settings/local_settings/window.py index 76c2d851e9..fdb05e219f 100644 --- a/openpype/tools/settings/local_settings/window.py +++ b/openpype/tools/settings/local_settings/window.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtGui +from qtpy import QtWidgets, QtGui from openpype import style diff --git a/openpype/tools/settings/settings/base.py b/openpype/tools/settings/settings/base.py index 6def284a83..074ecdae90 100644 --- a/openpype/tools/settings/settings/base.py +++ b/openpype/tools/settings/settings/base.py @@ -5,7 +5,7 @@ import traceback import functools import datetime -from Qt import QtWidgets, QtGui, QtCore +from qtpy import QtWidgets, QtGui, QtCore from openpype.settings.entities import ProjectSettings from openpype.tools.settings import CHILD_OFFSET diff --git a/openpype/tools/settings/settings/breadcrumbs_widget.py b/openpype/tools/settings/settings/breadcrumbs_widget.py index 7524bc61f0..2676d2f52d 100644 --- a/openpype/tools/settings/settings/breadcrumbs_widget.py +++ b/openpype/tools/settings/settings/breadcrumbs_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtGui, QtCore +from qtpy import QtWidgets, QtGui, QtCore PREFIX_ROLE = QtCore.Qt.UserRole + 1 LAST_SEGMENT_ROLE = QtCore.Qt.UserRole + 2 diff --git a/openpype/tools/settings/settings/categories.py b/openpype/tools/settings/settings/categories.py index e1b3943317..2e5ce496ed 100644 --- a/openpype/tools/settings/settings/categories.py +++ b/openpype/tools/settings/settings/categories.py @@ -2,7 +2,7 @@ import sys import traceback import contextlib from enum import Enum -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore import qtawesome from openpype.lib import get_openpype_version diff --git a/openpype/tools/settings/settings/color_widget.py b/openpype/tools/settings/settings/color_widget.py index b38b46f3cb..819bfb3581 100644 --- a/openpype/tools/settings/settings/color_widget.py +++ b/openpype/tools/settings/settings/color_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from .item_widgets import InputWidget diff --git a/openpype/tools/settings/settings/constants.py b/openpype/tools/settings/settings/constants.py index 23526e4de9..b2792d885b 100644 --- a/openpype/tools/settings/settings/constants.py +++ b/openpype/tools/settings/settings/constants.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore DEFAULT_PROJECT_LABEL = "< Default >" diff --git a/openpype/tools/settings/settings/dialogs.py b/openpype/tools/settings/settings/dialogs.py index b1b4daa1a0..38da3cf881 100644 --- a/openpype/tools/settings/settings/dialogs.py +++ b/openpype/tools/settings/settings/dialogs.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.utils.delegates import pretty_date diff --git a/openpype/tools/settings/settings/dict_conditional.py b/openpype/tools/settings/settings/dict_conditional.py index b2a7bb52a2..564603b258 100644 --- a/openpype/tools/settings/settings/dict_conditional.py +++ b/openpype/tools/settings/settings/dict_conditional.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets +from qtpy import QtWidgets from .widgets import ( ExpandingWidget, diff --git a/openpype/tools/settings/settings/dict_mutable_widget.py b/openpype/tools/settings/settings/dict_mutable_widget.py index 1c704b3cd5..b9932da789 100644 --- a/openpype/tools/settings/settings/dict_mutable_widget.py +++ b/openpype/tools/settings/settings/dict_mutable_widget.py @@ -1,6 +1,6 @@ from uuid import uuid4 -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from .base import BaseWidget from .lib import ( diff --git a/openpype/tools/settings/settings/images/__init__.py b/openpype/tools/settings/settings/images/__init__.py index 3ad65e114a..0b246349a8 100644 --- a/openpype/tools/settings/settings/images/__init__.py +++ b/openpype/tools/settings/settings/images/__init__.py @@ -1,5 +1,5 @@ import os -from Qt import QtGui +from qtpy import QtGui def get_image_path(image_filename): diff --git a/openpype/tools/settings/settings/item_widgets.py b/openpype/tools/settings/settings/item_widgets.py index 1ddee7efbe..d51f9b9684 100644 --- a/openpype/tools/settings/settings/item_widgets.py +++ b/openpype/tools/settings/settings/item_widgets.py @@ -1,6 +1,6 @@ import json -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui from openpype.widgets.sliders import NiceSlider from openpype.tools.settings import CHILD_OFFSET diff --git a/openpype/tools/settings/settings/lib.py b/openpype/tools/settings/settings/lib.py index eef157812f..0bcf8a4e94 100644 --- a/openpype/tools/settings/settings/lib.py +++ b/openpype/tools/settings/settings/lib.py @@ -1,4 +1,4 @@ -from Qt import QtCore +from qtpy import QtCore from .widgets import SettingsToolBtn diff --git a/openpype/tools/settings/settings/list_item_widget.py b/openpype/tools/settings/settings/list_item_widget.py index cd1fd912ae..67ce4b9dc9 100644 --- a/openpype/tools/settings/settings/list_item_widget.py +++ b/openpype/tools/settings/settings/list_item_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from openpype.tools.settings import ( CHILD_OFFSET diff --git a/openpype/tools/settings/settings/list_strict_widget.py b/openpype/tools/settings/settings/list_strict_widget.py index f0a3022a50..b0b78e5732 100644 --- a/openpype/tools/settings/settings/list_strict_widget.py +++ b/openpype/tools/settings/settings/list_strict_widget.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore from .widgets import ( GridLabelWidget, diff --git a/openpype/tools/settings/settings/multiselection_combobox.py b/openpype/tools/settings/settings/multiselection_combobox.py index c2cc2a8fee..4cc81ff56e 100644 --- a/openpype/tools/settings/settings/multiselection_combobox.py +++ b/openpype/tools/settings/settings/multiselection_combobox.py @@ -1,4 +1,4 @@ -from Qt import QtCore, QtGui, QtWidgets +from qtpy import QtCore, QtGui, QtWidgets class ComboItemDelegate(QtWidgets.QStyledItemDelegate): diff --git a/openpype/tools/settings/settings/search_dialog.py b/openpype/tools/settings/settings/search_dialog.py index e6538cfe67..2860e7c943 100644 --- a/openpype/tools/settings/settings/search_dialog.py +++ b/openpype/tools/settings/settings/search_dialog.py @@ -1,7 +1,7 @@ import re import collections -from Qt import QtCore, QtWidgets, QtGui +from qtpy import QtCore, QtWidgets, QtGui ENTITY_LABEL_ROLE = QtCore.Qt.UserRole + 1 ENTITY_PATH_ROLE = QtCore.Qt.UserRole + 2 diff --git a/openpype/tools/settings/settings/tests.py b/openpype/tools/settings/settings/tests.py index fc53e38ad5..772d4618f7 100644 --- a/openpype/tools/settings/settings/tests.py +++ b/openpype/tools/settings/settings/tests.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore def indented_print(data, indent=0): diff --git a/openpype/tools/settings/settings/widgets.py b/openpype/tools/settings/settings/widgets.py index b8ad21e7e4..fd04cb0a23 100644 --- a/openpype/tools/settings/settings/widgets.py +++ b/openpype/tools/settings/settings/widgets.py @@ -1,6 +1,6 @@ import copy import uuid -from Qt import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore, QtGui import qtawesome from openpype.client import get_projects diff --git a/openpype/tools/settings/settings/window.py b/openpype/tools/settings/settings/window.py index 77a2f64dac..f479908f7b 100644 --- a/openpype/tools/settings/settings/window.py +++ b/openpype/tools/settings/settings/window.py @@ -1,4 +1,4 @@ -from Qt import QtWidgets, QtGui, QtCore +from qtpy import QtWidgets, QtGui, QtCore from openpype import style diff --git a/openpype/tools/settings/settings/wrapper_widgets.py b/openpype/tools/settings/settings/wrapper_widgets.py index b14a226912..0b45a9a01b 100644 --- a/openpype/tools/settings/settings/wrapper_widgets.py +++ b/openpype/tools/settings/settings/wrapper_widgets.py @@ -1,5 +1,5 @@ from uuid import uuid4 -from Qt import QtWidgets +from qtpy import QtWidgets from .widgets import ( ExpandingWidget, From dbe5872960fc96ee6ad5a17d8a6c289d6ee6f9ef Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 7 Dec 2022 23:43:23 +0800 Subject: [PATCH 19/46] options for creating renderpasses in redshift and vray --- openpype/hosts/maya/api/lib_rendersettings.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index f9d24c3780..d9b79e3c2f 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -159,13 +159,16 @@ class RenderSettings(object): redshift_aovs = redshift_render_presets["aov_list"] for rs_aov in redshift_aovs: - rs_renderlayer = rs_aov.replace(" ", "") - rs_layername = "rsAov_{}".format(rs_renderlayer) + if " " in rs_aov: + rs_renderlayer = rs_aov.replace(" ", "") + rs_layername = "rsAov_{}".format(rs_renderlayer) + else: + rs_layername = "rsAov_{}".format(rs_aov) if rs_layername in all_rs_aovs: continue cmds.rsCreateAov(type=rs_aov) # update the AOV list - mel.eval("redshiftUpdateActiveAovList;") + mel.eval("redshiftUpdateActiveAovList") additional_options = redshift_render_presets["additional_options"] ext = redshift_render_presets["image_format"] @@ -205,7 +208,8 @@ class RenderSettings(object): for renderlayer in vray_aovs: renderElement = "vrayAddRenderElement {}".format(renderlayer) RE_name = mel.eval(renderElement) - if RE_name.endswith("1"): # if there is more than one same render element + # if there is more than one same render element + if RE_name.endswith("1"): cmds.delete(RE_name) # Set aov separator # First we need to explicitly set the UI items in Render Settings From c0319efd2ace058f682578805bd688b06bcf389d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 8 Dec 2022 12:05:01 +0100 Subject: [PATCH 20/46] change import in settings init --- openpype/tools/settings/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/settings/__init__.py b/openpype/tools/settings/__init__.py index 3e77a8348a..0bc166b437 100644 --- a/openpype/tools/settings/__init__.py +++ b/openpype/tools/settings/__init__.py @@ -1,5 +1,5 @@ import sys -from Qt import QtWidgets, QtGui +from qtpy import QtWidgets, QtGui from openpype import style from .lib import ( From 834edafa472d97f0944b40a87ac44015a9d27007 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 8 Dec 2022 22:20:14 +0100 Subject: [PATCH 21/46] :art: support for unreal engine 5.1 --- openpype/hosts/unreal/api/pipeline.py | 8 +++++++- .../hosts/unreal/hooks/pre_workfile_preparation.py | 1 + .../unreal/plugins/publish/collect_instances.py | 13 ++++++++----- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/unreal/api/pipeline.py b/openpype/hosts/unreal/api/pipeline.py index d396b64072..db5b121d14 100644 --- a/openpype/hosts/unreal/api/pipeline.py +++ b/openpype/hosts/unreal/api/pipeline.py @@ -2,6 +2,7 @@ import os import logging from typing import List +import semver import pyblish.api @@ -21,6 +22,8 @@ import unreal # noqa logger = logging.getLogger("openpype.hosts.unreal") OPENPYPE_CONTAINERS = "OpenPypeContainers" +UNREAL_VERSION = semver.VersionInfo( + *os.getenv("OPENPYPE_UNREAL_VERSION").split(".")) HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.unreal.__file__)) PLUGINS_DIR = os.path.join(HOST_DIR, "plugins") @@ -40,6 +43,7 @@ class UnrealHost(HostBase, ILoadHost): name = "unreal" def install(self): + version = UNREAL_VERSION install() def get_containers(self): @@ -111,7 +115,9 @@ def ls(): """ ar = unreal.AssetRegistryHelpers.get_asset_registry() - openpype_containers = ar.get_assets_by_class("AssetContainer", True) + # UE 5.1 changed how class name is specified + class_name = ["/Script", "AssetContainer"] if UNREAL_VERSION.major == 5 and UNREAL_VERSION.minor > 0 else "AssetContainer" # noqa + openpype_containers = ar.get_assets_by_class(class_name, True) # get_asset_by_class returns AssetData. To get all metadata we need to # load asset. get_tag_values() work only on metadata registered in diff --git a/openpype/hosts/unreal/hooks/pre_workfile_preparation.py b/openpype/hosts/unreal/hooks/pre_workfile_preparation.py index 4ae72593e9..2dc6fb9f42 100644 --- a/openpype/hosts/unreal/hooks/pre_workfile_preparation.py +++ b/openpype/hosts/unreal/hooks/pre_workfile_preparation.py @@ -150,6 +150,7 @@ class UnrealPrelaunchHook(PreLaunchHook): engine_path=Path(engine_path) ) + self.launch_context.env["OPENPYPE_UNREAL_VERSION"] = engine_version # Append project file to launch arguments self.launch_context.launch_args.append( f"\"{project_file.as_posix()}\"") diff --git a/openpype/hosts/unreal/plugins/publish/collect_instances.py b/openpype/hosts/unreal/plugins/publish/collect_instances.py index 2f604cb322..db968330c6 100644 --- a/openpype/hosts/unreal/plugins/publish/collect_instances.py +++ b/openpype/hosts/unreal/plugins/publish/collect_instances.py @@ -3,6 +3,8 @@ import ast import unreal # noqa import pyblish.api +from openpype.hosts.unreal.api.pipeline import UNREAL_VERSION +from openpype.pipeline.publish import KnownPublishError class CollectInstances(pyblish.api.ContextPlugin): @@ -23,8 +25,10 @@ class CollectInstances(pyblish.api.ContextPlugin): def process(self, context): ar = unreal.AssetRegistryHelpers.get_asset_registry() - instance_containers = ar.get_assets_by_class( - "OpenPypePublishInstance", True) + class_name = ["/Script", + "AssetContainer"] if UNREAL_VERSION.major == 5 and \ + UNREAL_VERSION.minor > 0 else "OpenPypePublishInstance" # noqa + instance_containers = ar.get_assets_by_class(class_name, True) for container_data in instance_containers: asset = container_data.get_asset() @@ -32,9 +36,8 @@ class CollectInstances(pyblish.api.ContextPlugin): data["objectName"] = container_data.asset_name # convert to strings data = {str(key): str(value) for (key, value) in data.items()} - assert data.get("family"), ( - "instance has no family" - ) + if not data.get("family"): + raise KnownPublishError("instance has no family") # content of container members = ast.literal_eval(data.get("members")) From 151bb60679da425784d74b4e1fd9f5f6c47dee18 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Thu, 8 Dec 2022 22:25:47 +0100 Subject: [PATCH 22/46] :rotating_light: fix Hound --- openpype/hosts/unreal/api/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/unreal/api/pipeline.py b/openpype/hosts/unreal/api/pipeline.py index db5b121d14..839465881d 100644 --- a/openpype/hosts/unreal/api/pipeline.py +++ b/openpype/hosts/unreal/api/pipeline.py @@ -23,7 +23,8 @@ import unreal # noqa logger = logging.getLogger("openpype.hosts.unreal") OPENPYPE_CONTAINERS = "OpenPypeContainers" UNREAL_VERSION = semver.VersionInfo( - *os.getenv("OPENPYPE_UNREAL_VERSION").split(".")) + *os.getenv("OPENPYPE_UNREAL_VERSION").split(".") +) HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.unreal.__file__)) PLUGINS_DIR = os.path.join(HOST_DIR, "plugins") @@ -43,7 +44,6 @@ class UnrealHost(HostBase, ILoadHost): name = "unreal" def install(self): - version = UNREAL_VERSION install() def get_containers(self): From f51325543a1965f63e5dd70980227311b735c962 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 9 Dec 2022 11:32:54 +0100 Subject: [PATCH 23/46] change default command for headless mode --- openpype/cli.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openpype/cli.py b/openpype/cli.py index d24cd4a872..7611915d84 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -29,8 +29,14 @@ def main(ctx): It wraps different commands together. """ + if ctx.invoked_subcommand is None: - ctx.invoke(tray) + # Default command for headless openpype is 'interactive' command + # otherwise 'tray' is used. + if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1": + ctx.invoke(interactive) + else: + ctx.invoke(tray) @main.command() From 1338b1372c008de526a0fda97a826adfb313c3b4 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 9 Dec 2022 13:00:29 +0100 Subject: [PATCH 24/46] :bug: fix the path --- openpype/hosts/unreal/api/pipeline.py | 2 +- openpype/hosts/unreal/plugins/publish/collect_instances.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/unreal/api/pipeline.py b/openpype/hosts/unreal/api/pipeline.py index 839465881d..ca5a42cd82 100644 --- a/openpype/hosts/unreal/api/pipeline.py +++ b/openpype/hosts/unreal/api/pipeline.py @@ -116,7 +116,7 @@ def ls(): """ ar = unreal.AssetRegistryHelpers.get_asset_registry() # UE 5.1 changed how class name is specified - class_name = ["/Script", "AssetContainer"] if UNREAL_VERSION.major == 5 and UNREAL_VERSION.minor > 0 else "AssetContainer" # noqa + class_name = ["/Script/OpenPype", "AssetContainer"] if UNREAL_VERSION.major == 5 and UNREAL_VERSION.minor > 0 else "AssetContainer" # noqa openpype_containers = ar.get_assets_by_class(class_name, True) # get_asset_by_class returns AssetData. To get all metadata we need to diff --git a/openpype/hosts/unreal/plugins/publish/collect_instances.py b/openpype/hosts/unreal/plugins/publish/collect_instances.py index db968330c6..1f25cbde7d 100644 --- a/openpype/hosts/unreal/plugins/publish/collect_instances.py +++ b/openpype/hosts/unreal/plugins/publish/collect_instances.py @@ -25,7 +25,7 @@ class CollectInstances(pyblish.api.ContextPlugin): def process(self, context): ar = unreal.AssetRegistryHelpers.get_asset_registry() - class_name = ["/Script", + class_name = ["/Script/OpenPype", "AssetContainer"] if UNREAL_VERSION.major == 5 and \ UNREAL_VERSION.minor > 0 else "OpenPypePublishInstance" # noqa instance_containers = ar.get_assets_by_class(class_name, True) From ef9f338fb15b666db999daaa8f4341371591b3a2 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Fri, 9 Dec 2022 13:23:33 +0100 Subject: [PATCH 25/46] :bug: remove unnecessary header --- .../UE_5.0/Source/OpenPype/Public/OpenPypePublishInstance.h | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/OpenPypePublishInstance.h b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/OpenPypePublishInstance.h index 2f066bd94b..e9d94aecfc 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/OpenPypePublishInstance.h +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/OpenPypePublishInstance.h @@ -1,6 +1,5 @@ #pragma once -#include "EditorTutorial.h" #include "Engine.h" #include "OpenPypePublishInstance.generated.h" From 3acbd9bd0cc00811e10f8b48e1da60a129b2109c Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sat, 10 Dec 2022 09:20:53 +0000 Subject: [PATCH 26/46] Prevent warning about already connected time attribute --- openpype/hosts/maya/api/plugin.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 66b525bad1..fe30001a96 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -273,7 +273,12 @@ class ReferenceLoader(Loader): if alembic_nodes: for attr, data in alembic_data.items(): node_attr = "{}.{}".format(alembic_nodes[0], attr) - if data["input"]: + + # Prevent warning about connecting to the time attribute + # cause Maya connects to this attribute by default. + if attr == "time": + continue + elif data["input"]: cmds.connectAttr( data["input"], node_attr, force=True ) From b833025a625ec2720da0822f76b4de24faae457f Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Sat, 10 Dec 2022 09:30:42 +0000 Subject: [PATCH 27/46] Improve readability --- openpype/hosts/maya/api/lib.py | 5 +++++ openpype/hosts/maya/api/plugin.py | 30 +++++++++++------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 2530021eba..04b0ad35f1 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3436,3 +3436,8 @@ def iter_visible_nodes_in_range(nodes, start, end): # If no more nodes to process break the frame iterations.. if not node_dependencies: break + + +def get_attribute_input(attr): + connections = cmds.listConnections(attr, plugs=True, destination=False) + return connections[0] if connections else None diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index fe30001a96..82df85a8be 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -226,11 +226,8 @@ class ReferenceLoader(Loader): if alembic_nodes: for attr in alembic_attrs: node_attr = "{}.{}".format(alembic_nodes[0], attr) - inputs = cmds.listConnections( - node_attr, plugs=True, destination=False - ) data = { - "input": None if inputs is None else inputs[0], + "input": lib.get_attribute_input(node_attr), "value": cmds.getAttr(node_attr) } @@ -271,23 +268,18 @@ class ReferenceLoader(Loader): "{}:*".format(namespace), type="AlembicNode" ) if alembic_nodes: + alembic_node = alembic_nodes[0] # assume single AlembicNode for attr, data in alembic_data.items(): - node_attr = "{}.{}".format(alembic_nodes[0], attr) - - # Prevent warning about connecting to the time attribute - # cause Maya connects to this attribute by default. - if attr == "time": - continue - elif data["input"]: - cmds.connectAttr( - data["input"], node_attr, force=True - ) + node_attr = "{}.{}".format(alembic_node, attr) + input = lib.get_attribute_input(node_attr) + if data["input"]: + if data["input"] != input: + cmds.connectAttr( + data["input"], node_attr, force=True + ) else: - inputs = cmds.listConnections( - node_attr, plugs=True, destination=False - ) - if inputs: - cmds.disconnectAttr(inputs[0], node_attr) + if input: + cmds.disconnectAttr(input, node_attr) cmds.setAttr(node_attr, data["value"]) # Fix PLN-40 for older containers created with Avalon that had the From 771d7994dcfbf76bef1547ad1fcdc799e7418697 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 12 Dec 2022 22:05:47 +0800 Subject: [PATCH 28/46] update the redshift render settings --- openpype/hosts/maya/api/lib_rendersettings.py | 21 +++++++++++++++++++ .../schemas/schema_maya_render_settings.json | 10 ++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index d9b79e3c2f..5161141ef9 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -95,6 +95,7 @@ class RenderSettings(object): if renderer == "redshift": self._set_redshift_settings(width, height) + mel.eval("redshiftUpdateActiveAovList") def _set_arnold_settings(self, width, height): """Sets settings for Arnold.""" @@ -158,7 +159,10 @@ class RenderSettings(object): cmds.delete(aov) redshift_aovs = redshift_render_presets["aov_list"] + # list all the aovs + all_rs_aovs = cmds.ls(type='RedshiftAOV') for rs_aov in redshift_aovs: + rs_layername = rs_aov if " " in rs_aov: rs_renderlayer = rs_aov.replace(" ", "") rs_layername = "rsAov_{}".format(rs_renderlayer) @@ -170,6 +174,23 @@ class RenderSettings(object): # update the AOV list mel.eval("redshiftUpdateActiveAovList") + rs_p_engine = redshift_render_presets["primary_gi_engine"] + rs_s_engine = redshift_render_presets["secondary_gi_engine"] + + if int(rs_p_engine) or int(rs_s_engine) != 0: + cmds.setAttr("redshiftOptions.GIEnabled", 1) + if int(rs_p_engine) == 0: + # reset the primary GI Engine as default + cmds.setAttr("redshiftOptions.primaryGIEngine", 4) + if int(rs_s_engine) == 0: + # reset the secondary GI Engine as default + cmds.setAttr("redshiftOptions.secondaryGIEngine", 2) + else: + cmds.setAttr("redshiftOptions.GIEnabled", 0) + + cmds.setAttr("redshiftOptions.primaryGIEngine", int(rs_p_engine)) + cmds.setAttr("redshiftOptions.secondaryGIEngine", int(rs_s_engine)) + additional_options = redshift_render_presets["additional_options"] ext = redshift_render_presets["image_format"] img_exts = ["iff", "exr", "tif", "png", "tga", "jpg"] diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json index 512e45f674..e90495891b 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_render_settings.json @@ -317,9 +317,8 @@ "defaults": "0", "enum_items": [ {"0": "None"}, - {"1": "Photon Map"}, - {"2": "Irradiance Cache"}, - {"3": "Brute Force"} + {"3": "Irradiance Cache"}, + {"4": "Brute Force"} ] }, { @@ -330,9 +329,8 @@ "defaults": "0", "enum_items": [ {"0": "None"}, - {"1": "Photon Map"}, - {"2": "Irradiance Cache"}, - {"3": "Brute Force"} + {"2": "Irradiance Point Cloud"}, + {"4": "Brute Force"} ] }, { From b50e60987420762d06435478c8a14706c9c4f969 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 12 Dec 2022 17:37:16 +0100 Subject: [PATCH 29/46] OP-4465 - updated filter_profiles to handle arrays in values key_values might now contain arrays. Useful for filtering on 'families' --- openpype/lib/profiles_filtering.py | 31 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/openpype/lib/profiles_filtering.py b/openpype/lib/profiles_filtering.py index 370703a68b..e030b19716 100644 --- a/openpype/lib/profiles_filtering.py +++ b/openpype/lib/profiles_filtering.py @@ -79,11 +79,11 @@ def fullmatch(regex, string, flags=0): return None -def validate_value_by_regexes(value, in_list): +def validate_value_by_regexes(values, in_list): """Validates in any regex from list match entered value. Args: - value (str): String where regexes is checked. + values (str|list): String where regexes is checked. in_list (list): List with regexes. Returns: @@ -102,17 +102,21 @@ def validate_value_by_regexes(value, in_list): # If value is not set and in list has specific values then resolve value # as not matching. - if not value: + if not values: return -1 + if isinstance(values, str): + values = [values] + regexes = compile_list_of_regexes(in_list) for regex in regexes: - if hasattr(regex, "fullmatch"): - result = regex.fullmatch(value) - else: - result = fullmatch(regex, value) - if result: - return 1 + for value in values: + if hasattr(regex, "fullmatch"): + result = regex.fullmatch(value) + else: + result = fullmatch(regex, value) + if result: + return 1 return -1 @@ -136,7 +140,8 @@ def filter_profiles(profiles_data, key_values, keys_order=None, logger=None): Args: profiles_data (list): Profile definitions as dictionaries. - key_values (dict): Mapping of Key <-> Value. Key is checked if is + key_values (dict): Mapping of Key <-> Value|[Value]. + Key is checked if is available in profile and if Value is matching it's values. keys_order (list, tuple): Order of keys from `key_values` which matters only when multiple profiles have same score. @@ -181,12 +186,12 @@ def filter_profiles(profiles_data, key_values, keys_order=None, logger=None): profile_scores = [] for key in keys_order: - value = key_values[key] - match = validate_value_by_regexes(value, profile.get(key)) + values = key_values[key] + match = validate_value_by_regexes(values, profile.get(key)) if match == -1: profile_value = profile.get(key) or [] logger.debug( - "\"{}\" not found in \"{}\": {}".format(value, key, + "\"{}\" not found in \"{}\": {}".format(values, key, profile_value) ) profile_points = -1 From 3296ac68ef1a2469ce68651fe4e6f8c8b4c71ba3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 12 Dec 2022 17:41:51 +0100 Subject: [PATCH 30/46] OP-4465 - extract burnin is triggered by profiles in Settings Cleaned up obsolete methods --- openpype/plugins/publish/extract_burnin.py | 233 +++------------------ 1 file changed, 28 insertions(+), 205 deletions(-) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index fd8dfdece9..eab7652ae2 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -1,5 +1,4 @@ import os -import re import json import copy import tempfile @@ -21,6 +20,7 @@ from openpype.lib import ( CREATE_NO_WINDOW ) +from openpype.lib.profiles_filtering import filter_profiles class ExtractBurnin(publish.Extractor): @@ -34,25 +34,7 @@ class ExtractBurnin(publish.Extractor): label = "Extract burnins" order = pyblish.api.ExtractorOrder + 0.03 - families = ["review", "burnin"] - hosts = [ - "nuke", - "maya", - "shell", - "hiero", - "premiere", - "traypublisher", - "standalonepublisher", - "harmony", - "fusion", - "aftereffects", - "tvpaint", - "webpublisher", - "aftereffects", - "photoshop", - "flame" - # "resolve" - ] + optional = True positions = [ @@ -69,11 +51,15 @@ class ExtractBurnin(publish.Extractor): "y_offset": 5 } - # Preset attributes + # Configurable by Settings profiles = None options = None def process(self, instance): + if not self.profiles: + self.log.warning("No profiles present for create burnin") + return + # QUESTION what is this for and should we raise an exception? if "representations" not in instance.data: raise RuntimeError("Burnin needs already created mov to work on.") @@ -137,18 +123,29 @@ class ExtractBurnin(publish.Extractor): return filtered_repres def main_process(self, instance): - # TODO get these data from context - host_name = instance.context.data["hostName"] - task_name = os.environ["AVALON_TASK"] - family = self.main_family_from_instance(instance) + host_name = instance.data["anatomyData"]["app"] + families = list(set(instance.data["family"]).union( + set(instance.data["families"]))) + task_data = instance.data["anatomyData"].get("task", {}) + task_name = task_data.get("name") + task_type = task_data.get("type") + subset = instance.data["subset"] + + filtering_criteria = { + "hosts": host_name, + "families": families, + "task_names": task_name, + "task_types": task_type, + "subset": subset + } + profile = filter_profiles(self.profiles, filtering_criteria, + logger=self.log) - # Find profile most matching current host, task and instance family - profile = self.find_matching_profile(host_name, task_name, family) if not profile: self.log.info(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Family: \"{}\" | Task \"{}\"" - ).format(host_name, family, task_name)) + " Host: \"{}\" | Families: \"{}\" | Task \"{}\" | Task type \"{}\" | Subset \"{}\" " + ).format(host_name, families, task_name, task_type, subset)) return self.log.debug("profile: {}".format(profile)) @@ -158,8 +155,8 @@ class ExtractBurnin(publish.Extractor): if not burnin_defs: self.log.info(( "Skipped instance. Burnin definitions are not set for profile" - " Host: \"{}\" | Family: \"{}\" | Task \"{}\" | Profile \"{}\"" - ).format(host_name, family, task_name, profile)) + " Host: \"{}\" | Families: \"{}\" | Task \"{}\" | Profile \"{}\"" + ).format(host_name, families, task_name, profile)) return burnin_options = self._get_burnin_options() @@ -693,130 +690,6 @@ class ExtractBurnin(publish.Extractor): ) }) - def find_matching_profile(self, host_name, task_name, family): - """ Filter profiles by Host name, Task name and main Family. - - Filtering keys are "hosts" (list), "tasks" (list), "families" (list). - If key is not find or is empty than it's expected to match. - - Args: - profiles (list): Profiles definition from presets. - host_name (str): Current running host name. - task_name (str): Current context task name. - family (str): Main family of current Instance. - - Returns: - dict/None: Return most matching profile or None if none of profiles - match at least one criteria. - """ - - matching_profiles = None - highest_points = -1 - for profile in self.profiles or tuple(): - profile_points = 0 - profile_value = [] - - # Host filtering - host_names = profile.get("hosts") - match = self.validate_value_by_regexes(host_name, host_names) - if match == -1: - continue - profile_points += match - profile_value.append(bool(match)) - - # Task filtering - task_names = profile.get("tasks") - match = self.validate_value_by_regexes(task_name, task_names) - if match == -1: - continue - profile_points += match - profile_value.append(bool(match)) - - # Family filtering - families = profile.get("families") - match = self.validate_value_by_regexes(family, families) - if match == -1: - continue - profile_points += match - profile_value.append(bool(match)) - - if profile_points > highest_points: - matching_profiles = [] - highest_points = profile_points - - if profile_points == highest_points: - profile["__value__"] = profile_value - matching_profiles.append(profile) - - if not matching_profiles: - return - - if len(matching_profiles) == 1: - return matching_profiles[0] - - return self.profile_exclusion(matching_profiles) - - def profile_exclusion(self, matching_profiles): - """Find out most matching profile by host, task and family match. - - Profiles are selectivelly filtered. Each profile should have - "__value__" key with list of booleans. Each boolean represents - existence of filter for specific key (host, taks, family). - Profiles are looped in sequence. In each sequence are split into - true_list and false_list. For next sequence loop are used profiles in - true_list if there are any profiles else false_list is used. - - Filtering ends when only one profile left in true_list. Or when all - existence booleans loops passed, in that case first profile from left - profiles is returned. - - Args: - matching_profiles (list): Profiles with same values. - - Returns: - dict: Most matching profile. - """ - self.log.info( - "Search for first most matching profile in match order:" - " Host name -> Task name -> Family." - ) - # Filter all profiles with highest points value. First filter profiles - # with matching host if there are any then filter profiles by task - # name if there are any and lastly filter by family. Else use first in - # list. - idx = 0 - final_profile = None - while True: - profiles_true = [] - profiles_false = [] - for profile in matching_profiles: - value = profile["__value__"] - # Just use first profile when idx is greater than values. - if not idx < len(value): - final_profile = profile - break - - if value[idx]: - profiles_true.append(profile) - else: - profiles_false.append(profile) - - if final_profile is not None: - break - - if profiles_true: - matching_profiles = profiles_true - else: - matching_profiles = profiles_false - - if len(matching_profiles) == 1: - final_profile = matching_profiles[0] - break - idx += 1 - - final_profile.pop("__value__") - return final_profile - def filter_burnins_defs(self, profile, instance): """Filter outputs by their values from settings. @@ -909,56 +782,6 @@ class ExtractBurnin(publish.Extractor): return True return False - def compile_list_of_regexes(self, in_list): - """Convert strings in entered list to compiled regex objects.""" - regexes = [] - if not in_list: - return regexes - - for item in in_list: - if not item: - continue - - try: - regexes.append(re.compile(item)) - except TypeError: - self.log.warning(( - "Invalid type \"{}\" value \"{}\"." - " Expected string based object. Skipping." - ).format(str(type(item)), str(item))) - - return regexes - - def validate_value_by_regexes(self, value, in_list): - """Validate in any regexe from list match entered value. - - Args: - in_list (list): List with regexes. - value (str): String where regexes is checked. - - Returns: - int: Returns `0` when list is not set or is empty. Returns `1` when - any regex match value and returns `-1` when none of regexes - match value entered. - """ - if not in_list: - return 0 - - output = -1 - regexes = self.compile_list_of_regexes(in_list) - for regex in regexes: - if re.match(regex, value): - output = 1 - break - return output - - def main_family_from_instance(self, instance): - """Return main family of entered instance.""" - family = instance.data.get("family") - if not family: - family = instance.data["families"][0] - return family - def families_from_instance(self, instance): """Return all families of entered instance.""" families = [] From e82f831c5abbccd3fbe98b4483f68f3c105866d3 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 12 Dec 2022 18:13:21 +0100 Subject: [PATCH 31/46] Revert "OP-4465 - updated filter_profiles to handle arrays in values" This reverts commit b50e60987420762d06435478c8a14706c9c4f969. --- openpype/lib/profiles_filtering.py | 31 +++++++++++++----------------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/openpype/lib/profiles_filtering.py b/openpype/lib/profiles_filtering.py index e030b19716..370703a68b 100644 --- a/openpype/lib/profiles_filtering.py +++ b/openpype/lib/profiles_filtering.py @@ -79,11 +79,11 @@ def fullmatch(regex, string, flags=0): return None -def validate_value_by_regexes(values, in_list): +def validate_value_by_regexes(value, in_list): """Validates in any regex from list match entered value. Args: - values (str|list): String where regexes is checked. + value (str): String where regexes is checked. in_list (list): List with regexes. Returns: @@ -102,21 +102,17 @@ def validate_value_by_regexes(values, in_list): # If value is not set and in list has specific values then resolve value # as not matching. - if not values: + if not value: return -1 - if isinstance(values, str): - values = [values] - regexes = compile_list_of_regexes(in_list) for regex in regexes: - for value in values: - if hasattr(regex, "fullmatch"): - result = regex.fullmatch(value) - else: - result = fullmatch(regex, value) - if result: - return 1 + if hasattr(regex, "fullmatch"): + result = regex.fullmatch(value) + else: + result = fullmatch(regex, value) + if result: + return 1 return -1 @@ -140,8 +136,7 @@ def filter_profiles(profiles_data, key_values, keys_order=None, logger=None): Args: profiles_data (list): Profile definitions as dictionaries. - key_values (dict): Mapping of Key <-> Value|[Value]. - Key is checked if is + key_values (dict): Mapping of Key <-> Value. Key is checked if is available in profile and if Value is matching it's values. keys_order (list, tuple): Order of keys from `key_values` which matters only when multiple profiles have same score. @@ -186,12 +181,12 @@ def filter_profiles(profiles_data, key_values, keys_order=None, logger=None): profile_scores = [] for key in keys_order: - values = key_values[key] - match = validate_value_by_regexes(values, profile.get(key)) + value = key_values[key] + match = validate_value_by_regexes(value, profile.get(key)) if match == -1: profile_value = profile.get(key) or [] logger.debug( - "\"{}\" not found in \"{}\": {}".format(values, key, + "\"{}\" not found in \"{}\": {}".format(value, key, profile_value) ) profile_points = -1 From a91ae985fbf481560bd9fc28eb78edf020250bff Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Mon, 12 Dec 2022 18:15:05 +0100 Subject: [PATCH 32/46] Removed unused import --- openpype/tools/settings/settings/dict_mutable_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/settings/settings/dict_mutable_widget.py b/openpype/tools/settings/settings/dict_mutable_widget.py index b9932da789..27c9392320 100644 --- a/openpype/tools/settings/settings/dict_mutable_widget.py +++ b/openpype/tools/settings/settings/dict_mutable_widget.py @@ -1,6 +1,6 @@ from uuid import uuid4 -from qtpy import QtWidgets, QtCore, QtGui +from qtpy import QtWidgets, QtCore from .base import BaseWidget from .lib import ( From 0ee65517f4e34cdbda225f9c472f129375f43cc4 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 12 Dec 2022 18:26:54 +0100 Subject: [PATCH 33/46] OP-4465 - revert wrong defaults Values here were copied from Pyblish filtering, should not be used for profiles. --- openpype/settings/defaults/project_settings/global.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/settings/defaults/project_settings/global.json b/openpype/settings/defaults/project_settings/global.json index 89d7cf08b7..8c56500646 100644 --- a/openpype/settings/defaults/project_settings/global.json +++ b/openpype/settings/defaults/project_settings/global.json @@ -209,6 +209,9 @@ { "families": [], "hosts": [], + "task_types": [], + "task_names": [], + "subsets": [], "burnins": { "burnin": { "TOP_LEFT": "{yy}-{mm}-{dd}", From ec3e04699877d08b070ed4cfb1fbd0fda3d2a2b5 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Mon, 12 Dec 2022 18:30:55 +0100 Subject: [PATCH 34/46] OP-4465 - revert deleted filters families and hosts here are meant for Pyblish filtering, they should stay here for now. --- openpype/plugins/publish/extract_burnin.py | 37 +++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/openpype/plugins/publish/extract_burnin.py b/openpype/plugins/publish/extract_burnin.py index eab7652ae2..f113e61bb0 100644 --- a/openpype/plugins/publish/extract_burnin.py +++ b/openpype/plugins/publish/extract_burnin.py @@ -35,6 +35,26 @@ class ExtractBurnin(publish.Extractor): label = "Extract burnins" order = pyblish.api.ExtractorOrder + 0.03 + families = ["review", "burnin"] + hosts = [ + "nuke", + "maya", + "shell", + "hiero", + "premiere", + "traypublisher", + "standalonepublisher", + "harmony", + "fusion", + "aftereffects", + "tvpaint", + "webpublisher", + "aftereffects", + "photoshop", + "flame" + # "resolve" + ] + optional = True positions = [ @@ -123,9 +143,8 @@ class ExtractBurnin(publish.Extractor): return filtered_repres def main_process(self, instance): - host_name = instance.data["anatomyData"]["app"] - families = list(set(instance.data["family"]).union( - set(instance.data["families"]))) + host_name = instance.context.data["hostName"] + family = instance.data["family"] task_data = instance.data["anatomyData"].get("task", {}) task_name = task_data.get("name") task_type = task_data.get("type") @@ -133,7 +152,7 @@ class ExtractBurnin(publish.Extractor): filtering_criteria = { "hosts": host_name, - "families": families, + "families": family, "task_names": task_name, "task_types": task_type, "subset": subset @@ -144,8 +163,9 @@ class ExtractBurnin(publish.Extractor): if not profile: self.log.info(( "Skipped instance. None of profiles in presets are for" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\" | Task type \"{}\" | Subset \"{}\" " - ).format(host_name, families, task_name, task_type, subset)) + " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" + " | Task type \"{}\" | Subset \"{}\" " + ).format(host_name, family, task_name, task_type, subset)) return self.log.debug("profile: {}".format(profile)) @@ -155,8 +175,9 @@ class ExtractBurnin(publish.Extractor): if not burnin_defs: self.log.info(( "Skipped instance. Burnin definitions are not set for profile" - " Host: \"{}\" | Families: \"{}\" | Task \"{}\" | Profile \"{}\"" - ).format(host_name, families, task_name, profile)) + " Host: \"{}\" | Families: \"{}\" | Task \"{}\"" + " | Profile \"{}\"" + ).format(host_name, family, task_name, profile)) return burnin_options = self._get_burnin_options() From 76f1cbc2e3b93df36cc7bdc140e86ec5d0051f14 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Dec 2022 18:31:19 +0100 Subject: [PATCH 35/46] print help instead of invokinf 'interactive' command --- openpype/cli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/cli.py b/openpype/cli.py index 7611915d84..2c32220522 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -34,7 +34,8 @@ def main(ctx): # Default command for headless openpype is 'interactive' command # otherwise 'tray' is used. if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1": - ctx.invoke(interactive) + print(ctx.get_help()) + sys.exit(0) else: ctx.invoke(tray) From b05bcf94258c52578f9758205e3fb74d220e645b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 12 Dec 2022 18:34:07 +0100 Subject: [PATCH 36/46] Change comment --- openpype/cli.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index 2c32220522..897106c35f 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -31,8 +31,7 @@ def main(ctx): """ if ctx.invoked_subcommand is None: - # Default command for headless openpype is 'interactive' command - # otherwise 'tray' is used. + # Print help if headless mode is used if os.environ.get("OPENPYPE_HEADLESS_MODE") == "1": print(ctx.get_help()) sys.exit(0) From 7e129a8526f92ea2f2b92e959e673ff528beeb8a Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 13 Dec 2022 11:39:23 +0100 Subject: [PATCH 37/46] OP-4465 - added missed settings schema --- .../schemas/schema_global_publish.json | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json index f2ada5fd8d..5388d04bc9 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_global_publish.json @@ -526,11 +526,28 @@ "object_type": "text" }, { - "type": "hosts-enum", "key": "hosts", - "label": "Hosts", + "label": "Host names", + "type": "hosts-enum", "multiselection": true }, + { + "key": "task_types", + "label": "Task types", + "type": "task-types-enum" + }, + { + "key": "task_names", + "label": "Task names", + "type": "list", + "object_type": "text" + }, + { + "key": "subsets", + "label": "Subset names", + "type": "list", + "object_type": "text" + }, { "type": "splitter" }, From 54780b477aa1303585e2bfe19fd57ab6d36a087c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 13 Dec 2022 14:00:24 +0100 Subject: [PATCH 38/46] use new interface class name for publish host --- openpype/hosts/houdini/api/pipeline.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/api/pipeline.py b/openpype/hosts/houdini/api/pipeline.py index b0791fcb6c..f8e2c16d21 100644 --- a/openpype/hosts/houdini/api/pipeline.py +++ b/openpype/hosts/houdini/api/pipeline.py @@ -7,7 +7,7 @@ import contextlib import hou # noqa -from openpype.host import HostBase, IWorkfileHost, ILoadHost, INewPublisher +from openpype.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost import pyblish.api @@ -40,7 +40,7 @@ CREATE_PATH = os.path.join(PLUGINS_DIR, "create") INVENTORY_PATH = os.path.join(PLUGINS_DIR, "inventory") -class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, INewPublisher): +class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): name = "houdini" def __init__(self): From 23e9f120cf6152228b1f6c0ee735889f0433fb5c Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 13 Dec 2022 15:19:13 +0100 Subject: [PATCH 39/46] :recycle: fix 5.1 compatibility --- .../UE_5.0/Source/OpenPype/Private/AssetContainer.cpp | 8 ++++---- .../Source/OpenPype/Private/OpenPypePublishInstance.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp index c766f87a8e..4965ae2aab 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp @@ -30,8 +30,8 @@ void UAssetContainer::OnAssetAdded(const FAssetData& AssetData) // get asset path and class FString assetPath = AssetData.GetFullName(); - FString assetFName = AssetData.AssetClass.ToString(); - + FString assetFName = AssetData.AssetClassPath.ToString(); + UE_LOG(LogTemp, Log, TEXT("asset name %s"), *assetFName); // split path assetPath.ParseIntoArray(split, TEXT(" "), true); @@ -60,7 +60,7 @@ void UAssetContainer::OnAssetRemoved(const FAssetData& AssetData) // get asset path and class FString assetPath = AssetData.GetFullName(); - FString assetFName = AssetData.AssetClass.ToString(); + FString assetFName = AssetData.AssetClassPath.ToString(); // split path assetPath.ParseIntoArray(split, TEXT(" "), true); @@ -93,7 +93,7 @@ void UAssetContainer::OnAssetRenamed(const FAssetData& AssetData, const FString& // get asset path and class FString assetPath = AssetData.GetFullName(); - FString assetFName = AssetData.AssetClass.ToString(); + FString assetFName = AssetData.AssetClassPath.ToString(); // split path assetPath.ParseIntoArray(split, TEXT(" "), true); diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp index 322663eeec..c432ebb7e4 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp @@ -4,7 +4,7 @@ #include "AssetRegistryModule.h" #include "AssetToolsModule.h" #include "Framework/Notifications/NotificationManager.h" -#include "SNotificationList.h" +#include "Widgets/Notifications/SNotificationList.h" //Moves all the invalid pointers to the end to prepare them for the shrinking #define REMOVE_INVALID_ENTRIES(VAR) VAR.CompactStable(); \ @@ -47,7 +47,7 @@ void UOpenPypePublishInstance::OnAssetCreated(const FAssetData& InAssetData) if (!IsValid(Asset)) { UE_LOG(LogAssetData, Warning, TEXT("Asset \"%s\" is not valid! Skipping the addition."), - *InAssetData.ObjectPath.ToString()); + *InAssetData.GetObjectPathString()); return; } From b487b90fa0ac0943b02bc7b61575163780fb20fd Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 13 Dec 2022 15:19:29 +0100 Subject: [PATCH 40/46] :recycle: update build options --- .../integration/UE_5.0/Source/OpenPype/OpenPype.Build.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/OpenPype.Build.cs b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/OpenPype.Build.cs index fcfd268234..67db648b2a 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/OpenPype.Build.cs +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/OpenPype.Build.cs @@ -6,7 +6,11 @@ public class OpenPype : ModuleRules { public OpenPype(ReadOnlyTargetRules Target) : base(Target) { + DefaultBuildSettings = BuildSettingsVersion.V2; + bLegacyPublicIncludePaths = false; + ShadowVariableWarningLevel = WarningLevel.Error; PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; + IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_0; PublicIncludePaths.AddRange( new string[] { From 4d0e8180674eb0db2ba402fc8532ac9624309dcf Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Tue, 13 Dec 2022 15:33:15 +0100 Subject: [PATCH 41/46] :recycle: fix includes --- .../UE_5.0/Source/OpenPype/Private/AssetContainer.cpp | 2 +- .../UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp | 2 +- .../integration/UE_5.0/Source/OpenPype/Public/AssetContainer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp index 4965ae2aab..61e563f729 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/AssetContainer.cpp @@ -1,7 +1,7 @@ // Fill out your copyright notice in the Description page of Project Settings. #include "AssetContainer.h" -#include "AssetRegistryModule.h" +#include "AssetRegistry/AssetRegistryModule.h" #include "Misc/PackageName.h" #include "Engine.h" #include "Containers/UnrealString.h" diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp index c432ebb7e4..f5eb6f9e70 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Private/OpenPypePublishInstance.cpp @@ -1,7 +1,7 @@ #pragma once #include "OpenPypePublishInstance.h" -#include "AssetRegistryModule.h" +#include "AssetRegistry/AssetRegistryModule.h" #include "AssetToolsModule.h" #include "Framework/Notifications/NotificationManager.h" #include "Widgets/Notifications/SNotificationList.h" diff --git a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/AssetContainer.h b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/AssetContainer.h index 3c2a360c78..2c06e59d6f 100644 --- a/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/AssetContainer.h +++ b/openpype/hosts/unreal/integration/UE_5.0/Source/OpenPype/Public/AssetContainer.h @@ -5,7 +5,7 @@ #include "CoreMinimal.h" #include "UObject/NoExportTypes.h" #include "Engine/AssetUserData.h" -#include "AssetData.h" +#include "AssetRegistry/AssetData.h" #include "AssetContainer.generated.h" /** From b7afb84d6ca19df23b5bcfef7e451bfc65e749f7 Mon Sep 17 00:00:00 2001 From: Petr Kalis Date: Tue, 13 Dec 2022 17:28:20 +0100 Subject: [PATCH 42/46] Fix - join needs list --- openpype/tools/attribute_defs/files_widget.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/attribute_defs/files_widget.py b/openpype/tools/attribute_defs/files_widget.py index 738e50ba07..2c8ed729c2 100644 --- a/openpype/tools/attribute_defs/files_widget.py +++ b/openpype/tools/attribute_defs/files_widget.py @@ -155,7 +155,7 @@ class DropEmpty(QtWidgets.QWidget): extensions_label = " or ".join(allowed_items) else: last_item = allowed_items.pop(-1) - new_last_item = " or ".join(last_item, allowed_items.pop(-1)) + new_last_item = " or ".join([last_item, allowed_items.pop(-1)]) allowed_items.append(new_last_item) extensions_label = ", ".join(allowed_items) From 7810d425dabe7900411809e61444c9ab820205bb Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 13 Dec 2022 16:52:32 +0000 Subject: [PATCH 43/46] Camera is created only when the creator is not using the selection --- openpype/hosts/blender/plugins/create/create_camera.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 1a3c008069..ada512d7ac 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -32,11 +32,6 @@ class CreateCamera(plugin.Creator): subset = self.data["subset"] name = plugin.asset_name(asset, subset) - camera = bpy.data.cameras.new(subset) - camera_obj = bpy.data.objects.new(subset, camera) - - instances.objects.link(camera_obj) - asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) @@ -53,6 +48,11 @@ class CreateCamera(plugin.Creator): bpy.ops.object.parent_set(keep_transform=True) else: plugin.deselect_all() + camera = bpy.data.cameras.new(subset) + camera_obj = bpy.data.objects.new(subset, camera) + + instances.objects.link(camera_obj) + camera_obj.select_set(True) asset_group.select_set(True) bpy.context.view_layer.objects.active = asset_group From 730df2a4cd976f859f78cdf0ca60e484edd0d51f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 13 Dec 2022 21:55:41 +0100 Subject: [PATCH 44/46] deadline: pr comments --- .../deadline/plugins/publish/submit_publish_job.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_job.py index 5ed8c83412..5c5c54febb 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_job.py @@ -127,10 +127,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "celaction": [r".*"]} environ_job_filter = [ - "OPENPYPE_METADATA_FILE", - "OPENPYPE_PUBLISH_JOB", - "OPENPYPE_RENDER_JOB", - "OPENPYPE_LOG_NO_COLORS" + "OPENPYPE_METADATA_FILE" ] environ_keys = [ @@ -238,10 +235,11 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): "AVALON_PROJECT": legacy_io.Session["AVALON_PROJECT"], "AVALON_ASSET": legacy_io.Session["AVALON_ASSET"], "AVALON_TASK": legacy_io.Session["AVALON_TASK"], - "OPENPYPE_LOG_NO_COLORS": "1", "OPENPYPE_USERNAME": instance.context.data["user"], "OPENPYPE_PUBLISH_JOB": "1", - "OPENPYPE_RENDER_JOB": "0" + "OPENPYPE_RENDER_JOB": "0", + "OPENPYPE_REMOTE_JOB": "0", + "OPENPYPE_LOG_NO_COLORS": "1" } # add environments from self.environ_keys From c58162bb1e6246d32ef0e58f0202b17ac90afe44 Mon Sep 17 00:00:00 2001 From: OpenPype Date: Wed, 14 Dec 2022 03:30:40 +0000 Subject: [PATCH 45/46] [Automated] Bump version --- openpype/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/version.py b/openpype/version.py index 190f7ac401..8d82df563d 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.14.9-nightly.3" +__version__ = "3.14.9-nightly.4" From 4d20f025f63d8178aece5fe58d28a8a3f6997aeb Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 14 Dec 2022 16:34:40 +0100 Subject: [PATCH 46/46] :bug: fix empty ue folder bug --- openpype/hosts/unreal/lib.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/unreal/lib.py b/openpype/hosts/unreal/lib.py index d02c6de357..095f5e414b 100644 --- a/openpype/hosts/unreal/lib.py +++ b/openpype/hosts/unreal/lib.py @@ -50,7 +50,10 @@ def get_engine_versions(env=None): # environment variable not set pass except OSError: - # specified directory doesn't exists + # specified directory doesn't exist + pass + except StopIteration: + # specified directory doesn't exist pass # if we've got something, terminate auto-detection process