From ca6f2b467ded88c0b0a8ac662f1e75145394f0a3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 24 Apr 2023 11:40:33 +0200 Subject: [PATCH 001/690] Add Fusion USD loader --- .../hosts/fusion/plugins/load/load_usd.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 openpype/hosts/fusion/plugins/load/load_usd.py diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py new file mode 100644 index 0000000000..8c2c69f52f --- /dev/null +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -0,0 +1,73 @@ +from openpype.pipeline import ( + load, + get_representation_path, +) +from openpype.hosts.fusion.api import ( + imprint_container, + get_current_comp, + comp_lock_and_undo_chunk +) + + +class FusionLoadAlembicMesh(load.LoaderPlugin): + """Load USD into Fusion + + Support for USD was added since Fusion 18.5 + """ + + families = ["*"] + representations = ["*"] + extensions = {"usd", "usda", "usdz"} + + label = "Load USD" + order = -10 + icon = "code-fork" + color = "orange" + + tool_type = "uLoader" + + def load(self, context, name, namespace, data): + # Fallback to asset name when namespace is None + if namespace is None: + namespace = context['asset']['name'] + + # Create the Loader with the filename path set + comp = get_current_comp() + with comp_lock_and_undo_chunk(comp, "Create tool"): + + path = self.fname + + args = (-32768, -32768) + tool = comp.AddTool(self.tool_type, *args) + tool["Filename"] = path + + imprint_container(tool, + name=name, + namespace=namespace, + context=context, + loader=self.__class__.__name__) + + def switch(self, container, representation): + self.update(container, representation) + + def update(self, container, representation): + + tool = container["_tool"] + assert tool.ID == self.tool_type, f"Must be {self.tool_type}" + comp = tool.Comp() + + path = get_representation_path(representation) + + with comp_lock_and_undo_chunk(comp, "Update tool"): + tool["Filename"] = path + + # Update the imprinted representation + tool.SetData("avalon.representation", str(representation["_id"])) + + def remove(self, container): + tool = container["_tool"] + assert tool.ID == self.tool_type, f"Must be {self.tool_type}" + comp = tool.Comp() + + with comp_lock_and_undo_chunk(comp, "Remove tool"): + tool.Delete() From 00b68805069207584dc955883268b3bbcab1005e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Tue, 30 May 2023 13:06:13 +0200 Subject: [PATCH 002/690] Fix Nuke workfile template builder so representations get loaded next to each other for a single placeholder --- .../maya/api/workfile_template_builder.py | 2 +- .../nuke/api/workfile_template_builder.py | 8 +++-- .../workfile/workfile_template_builder.py | 29 ++++++++++++------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index 6e6166c2ef..504db4dc06 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -250,7 +250,7 @@ class MayaPlaceholderLoadPlugin(PlaceholderPlugin, PlaceholderLoadMixin): def get_placeholder_options(self, options=None): return self.get_load_plugin_options(options) - def cleanup_placeholder(self, placeholder, failed): + def cleanup_placeholder(self, placeholder): """Hide placeholder, add them to placeholder set """ node = placeholder._scene_identifier diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 72d4ffb476..3def140c92 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -156,8 +156,10 @@ class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): ) return loaded_representation_ids - def _before_repre_load(self, placeholder, representation): + def _before_placeholder_load(self, placeholder): placeholder.data["nodes_init"] = nuke.allNodes() + + def _before_repre_load(self, placeholder, representation): placeholder.data["last_repre_id"] = str(representation["_id"]) def collect_placeholders(self): @@ -189,7 +191,7 @@ class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): def get_placeholder_options(self, options=None): return self.get_load_plugin_options(options) - def cleanup_placeholder(self, placeholder, failed): + def cleanup_placeholder(self, placeholder): # deselect all selected nodes placeholder_node = nuke.toNode(placeholder.scene_identifier) @@ -603,7 +605,7 @@ class NukePlaceholderCreatePlugin( def get_placeholder_options(self, options=None): return self.get_create_plugin_options(options) - def cleanup_placeholder(self, placeholder, failed): + def cleanup_placeholder(self, placeholder): # deselect all selected nodes placeholder_node = nuke.toNode(placeholder.scene_identifier) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 896ed40f2d..a8a7ffec75 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -1457,8 +1457,15 @@ class PlaceholderLoadMixin(object): context_filters=context_filters )) + def _before_placeholder_load(self, placeholder): + """Can be overridden. It's called before placeholder representations + are loaded. + """ + + pass + def _before_repre_load(self, placeholder, representation): - """Can be overriden. Is called before representation is loaded.""" + """Can be overridden. It's called before representation is loaded.""" pass @@ -1491,7 +1498,7 @@ class PlaceholderLoadMixin(object): return output def populate_load_placeholder(self, placeholder, ignore_repre_ids=None): - """Load placeholder is goind to load matching representations. + """Load placeholder is going to load matching representations. Note: Ignore repre ids is to avoid loading the same representation again @@ -1513,7 +1520,7 @@ class PlaceholderLoadMixin(object): # TODO check loader existence loader_name = placeholder.data["loader"] - loader_args = placeholder.data["loader_args"] + loader_args = self.parse_loader_args(placeholder.data["loader_args"]) placeholder_representations = self._get_representations(placeholder) @@ -1535,6 +1542,9 @@ class PlaceholderLoadMixin(object): self.project_name, filtered_representations ) loaders_by_name = self.builder.get_loaders_by_name() + self._before_placeholder_load( + placeholder + ) for repre_load_context in repre_load_contexts.values(): representation = repre_load_context["representation"] repre_context = representation["context"] @@ -1547,24 +1557,24 @@ class PlaceholderLoadMixin(object): repre_context["subset"], repre_context["asset"], loader_name, - loader_args + placeholder.data["loader_args"], ) ) try: container = load_with_repre_context( loaders_by_name[loader_name], repre_load_context, - options=self.parse_loader_args(loader_args) + options=loader_args ) except Exception: - failed = True self.load_failed(placeholder, representation) else: - failed = False self.load_succeed(placeholder, container) - self.cleanup_placeholder(placeholder, failed) + + # Cleanup placeholder after load of all representations + self.cleanup_placeholder(placeholder) def load_failed(self, placeholder, representation): if hasattr(placeholder, "load_failed"): @@ -1574,7 +1584,7 @@ class PlaceholderLoadMixin(object): if hasattr(placeholder, "load_succeed"): placeholder.load_succeed(container) - def cleanup_placeholder(self, placeholder, failed): + def cleanup_placeholder(self, placeholder): """Cleanup placeholder after load of single representation. Can be called multiple times during placeholder item populating and is @@ -1583,7 +1593,6 @@ class PlaceholderLoadMixin(object): Args: placeholder (PlaceholderItem): Item which was just used to load representation. - failed (bool): Loading of representation failed. """ pass From c253bc11d0af425744384ee6a1cb39bc9a8c0277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Tue, 30 May 2023 13:13:25 +0200 Subject: [PATCH 003/690] Fix docstring --- openpype/pipeline/workfile/workfile_template_builder.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index a8a7ffec75..a081b66789 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -1585,10 +1585,7 @@ class PlaceholderLoadMixin(object): placeholder.load_succeed(container) def cleanup_placeholder(self, placeholder): - """Cleanup placeholder after load of single representation. - - Can be called multiple times during placeholder item populating and is - called even if loading failed. + """Cleanup placeholder after load of its corresponding representations. Args: placeholder (PlaceholderItem): Item which was just used to load From ac7e53a44a038df8c31ad1fbd4d49c8c90c3a95b Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 3 Jul 2023 16:55:53 -0500 Subject: [PATCH 004/690] Set some default `failed` value on the right scope --- openpype/pipeline/workfile/workfile_template_builder.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 13fcd3693e..8853097b21 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -1547,6 +1547,8 @@ class PlaceholderLoadMixin(object): self._before_placeholder_load( placeholder ) + + failed = False for repre_load_context in repre_load_contexts.values(): representation = repre_load_context["representation"] repre_context = representation["context"] @@ -1571,9 +1573,10 @@ class PlaceholderLoadMixin(object): except Exception: self.load_failed(placeholder, representation) - + failed = True else: self.load_succeed(placeholder, container) + # Run post placeholder process after load of all representations self.post_placeholder_process(placeholder, failed) From 833d2fcb737aa6e8e561a927a93ee60de6225014 Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 3 Jul 2023 17:01:10 -0500 Subject: [PATCH 005/690] Fix docstrings --- .../hosts/maya/api/workfile_template_builder.py | 8 +++++++- .../hosts/nuke/api/workfile_template_builder.py | 14 ++++++++++++++ .../pipeline/workfile/workfile_template_builder.py | 10 ++-------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/maya/api/workfile_template_builder.py b/openpype/hosts/maya/api/workfile_template_builder.py index e2f30f46d0..30113578c5 100644 --- a/openpype/hosts/maya/api/workfile_template_builder.py +++ b/openpype/hosts/maya/api/workfile_template_builder.py @@ -244,8 +244,14 @@ class MayaPlaceholderLoadPlugin(PlaceholderPlugin, PlaceholderLoadMixin): return self.get_load_plugin_options(options) def post_placeholder_process(self, placeholder, failed): - """Hide placeholder, add them to placeholder set + """Cleanup placeholder after load of its corresponding representations. + + Args: + placeholder (PlaceholderItem): Item which was just used to load + representation. + failed (bool): Loading of representation failed. """ + # Hide placeholder and add them to placeholder set node = placeholder.scene_identifier cmds.sets(node, addElement=PLACEHOLDER_SET) diff --git a/openpype/hosts/nuke/api/workfile_template_builder.py b/openpype/hosts/nuke/api/workfile_template_builder.py index 7fc1ff385b..672c5cb836 100644 --- a/openpype/hosts/nuke/api/workfile_template_builder.py +++ b/openpype/hosts/nuke/api/workfile_template_builder.py @@ -193,6 +193,13 @@ class NukePlaceholderLoadPlugin(NukePlaceholderPlugin, PlaceholderLoadMixin): return self.get_load_plugin_options(options) def post_placeholder_process(self, placeholder, failed): + """Cleanup placeholder after load of its corresponding representations. + + Args: + placeholder (PlaceholderItem): Item which was just used to load + representation. + failed (bool): Loading of representation failed. + """ # deselect all selected nodes placeholder_node = nuke.toNode(placeholder.scene_identifier) @@ -607,6 +614,13 @@ class NukePlaceholderCreatePlugin( return self.get_create_plugin_options(options) def post_placeholder_process(self, placeholder, failed): + """Cleanup placeholder after load of its corresponding representations. + + Args: + placeholder (PlaceholderItem): Item which was just used to load + representation. + failed (bool): Loading of representation failed. + """ # deselect all selected nodes placeholder_node = nuke.toNode(placeholder.scene_identifier) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 8853097b21..8ef83a4cdd 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -1598,10 +1598,7 @@ class PlaceholderLoadMixin(object): placeholder.load_succeed(container) def post_placeholder_process(self, placeholder, failed): - """Cleanup placeholder after load of single representation. - - Can be called multiple times during placeholder item populating and is - called even if loading failed. + """Cleanup placeholder after load of its corresponding representations. Args: placeholder (PlaceholderItem): Item which was just used to load @@ -1788,10 +1785,7 @@ class PlaceholderCreateMixin(object): placeholder.create_succeed(creator_instance) def post_placeholder_process(self, placeholder, failed): - """Cleanup placeholder after load of single representation. - - Can be called multiple times during placeholder item populating and is - called even if loading failed. + """Cleanup placeholder after load of its corresponding representations. Args: placeholder (PlaceholderItem): Item which was just used to load From 9847f879d827a56108348bae27985fd25316ffdc Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 3 Jul 2023 17:03:23 -0500 Subject: [PATCH 006/690] Revert to original docstring --- openpype/pipeline/workfile/workfile_template_builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/pipeline/workfile/workfile_template_builder.py b/openpype/pipeline/workfile/workfile_template_builder.py index 8ef83a4cdd..3b06ef059b 100644 --- a/openpype/pipeline/workfile/workfile_template_builder.py +++ b/openpype/pipeline/workfile/workfile_template_builder.py @@ -1603,7 +1603,7 @@ class PlaceholderLoadMixin(object): Args: placeholder (PlaceholderItem): Item which was just used to load representation. - failed (bool): True if loading failed. + failed (bool): Loading of representation failed. """ pass From f814db2ce0c4432023b18903c7819729997abfb5 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Thu, 6 Jul 2023 10:45:00 +0100 Subject: [PATCH 007/690] Use colorspace data when creating thumbnail. --- openpype/lib/transcoding.py | 13 +++-- openpype/plugins/publish/extract_thumbnail.py | 51 ++++++++++++------- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index de6495900e..771f670f89 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -1056,7 +1056,8 @@ def convert_colorspace( view=None, display=None, additional_command_args=None, - logger=None + logger=None, + input_args=None ): """Convert source file from one color space to another. @@ -1084,13 +1085,17 @@ def convert_colorspace( if logger is None: logger = logging.getLogger(__name__) - oiio_cmd = [ - get_oiio_tools_path(), + oiio_cmd = [get_oiio_tools_path()] + + if input_args: + oiio_cmd.extend(input_args) + + oiio_cmd.extend([ input_path, # Don't add any additional attributes "--nosoftwareattrib", "--colorconfig", config_path - ] + ]) if all([target_colorspace, view, display]): raise ValueError("Colorspace and both screen and display" diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index b98ab64f56..1d86741470 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -10,6 +10,7 @@ from openpype.lib import ( run_subprocess, path_to_subprocess_arg, ) +from openpype.lib.transcoding import convert_colorspace class ExtractThumbnail(pyblish.api.InstancePlugin): @@ -98,8 +99,18 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): self.log.debug("Trying to convert with OIIO") # If the input can read by OIIO then use OIIO method for # conversion otherwise use ffmpeg + colorspace_data = repre["colorspaceData"] + source_colorspace = colorspace_data["colorspace"] + config_path = colorspace_data.get("config", {}).get("path") + display = colorspace_data["display"] + view = colorspace_data["view"] thumbnail_created = self.create_thumbnail_oiio( - full_input_path, full_output_path + full_input_path, + full_output_path, + config_path, + source_colorspace, + display, + view ) # Try to use FFMPEG if OIIO is not supported or for cases when @@ -172,24 +183,28 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): filtered_repres.append(repre) return filtered_repres - def create_thumbnail_oiio(self, src_path, dst_path): + def create_thumbnail_oiio( + self, + src_path, + dst_path, + config_path, + source_colorspace, + display, + view + ): self.log.info("Extracting thumbnail {}".format(dst_path)) - oiio_tool_path = get_oiio_tools_path() - oiio_cmd = [ - oiio_tool_path, - "-a", src_path, - "-o", dst_path - ] - self.log.debug("running: {}".format(" ".join(oiio_cmd))) - try: - run_subprocess(oiio_cmd, logger=self.log) - return True - except Exception: - self.log.warning( - "Failed to create thumbnail using oiiotool", - exc_info=True - ) - return False + + convert_colorspace( + src_path, + dst_path, + config_path, + source_colorspace, + view=view, + display=display, + input_args=["-i:ch=R,G,B"] + ) + + return dst_path def create_thumbnail_ffmpeg(self, src_path, dst_path): self.log.info("outputting {}".format(dst_path)) From 08d17e527443fab05731eb0428806568e8e297aa Mon Sep 17 00:00:00 2001 From: Jacob Danell Date: Thu, 20 Jul 2023 15:44:19 +0200 Subject: [PATCH 008/690] Added possibility to discard changes with comp_lock_and_undo_chunk() --- openpype/hosts/fusion/api/lib.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index d96557571b..56705b1a40 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -354,7 +354,11 @@ def get_current_comp(): @contextlib.contextmanager -def comp_lock_and_undo_chunk(comp, undo_queue_name="Script CMD"): +def comp_lock_and_undo_chunk( + comp, + undo_queue_name="Script CMD", + keep_undo=True, +): """Lock comp and open an undo chunk during the context""" try: comp.Lock() @@ -362,4 +366,4 @@ def comp_lock_and_undo_chunk(comp, undo_queue_name="Script CMD"): yield finally: comp.Unlock() - comp.EndUndo() + comp.EndUndo(keep_undo) From 6a3729c22923ad76b205a8f750501c7b6c6e7336 Mon Sep 17 00:00:00 2001 From: Jacob Danell Date: Thu, 20 Jul 2023 15:44:38 +0200 Subject: [PATCH 009/690] Add resolution validator --- .../publish/validator_saver_resolution.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py new file mode 100644 index 0000000000..43e2ea5093 --- /dev/null +++ b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py @@ -0,0 +1,96 @@ +import pyblish.api +from openpype.pipeline import ( + PublishValidationError, + OptionalPyblishPluginMixin, +) + +from openpype.hosts.fusion.api.action import SelectInvalidAction +from openpype.hosts.fusion.api import ( + get_current_comp, + comp_lock_and_undo_chunk, +) + + +class ValidateSaverResolution( + pyblish.api.InstancePlugin, OptionalPyblishPluginMixin +): + """Validate that the saver input resolution matches the projects""" + + order = pyblish.api.ValidatorOrder + label = "Validate Saver Resolution" + families = ["render"] + hosts = ["fusion"] + optional = True + actions = [SelectInvalidAction] + + @classmethod + def get_invalid(cls, instance, wrong_resolution=None): + """Validate if the saver rescive the expected resolution""" + if wrong_resolution is None: + wrong_resolution = [] + + saver = instance[0] + firstFrame = saver.GetAttrs("TOOLNT_Region_Start")[1] + comp = get_current_comp() + + # If the current saver hasn't bin rendered its input resolution + # hasn't bin saved. To combat this, add an expression in + # the comments field to read the resolution + + # False undo removes the undo-stack from the undo list + with comp_lock_and_undo_chunk(comp, "Read resolution", False): + # Save old comment + oldComment = "" + hasExpression = False + if saver["Comments"][firstFrame] != "": + if saver["Comments"].GetExpression() is not None: + hasExpression = True + oldComment = saver["Comments"].GetExpression() + saver["Comments"].SetExpression(None) + else: + oldComment = saver["Comments"][firstFrame] + saver["Comments"][firstFrame] = "" + + # Get input width + saver["Comments"].SetExpression("self.Input.OriginalWidth") + width = int(saver["Comments"][firstFrame]) + + # Get input height + saver["Comments"].SetExpression("self.Input.OriginalHeight") + height = int(saver["Comments"][firstFrame]) + + # Reset old comment + saver["Comments"].SetExpression(None) + if hasExpression: + saver["Comments"].SetExpression(oldComment) + else: + saver["Comments"][firstFrame] = oldComment + + # Time to compare! + wrong_resolution.append("{}x{}".format(width, height)) + entityData = instance.data["assetEntity"]["data"] + if entityData["resolutionWidth"] != width: + return [saver] + if entityData["resolutionHeight"] != height: + return [saver] + + return [] + + def process(self, instance): + if not self.is_active(instance.data): + return + + wrong_resolution = [] + invalid = self.get_invalid(instance, wrong_resolution) + if invalid: + entityData = instance.data["assetEntity"]["data"] + raise PublishValidationError( + "The input's resolution does not match" + " the asset's resolution of {}x{}.\n\n" + "The input's resolution is {}".format( + entityData["resolutionWidth"], + entityData["resolutionHeight"], + wrong_resolution[0], + ), + title=self.label, + ) From 644897a89d81a5be31371bde9d03a81b92e6b8f8 Mon Sep 17 00:00:00 2001 From: Jacob Danell Date: Thu, 20 Jul 2023 15:44:50 +0200 Subject: [PATCH 010/690] Black formatting --- openpype/hosts/fusion/api/lib.py | 106 +++++++++++++++++++------------ 1 file changed, 67 insertions(+), 39 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 56705b1a40..19db484856 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -22,8 +22,14 @@ self = sys.modules[__name__] self._project = None -def update_frame_range(start, end, comp=None, set_render_range=True, - handle_start=0, handle_end=0): +def update_frame_range( + start, + end, + comp=None, + set_render_range=True, + handle_start=0, + handle_end=0, +): """Set Fusion comp's start and end frame range Args: @@ -49,15 +55,17 @@ def update_frame_range(start, end, comp=None, set_render_range=True, attrs = { "COMPN_GlobalStart": start - handle_start, - "COMPN_GlobalEnd": end + handle_end + "COMPN_GlobalEnd": end + handle_end, } # set frame range if set_render_range: - attrs.update({ - "COMPN_RenderStart": start, - "COMPN_RenderEnd": end - }) + attrs.update( + { + "COMPN_RenderStart": start, + "COMPN_RenderEnd": end, + } + ) with comp_lock_and_undo_chunk(comp): comp.SetAttrs(attrs) @@ -70,9 +78,13 @@ def set_asset_framerange(): end = asset_doc["data"]["frameEnd"] handle_start = asset_doc["data"]["handleStart"] handle_end = asset_doc["data"]["handleEnd"] - update_frame_range(start, end, set_render_range=True, - handle_start=handle_start, - handle_end=handle_end) + update_frame_range( + start, + end, + set_render_range=True, + handle_start=handle_start, + handle_end=handle_end, + ) def set_asset_resolution(): @@ -82,12 +94,15 @@ def set_asset_resolution(): height = asset_doc["data"]["resolutionHeight"] comp = get_current_comp() - print("Setting comp frame format resolution to {}x{}".format(width, - height)) - comp.SetPrefs({ - "Comp.FrameFormat.Width": width, - "Comp.FrameFormat.Height": height, - }) + print( + "Setting comp frame format resolution to {}x{}".format(width, height) + ) + comp.SetPrefs( + { + "Comp.FrameFormat.Width": width, + "Comp.FrameFormat.Height": height, + } + ) def validate_comp_prefs(comp=None, force_repair=False): @@ -108,7 +123,7 @@ def validate_comp_prefs(comp=None, force_repair=False): "data.fps", "data.resolutionWidth", "data.resolutionHeight", - "data.pixelAspect" + "data.pixelAspect", ] asset_doc = get_current_project_asset(fields=fields) asset_data = asset_doc["data"] @@ -125,7 +140,7 @@ def validate_comp_prefs(comp=None, force_repair=False): ("resolutionWidth", "Width", "Resolution Width"), ("resolutionHeight", "Height", "Resolution Height"), ("pixelAspectX", "AspectX", "Pixel Aspect Ratio X"), - ("pixelAspectY", "AspectY", "Pixel Aspect Ratio Y") + ("pixelAspectY", "AspectY", "Pixel Aspect Ratio Y"), ] invalid = [] @@ -133,9 +148,9 @@ def validate_comp_prefs(comp=None, force_repair=False): asset_value = asset_data[key] comp_value = comp_frame_format_prefs.get(comp_key) if asset_value != comp_value: - invalid_msg = "{} {} should be {}".format(label, - comp_value, - asset_value) + invalid_msg = "{} {} should be {}".format( + label, comp_value, asset_value + ) invalid.append(invalid_msg) if not force_repair: @@ -146,7 +161,8 @@ def validate_comp_prefs(comp=None, force_repair=False): pref=label, value=comp_value, asset_name=asset_doc["name"], - asset_value=asset_value) + asset_value=asset_value, + ) ) if invalid: @@ -167,6 +183,7 @@ def validate_comp_prefs(comp=None, force_repair=False): from . import menu from openpype.widgets import popup from openpype.style import load_stylesheet + dialog = popup.Popup(parent=menu.menu) dialog.setWindowTitle("Fusion comp has invalid configuration") @@ -181,10 +198,12 @@ def validate_comp_prefs(comp=None, force_repair=False): dialog.setStyleSheet(load_stylesheet()) -def switch_item(container, - asset_name=None, - subset_name=None, - representation_name=None): +def switch_item( + container, + asset_name=None, + subset_name=None, + representation_name=None, +): """Switch container asset, subset or representation of a container by name. It'll always switch to the latest version - of course a different @@ -211,7 +230,8 @@ def switch_item(container, repre_id = container["representation"] representation = get_representation_by_id(project_name, repre_id) repre_parent_docs = get_representation_parents( - project_name, representation) + project_name, representation + ) if repre_parent_docs: version, subset, asset, _ = repre_parent_docs else: @@ -228,14 +248,18 @@ def switch_item(container, # Find the new one asset = get_asset_by_name(project_name, asset_name, fields=["_id"]) - assert asset, ("Could not find asset in the database with the name " - "'%s'" % asset_name) + assert asset, ( + "Could not find asset in the database with the name " + "'%s'" % asset_name + ) subset = get_subset_by_name( project_name, subset_name, asset["_id"], fields=["_id"] ) - assert subset, ("Could not find subset in the database with the name " - "'%s'" % subset_name) + assert subset, ( + "Could not find subset in the database with the name " + "'%s'" % subset_name + ) version = get_last_version_by_subset_id( project_name, subset["_id"], fields=["_id"] @@ -247,8 +271,10 @@ def switch_item(container, representation = get_representation_by_name( project_name, representation_name, version["_id"] ) - assert representation, ("Could not find representation in the database " - "with the name '%s'" % representation_name) + assert representation, ( + "Could not find representation in the database " + "with the name '%s'" % representation_name + ) switch_container(container, representation) @@ -273,11 +299,13 @@ def maintained_selection(comp=None): @contextlib.contextmanager -def maintained_comp_range(comp=None, - global_start=True, - global_end=True, - render_start=True, - render_end=True): +def maintained_comp_range( + comp=None, + global_start=True, + global_end=True, + render_start=True, + render_end=True, +): """Reset comp frame ranges from before the context after the context""" if comp is None: comp = get_current_comp() @@ -321,7 +349,7 @@ def get_frame_path(path): filename, ext = os.path.splitext(path) # Find a final number group - match = re.match('.*?([0-9]+)$', filename) + match = re.match(".*?([0-9]+)$", filename) if match: padding = len(match.group(1)) # remove number from end since fusion From 3841d298b2d1d3837a5a5e569cc120b3f87b9655 Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 7 Aug 2023 18:22:49 +0200 Subject: [PATCH 011/690] First draft at adding support in Houdini renders to split render in export + render tasks --- .../plugins/create/create_arnold_rop.py | 14 ++ .../plugins/create/create_mantra_rop.py | 11 + .../houdini/plugins/create/create_vray_rop.py | 15 ++ .../plugins/publish/collect_arnold_rop.py | 15 ++ .../plugins/publish/collect_mantra_rop.py | 15 ++ .../plugins/publish/collect_vray_rop.py | 16 ++ .../deadline/abstract_submit_deadline.py | 22 +- .../publish/submit_houdini_render_deadline.py | 205 ++++++++++++++++-- 8 files changed, 293 insertions(+), 20 deletions(-) diff --git a/openpype/hosts/houdini/plugins/create/create_arnold_rop.py b/openpype/hosts/houdini/plugins/create/create_arnold_rop.py index ca516619f6..d19795d3a9 100644 --- a/openpype/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_arnold_rop.py @@ -14,6 +14,9 @@ class CreateArnoldRop(plugin.HoudiniCreator): # Default extension ext = "exr" + # Default to split export and render jobs + export_job = True + def create(self, subset_name, instance_data, pre_create_data): import hou @@ -49,6 +52,14 @@ class CreateArnoldRop(plugin.HoudiniCreator): "ar_exr_half_precision": 1 # half precision } + if pre_create_data.get("export_job"): + ass_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.ass".format( + export_dir=hou.text.expandString("$HIP/pyblish/ass/"), + subset_name=subset_name, + ) + parms["ar_ass_export_enable"] = 1 + parms["ar_ass_file"] = ass_filepath + instance_node.setParms(parms) # Lock any parameters in this list @@ -67,6 +78,9 @@ class CreateArnoldRop(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), + BoolDef("export_job", + label="Split export and render jobs", + default=self.export_job), EnumDef("image_format", image_format_enum, default=self.ext, diff --git a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py index 5c29adb33f..41311a1e30 100644 --- a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py @@ -13,6 +13,9 @@ class CreateMantraROP(plugin.HoudiniCreator): icon = "magic" defaults = ["master"] + # Default to split export and render jobs + export_job = True + def create(self, subset_name, instance_data, pre_create_data): import hou # noqa @@ -45,6 +48,14 @@ class CreateMantraROP(plugin.HoudiniCreator): "vm_picture": filepath, } + if pre_create_data.get("export_job"): + ifd_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.ifd".format( + export_dir=hou.text.expandString("$HIP/pyblish/ifd/"), + subset_name=subset_name, + ) + parms["soho_outputmode"] = 1 + parms["soho_diskfile"] = ifd_filepath + if self.selected_nodes: # If camera found in selection # we will use as render camera diff --git a/openpype/hosts/houdini/plugins/create/create_vray_rop.py b/openpype/hosts/houdini/plugins/create/create_vray_rop.py index 58748d4c34..29fab0c60c 100644 --- a/openpype/hosts/houdini/plugins/create/create_vray_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_vray_rop.py @@ -18,6 +18,9 @@ class CreateVrayROP(plugin.HoudiniCreator): ext = "exr" + # Default to split export and render jobs + export_job = True + def create(self, subset_name, instance_data, pre_create_data): instance_data.pop("active", None) @@ -54,6 +57,15 @@ class CreateVrayROP(plugin.HoudiniCreator): "SettingsEXR_bits_per_channel": "16" # half precision } + if pre_create_data.get("export_job"): + scene_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.vrscene".format( + export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), + subset_name=subset_name, + ) + # TODO: don't have VRay to check the names of these + parms["render_export_mode"] = 1 + parms["render_export_filepath"] = scene_filepath + if self.selected_nodes: # set up the render camera from the selected node camera = None @@ -142,6 +154,9 @@ class CreateVrayROP(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), + BoolDef("export_job", + label="Split export and render jobs", + default=self.export_job), EnumDef("image_format", image_format_enum, default=self.ext, diff --git a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py index 43b8428c60..063dd728e1 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -38,6 +38,21 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "ar_picture") render_products = [] + # Store whether we are splitting the render job in an export + render + export_job = bool(rop.parm("ar_ass_export_enable").eval()) + instance.data["exportJob"] = export_job + export_prefix = None + export_products = [] + if export_job: + export_prefix = evalParmNoFrame(rop, "ar_ass_file", pad_character="0") + beauty_export_product = self.get_render_product_name( + prefix=export_prefix, + suffix=None) + export_products.append(beauty_export_product) + self.log.debug("Found export product: {}".format(beauty_export_product)) + instance.data["ifdFile"] = beauty_export_product + instance.data["exportFiles"] = list(export_products) + # Default beauty AOV beauty_product = self.get_render_product_name(prefix=default_prefix, suffix=None) diff --git a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py index c4460f5350..b235e2c110 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -42,6 +42,21 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "vm_picture") render_products = [] + # Store whether we are splitting the render job in an export + render + export_job = bool(rop.parm("soho_outputmode").eval()) + instance.data["exportJob"] = export_job + export_prefix = None + export_products = [] + if export_job: + export_prefix = evalParmNoFrame(rop, "soho_diskfile", pad_character="0") + beauty_export_product = self.get_render_product_name( + prefix=export_prefix, + suffix=None) + export_products.append(beauty_export_product) + self.log.debug("Found export product: {}".format(beauty_export_product)) + instance.data["ifdFile"] = beauty_export_product + instance.data["exportFiles"] = list(export_products) + # Default beauty AOV beauty_product = self.get_render_product_name( prefix=default_prefix, suffix=None diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index d4fe37f993..89a7c8bf72 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -43,6 +43,22 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): render_products = [] # TODO: add render elements if render element + # Store whether we are splitting the render job in an export + render + # TODO: check names of VRay parms + export_job = bool(rop.parm("render_export_mode").eval()) + instance.data["exportJob"] = export_job + export_prefix = None + export_products = [] + if export_job: + export_prefix = evalParmNoFrame(rop, "render_export_filepath", pad_character="0") + beauty_export_product = self.get_render_product_name( + prefix=export_prefix, + suffix=None) + export_products.append(beauty_export_product) + self.log.debug("Found export product: {}".format(beauty_export_product)) + instance.data["ifdFile"] = beauty_export_product + instance.data["exportFiles"] = list(export_products) + beauty_product = self.get_beauty_render_product(default_prefix) render_products.append(beauty_product) files_by_aov = { diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index 3fa427204b..56d8afbe3e 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -446,11 +446,29 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin, self.scene_path = file_path self.log.info("Using {} for render/export.".format(file_path)) - self.job_info = self.get_job_info() + # Check whether we are splitting render job in export + render + # and if so, create a separate task for the render + # TODO: Find a cleaner way so `get_job_info` can take extra args depending + # on host + export_job = instance.data["exportJob"] + self.job_info = self.get_job_info(split_render_job=export_job, export_job=True) self.plugin_info = self.get_plugin_info() self.aux_files = self.get_aux_files() - self.process_submission() + job_id = self.process_submission() + if export_job: + self.log.info("Splitting export and render in two jobs") + self.log.info("Export job id: %s", job_id) + render_job_info = self.get_job_info( + split_render_job=True, dependency_job_ids=[job_id] + ) + render_plugin_info = self.get_plugin_info(split_render_job=True) + payload = self.assemble_payload( + job_info=render_job_info, + plugin_info=render_plugin_info + ) + render_job_id = self.submit(payload) + self.log.info("Render job id: %s", render_job_id) def process_submission(self): """Process data for submission. diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index af341ca8e8..82f6876970 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -6,12 +6,15 @@ import getpass from datetime import datetime import pyblish.api -from openpype.pipeline import legacy_io +from openpype.pipeline import legacy_io, OpenPypePyblishPluginMixin from openpype.tests.lib import is_in_tests from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo -from openpype.lib import is_running_from_build - +from openpype.lib import ( + is_running_from_build, + BoolDef, + NumberDef +) @attr.s class DeadlinePluginInfo(): @@ -20,8 +23,27 @@ class DeadlinePluginInfo(): Version = attr.ib(default=None) IgnoreInputs = attr.ib(default=True) +@attr.s +class ArnoldRenderDeadlinePluginInfo(): + InputFile = attr.ib(default=None) + Verbose = attr.ib(default=4) -class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): + +@attr.s +class MantraRenderDeadlinePluginInfo(): + SceneFile = attr.ib(default=None) + Version = attr.ib(default=None) + + +@attr.s +class VrayRenderPluginInfo(): + InputFilename = attr.ib(default=None) + + +class HoudiniSubmitDeadline( + abstract_submit_deadline.AbstractSubmitDeadline, + OpenPypePyblishPluginMixin +): """Submit Solaris USD Render ROPs to Deadline. Renders are submitted to a Deadline Web Service as @@ -46,21 +68,117 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): targets = ["local"] use_published = True - def get_job_info(self): - job_info = DeadlineJobInfo(Plugin="Houdini") + # presets + priority = 50 + chunk_size = 1 + export_priority = 50 + export_chunk_size = 10 + group = "" + export_group = "" + department = "" + limit_groups = {} + env_allowed_keys = [] + env_search_replace_values = {} + + @classmethod + def apply_settings(cls, project_settings, system_settings): + settings = project_settings["deadline"]["publish"]["HoudiniSubmitDeadline"] # noqa + + # Take some defaults from settings + cls.use_published = settings.get( + "use_published", cls.use_published + ) + cls.priority = settings.get( + "priority", cls.priority + ) + cls.export_priority = settings.get( + "export_priority", cls.export_priority + ) + cls.chunk_size = settings.get("chunk_size", cls.chunk_size) + cls.export_chunk_size = settings.get( + "export_chunk_size", cls.export_chunk_size + ) + cls.group = settings.get("group", cls.group) + cls.export_group = settings.get("export_group", cls.export_group) + cls.department = settings.get("department", cls.department) + cls.env_allowed_keys = settings.get("env_allowed_keys", cls.env_allowed_keys) + cls.env_search_replace_values = settings.get( + "env_search_replace_values", cls.env_allowed_keys + ) + + @classmethod + def get_attribute_defs(cls): + return [ + NumberDef( + "priority", + label="Priority", + default=cls.priority, + decimals=0 + ), + NumberDef( + "chunk", + label="Frames Per Task", + default=cls.chunk_size, + decimals=0, + minimum=1, + maximum=1000 + ), + NumberDef( + "export_priority", + label="Export Priority", + default=cls.priority, + decimals=0 + ), + NumberDef( + "export_chunk", + label="Export Frames Per Task", + default=cls.export_chunk_size, + decimals=0, + minimum=1, + maximum=1000 + ), + BoolDef( + "suspend_publish", + default=False, + label="Suspend publish" + ) + ] + + def get_job_info(self, split_render_job=False, export_job=False, dependency_job_ids=None): instance = self._instance context = instance.context + attribute_values = self.get_attr_values_from_data(instance.data) + + if split_render_job and not export_job: + # Convert from family to Deadline plugin name + # i.e., arnold_rop -> Arnold + plugin = instance.data.get("family").replace("_rop", "").capitalize() + else: + plugin = "Houdini" + + job_info = DeadlineJobInfo(Plugin=plugin) + filepath = context.data["currentFile"] filename = os.path.basename(filepath) - job_info.Name = "{} - {}".format(filename, instance.name) job_info.BatchName = filename - job_info.Plugin = "Houdini" + job_info.UserName = context.data.get( "deadlineUser", getpass.getuser()) + if split_render_job and export_job: + job_info.Priority = attribute_values.get( + "export_priority", self.export_priority + ) + else: + job_info.Priority = attribute_values.get( + "priority", self.priority + ) + + job_info.Department = self.department + if is_in_tests(): job_info.BatchName += datetime.now().strftime("%d%m%Y%H%M%S") @@ -72,9 +190,23 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): ) job_info.Frames = frames + # Make sure we make job frame dependent so render tasks pick up a soon + # as export tasks are done + if split_render_job and not export_job: + job_info.IsFrameDependent = True + job_info.Pool = instance.data.get("primaryPool") job_info.SecondaryPool = instance.data.get("secondaryPool") - job_info.ChunkSize = instance.data.get("chunkSize", 10) + job_info.Group = self.group + if split_render_job and export_job: + job_info.ChunkSize = attribute_values.get( + "export_chunk", self.export_chunk_size + ) + else: + job_info.ChunkSize = attribute_values.get( + "chunk", self.chunk_size + ) + job_info.Comment = context.data.get("comment") keys = [ @@ -98,8 +230,19 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): if self._instance.context.data.get("deadlinePassMongoUrl"): keys.append("OPENPYPE_MONGO") + # add allowed keys from preset if any + if self.env_allowed_keys: + keys += self.env_allowed_keys + environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **legacy_io.Session) + + # finally search replace in values of any key + if self.env_search_replace_values: + for key, value in environment.items(): + for _k, _v in self.env_search_replace_values.items(): + environment[key] = value.replace(_k, _v) + for key in keys: value = environment.get(key) if value: @@ -114,23 +257,49 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): job_info.OutputDirectory += dirname.replace("\\", "/") job_info.OutputFilename += fname + # Add dependencies if given + if dependency_job_ids: + job_info.JobDependencies = ",".join(dependency_job_ids) + return job_info - def get_plugin_info(self): + def get_plugin_info(self, split_render_job=False): instance = self._instance context = instance.context - # Output driver to render - driver = hou.node(instance.data["instance_node"]) hou_major_minor = hou.applicationVersionString().rsplit(".", 1)[0] - plugin_info = DeadlinePluginInfo( - SceneFile=context.data["currentFile"], - OutputDriver=driver.path(), - Version=hou_major_minor, - IgnoreInputs=True - ) + # Output driver to render + if split_render_job: + family = instance.data.get("family") + if family == "arnold_rop": + plugin_info = ArnoldRenderDeadlinePluginInfo( + InputFile=instance.data["ifdFile"] + ) + elif family == "mantra_rop": + plugin_info = MantraRenderDeadlinePluginInfo( + SceneFile=instance.data["ifdFile"], + Version=hou_major_minor, + ) + elif family == "vray_rop": + plugin_info = VrayRenderPluginInfo( + InputFilename=instance.data["ifdFile"], + ) + else: + self.log.error( + "Family %s not supported yet to split export and render job", + family + ) + return + else: + driver = hou.node(instance.data["instance_node"]) + plugin_info = DeadlinePluginInfo( + SceneFile=context.data["currentFile"], + OutputDriver=driver.path(), + Version=hou_major_minor, + IgnoreInputs=True + ) return attr.asdict(plugin_info) From fa261c6a3269815575824dfd035e8424195ecbec Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 7 Aug 2023 18:23:36 +0200 Subject: [PATCH 012/690] Add way to query export parm from Houdini and fix output parm --- openpype/hosts/houdini/api/lib.py | 121 ++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 15 deletions(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index b03f8c8fc1..b1673b746d 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -104,8 +104,8 @@ def get_id_required_nodes(): return list(nodes) -def get_output_parameter(node): - """Return the render output parameter name of the given node +def get_export_parameter(node): + """Return the export output parameter of the given node Example: root = hou.node("/obj") @@ -120,21 +120,112 @@ def get_output_parameter(node): hou.Parm """ + node_type = node.type().description() - node_type = node.type().name() - if node_type == "geometry": - return node.parm("sopoutput") - elif node_type == "alembic": - return node.parm("filename") - elif node_type == "comp": - return node.parm("copoutput") - elif node_type == "opengl": - return node.parm("picture") - elif node_type == "arnold": - if node.evalParm("ar_ass_export_enable"): - return node.parm("ar_ass_file") - elif node_type == "Redshift_Proxy_Output": + # Ensures the proper Take is selected for each ROP to retrieve the correct ifd + try: + rop_take = hou.takes.findTake(node.parm("take").eval()) + if rop_take is not None: + hou.takes.setCurrentTake(rop_take) + except AttributeError: + # hou object doesn't always have the 'takes' attribute + pass + + if node_type == "Mantra" and node.parm("soho_outputmode").eval(): + return node.parm("soho_diskfile") + elif node_type == "Alfred": + return node.parm("alf_diskfile") + elif (node_type == "RenderMan" or node_type == "RenderMan RIS"): + pre_ris22 = node.parm("rib_outputmode") and node.parm("rib_outputmode").eval() + ris22 = node.parm("diskfile") and node.parm("diskfile").eval() + if pre_ris22 or ris22: + return node.parm("soho_diskfile") + elif node_type == "Redshift" and node.parm("RS_archive_enable").eval(): return node.parm("RS_archive_file") + elif node_type == "Wedge" and node.parm("driver").eval(): + return get_export_parameter(node.node(node.parm("driver").eval())) + elif node_type == "Arnold": + return node.parm("ar_ass_file") + elif node_type == "Alembic" and node.parm("use_sop_path").eval(): + return node.parm("sop_path") + elif node_type == "Shotgun Mantra" and node.parm("soho_outputmode").eval(): + return node.parm("sgtk_soho_diskfile") + elif node_type == "Shotgun Alembic" and node.parm("use_sop_path").eval(): + return node.parm("sop_path") + elif node.type().nameWithCategory() == "Driver/vray_renderer": + return node.parm("render_export_filepath") + + raise TypeError("Node type '%s' not supported" % node_type) + + +def get_output_parameter(node): + """Return the render output parameter of the given node + + Example: + root = hou.node("/obj") + my_alembic_node = root.createNode("alembic") + get_output_parameter(my_alembic_node) + # Result: "output" + + Args: + node(hou.Node): node instance + + Returns: + hou.Parm + + """ + node_type = node.type().description() + category = node.type().category().name() + + # Figure out which type of node is being rendered + if node_type == "Geometry" or node_type == "Filmbox FBX" or (node_type == "ROP Output Driver" and category == "Sop"): + return node.parm("sopoutput") + elif node_type == "Composite": + return node.parm("copoutput") + elif node_type == "Channel": + return node.parm("chopoutput") + elif node_type == "Dynamics" or (node_type == "ROP Output Driver" and category == "Dop"): + return node.parm("dopoutput") + elif node_type == "Alfred": + return node.parm("alf_diskfile") + elif node_type == "RenderMan" or node_type == "RenderMan RIS": + return node.parm("ri_display") + elif node_type == "Redshift": + return node.parm("RS_returnmePrefix") + elif node_type == "Mantra": + return node.parm("vm_picture") + elif node_type == "Wedge": + driver_node = node.node(node.parm("driver").eval()) + if driver_node: + return get_output_parameter(driver_node) + elif node_type == "Arnold": + return node.parm("ar_picture") + elif node_type == "HQueue Simulation": + inner_node = node.node(node.parm("hq_driver").eval()) + if inner_node: + return get_output_parameter(inner_node) + elif node_type == "ROP Alembic Output": + return node.parm("filename") + elif node_type == "Redshift": + return node.parm("RS_returnmePrefix") + elif node_type == "Alembic": + return node.parm("filename") + elif node_type == "Shotgun Mantra": + return node.parm("sgtk_vm_picture") + elif node_type == "Shotgun Alembic": + return node.parm("filename") + elif node_type == "Bake Texture": + return node.parm("vm_uvoutputpicture1") + elif node_type == "OpenGL": + return node.parm("picture") + elif node_type == "Octane": + return node.parm("HO_img_fileName") + elif node_type == "Fetch": + inner_node = node.node(node.parm("source").eval()) + if inner_node: + return get_output_parameter(inner_node) + elif node.type().nameWithCategory() == "Driver/vray_renderer": + return node.parm("SettingsOutput_img_file_path") raise TypeError("Node type '%s' not supported" % node_type) From 2b2ad8f1ed8ff4922fa9216983958e79ea93e26a Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 7 Aug 2023 18:30:12 +0200 Subject: [PATCH 013/690] Add missing pre create attr for splitting render job to Mantra ROP --- openpype/hosts/houdini/plugins/create/create_mantra_rop.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py index 41311a1e30..0601124ac0 100644 --- a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py @@ -90,6 +90,9 @@ class CreateMantraROP(plugin.HoudiniCreator): BoolDef("farm", label="Submitting to Farm", default=True), + BoolDef("export_job", + label="Split export and render jobs", + default=self.export_job), EnumDef("image_format", image_format_enum, default="exr", From aab913acbc7f33e0c79d2a966a52b22fd99c54fc Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Mon, 7 Aug 2023 18:32:09 +0200 Subject: [PATCH 014/690] Add Houdini deadline submission settings --- .../defaults/project_settings/deadline.json | 15 +++ .../schema_project_deadline.json | 91 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index 1b8c8397d7..d088ef5747 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -19,6 +19,21 @@ "deadline" ] }, + "HoudiniSubmitDeadline": { + "enabled": true, + "active": true, + "use_published": true, + "priority": 50, + "render_chunk_size": 1, + "group": "none", + "export_priority": 50, + "export_chunk_size": 10, + "export_group": "none", + "department": "", + "env_allowed_keys": [], + "env_search_replace_values": {}, + "limit_groups": {} + }, "MayaSubmitDeadline": { "enabled": true, "optional": false, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 6d59b5a92b..dfbcd8ef27 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -89,6 +89,97 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "HoudiniSubmitDeadline", + "label": "Houdini Submit to Deadline", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, + { + "type": "splitter" + }, + { + "type": "boolean", + "key": "use_published", + "label": "Use Published scene" + }, + { + "type": "number", + "key": "priority", + "label": "Priority" + }, + { + "type": "number", + "key": "render_chunk_size", + "label": "Render Chunk Size" + }, + { + "type": "text", + "key": "group", + "label": "Group" + }, + { + "type": "splitter" + }, + { + "type": "number", + "key": "export_priority", + "label": "Export Priority" + }, + { + "type": "number", + "key": "export_chunk_size", + "label": "Export Chunk Size" + }, + { + "type": "text", + "key": "export_group", + "label": "Export Group" + }, + { + "type": "splitter" + }, + { + "type": "text", + "key": "department", + "label": "Department" + }, + { + "type": "list", + "key": "env_allowed_keys", + "object_type": "text", + "label": "Allowed environment keys" + }, + { + "type": "dict-modifiable", + "key": "env_search_replace_values", + "label": "Search & replace in environment values", + "object_type": { + "type": "text" + } + }, + { + "type": "dict-modifiable", + "key": "limit_groups", + "label": "Limit Groups", + "object_type": { + "type": "list", + "object_type": "text" + } + } + ] + }, { "type": "dict", "collapsible": true, From 33dff766fe6777ff5e801beebe2b366ed5122c20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 18:51:53 +0200 Subject: [PATCH 015/690] Shush Hound --- openpype/hosts/houdini/api/lib.py | 12 ++++++++---- .../houdini/plugins/create/create_arnold_rop.py | 9 +++++---- .../houdini/plugins/create/create_mantra_rop.py | 9 +++++---- .../hosts/houdini/plugins/create/create_vray_rop.py | 9 +++++---- .../houdini/plugins/publish/collect_arnold_rop.py | 10 +++++++--- .../houdini/plugins/publish/collect_mantra_rop.py | 10 +++++++--- .../houdini/plugins/publish/collect_vray_rop.py | 8 ++++++-- .../publish/submit_houdini_render_deadline.py | 11 ++++++++--- 8 files changed, 51 insertions(+), 27 deletions(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index b1673b746d..94c4529ae2 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -122,7 +122,8 @@ def get_export_parameter(node): """ node_type = node.type().description() - # Ensures the proper Take is selected for each ROP to retrieve the correct ifd + # Ensures the proper Take is selected for each ROP to retrieve the correct + # ifd try: rop_take = hou.takes.findTake(node.parm("take").eval()) if rop_take is not None: @@ -136,7 +137,8 @@ def get_export_parameter(node): elif node_type == "Alfred": return node.parm("alf_diskfile") elif (node_type == "RenderMan" or node_type == "RenderMan RIS"): - pre_ris22 = node.parm("rib_outputmode") and node.parm("rib_outputmode").eval() + pre_ris22 = node.parm("rib_outputmode") and \ + node.parm("rib_outputmode").eval() ris22 = node.parm("diskfile") and node.parm("diskfile").eval() if pre_ris22 or ris22: return node.parm("soho_diskfile") @@ -178,13 +180,15 @@ def get_output_parameter(node): category = node.type().category().name() # Figure out which type of node is being rendered - if node_type == "Geometry" or node_type == "Filmbox FBX" or (node_type == "ROP Output Driver" and category == "Sop"): + if node_type == "Geometry" or node_type == "Filmbox FBX" or \ + (node_type == "ROP Output Driver" and category == "Sop"): return node.parm("sopoutput") elif node_type == "Composite": return node.parm("copoutput") elif node_type == "Channel": return node.parm("chopoutput") - elif node_type == "Dynamics" or (node_type == "ROP Output Driver" and category == "Dop"): + elif node_type == "Dynamics" or \ + (node_type == "ROP Output Driver" and category == "Dop"): return node.parm("dopoutput") elif node_type == "Alfred": return node.parm("alf_diskfile") diff --git a/openpype/hosts/houdini/plugins/create/create_arnold_rop.py b/openpype/hosts/houdini/plugins/create/create_arnold_rop.py index d19795d3a9..b2f04b64ec 100644 --- a/openpype/hosts/houdini/plugins/create/create_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_arnold_rop.py @@ -53,10 +53,11 @@ class CreateArnoldRop(plugin.HoudiniCreator): } if pre_create_data.get("export_job"): - ass_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.ass".format( - export_dir=hou.text.expandString("$HIP/pyblish/ass/"), - subset_name=subset_name, - ) + ass_filepath = \ + "{export_dir}{subset_name}/{subset_name}.$F4.ass".format( + export_dir=hou.text.expandString("$HIP/pyblish/ass/"), + subset_name=subset_name, + ) parms["ar_ass_export_enable"] = 1 parms["ar_ass_file"] = ass_filepath diff --git a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py index 0601124ac0..62074fe432 100644 --- a/openpype/hosts/houdini/plugins/create/create_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_mantra_rop.py @@ -49,10 +49,11 @@ class CreateMantraROP(plugin.HoudiniCreator): } if pre_create_data.get("export_job"): - ifd_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.ifd".format( - export_dir=hou.text.expandString("$HIP/pyblish/ifd/"), - subset_name=subset_name, - ) + ifd_filepath = \ + "{export_dir}{subset_name}/{subset_name}.$F4.ifd".format( + export_dir=hou.text.expandString("$HIP/pyblish/ifd/"), + subset_name=subset_name, + ) parms["soho_outputmode"] = 1 parms["soho_diskfile"] = ifd_filepath diff --git a/openpype/hosts/houdini/plugins/create/create_vray_rop.py b/openpype/hosts/houdini/plugins/create/create_vray_rop.py index 29fab0c60c..de3cfc3858 100644 --- a/openpype/hosts/houdini/plugins/create/create_vray_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_vray_rop.py @@ -58,10 +58,11 @@ class CreateVrayROP(plugin.HoudiniCreator): } if pre_create_data.get("export_job"): - scene_filepath = "{export_dir}{subset_name}/{subset_name}.$F4.vrscene".format( - export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), - subset_name=subset_name, - ) + scene_filepath = \ + "{export_dir}{subset_name}/{subset_name}.$F4.vrscene".format( + export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), + subset_name=subset_name, + ) # TODO: don't have VRay to check the names of these parms["render_export_mode"] = 1 parms["render_export_filepath"] = scene_filepath diff --git a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py index 063dd728e1..4af1d80a2d 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -38,18 +38,22 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "ar_picture") render_products = [] - # Store whether we are splitting the render job in an export + render + # Store whether we are splitting the render job (export + render) export_job = bool(rop.parm("ar_ass_export_enable").eval()) instance.data["exportJob"] = export_job export_prefix = None export_products = [] if export_job: - export_prefix = evalParmNoFrame(rop, "ar_ass_file", pad_character="0") + export_prefix = evalParmNoFrame( + rop, "ar_ass_file", pad_character="0" + ) beauty_export_product = self.get_render_product_name( prefix=export_prefix, suffix=None) export_products.append(beauty_export_product) - self.log.debug("Found export product: {}".format(beauty_export_product)) + self.log.debug( + "Found export product: {}".format(beauty_export_product) + ) instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) diff --git a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py index b235e2c110..7385a87679 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -42,18 +42,22 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): default_prefix = evalParmNoFrame(rop, "vm_picture") render_products = [] - # Store whether we are splitting the render job in an export + render + # Store whether we are splitting the render job (export + render) export_job = bool(rop.parm("soho_outputmode").eval()) instance.data["exportJob"] = export_job export_prefix = None export_products = [] if export_job: - export_prefix = evalParmNoFrame(rop, "soho_diskfile", pad_character="0") + export_prefix = evalParmNoFrame( + rop, "soho_diskfile", pad_character="0" + ) beauty_export_product = self.get_render_product_name( prefix=export_prefix, suffix=None) export_products.append(beauty_export_product) - self.log.debug("Found export product: {}".format(beauty_export_product)) + self.log.debug( + "Found export product: {}".format(beauty_export_product) + ) instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index 89a7c8bf72..4259f19eb2 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -50,12 +50,16 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): export_prefix = None export_products = [] if export_job: - export_prefix = evalParmNoFrame(rop, "render_export_filepath", pad_character="0") + export_prefix = evalParmNoFrame( + rop, "render_export_filepath", pad_character="0" + ) beauty_export_product = self.get_render_product_name( prefix=export_prefix, suffix=None) export_products.append(beauty_export_product) - self.log.debug("Found export product: {}".format(beauty_export_product)) + self.log.debug( + "Found export product: {}".format(beauty_export_product) + ) instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 82f6876970..d7d5ed906b 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -144,7 +144,12 @@ class HoudiniSubmitDeadline( ) ] - def get_job_info(self, split_render_job=False, export_job=False, dependency_job_ids=None): + def get_job_info( + self, + split_render_job=False, + export_job=False, + dependency_job_ids=None + ): instance = self._instance context = instance.context @@ -154,7 +159,7 @@ class HoudiniSubmitDeadline( if split_render_job and not export_job: # Convert from family to Deadline plugin name # i.e., arnold_rop -> Arnold - plugin = instance.data.get("family").replace("_rop", "").capitalize() + plugin = instance.data["family"].replace("_rop", "").capitalize() else: plugin = "Houdini" @@ -288,7 +293,7 @@ class HoudiniSubmitDeadline( ) else: self.log.error( - "Family %s not supported yet to split export and render job", + "Family '%s' not supported yet to split render job", family ) return From 2f62dd74ab9aed69f40d21b0ed3cc163c15d7bfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 18:59:16 +0200 Subject: [PATCH 016/690] Shush Hound --- .../modules/deadline/abstract_submit_deadline.py | 8 +++++--- .../publish/submit_houdini_render_deadline.py | 15 +++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index 56d8afbe3e..ae251f39b9 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -448,10 +448,12 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin, # Check whether we are splitting render job in export + render # and if so, create a separate task for the render - # TODO: Find a cleaner way so `get_job_info` can take extra args depending - # on host + # TODO: Find a cleaner way so `get_job_info` can take extra args + # depending on host export_job = instance.data["exportJob"] - self.job_info = self.get_job_info(split_render_job=export_job, export_job=True) + self.job_info = self.get_job_info( + split_render_job=export_job, export_job=True + ) self.plugin_info = self.get_plugin_info() self.aux_files = self.get_aux_files() diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d7d5ed906b..e5cd6467f7 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -23,6 +23,7 @@ class DeadlinePluginInfo(): Version = attr.ib(default=None) IgnoreInputs = attr.ib(default=True) + @attr.s class ArnoldRenderDeadlinePluginInfo(): InputFile = attr.ib(default=None) @@ -101,7 +102,9 @@ class HoudiniSubmitDeadline( cls.group = settings.get("group", cls.group) cls.export_group = settings.get("export_group", cls.export_group) cls.department = settings.get("department", cls.department) - cls.env_allowed_keys = settings.get("env_allowed_keys", cls.env_allowed_keys) + cls.env_allowed_keys = settings.get( + "env_allowed_keys", cls.env_allowed_keys + ) cls.env_search_replace_values = settings.get( "env_search_replace_values", cls.env_allowed_keys ) @@ -145,11 +148,11 @@ class HoudiniSubmitDeadline( ] def get_job_info( - self, - split_render_job=False, - export_job=False, - dependency_job_ids=None - ): + self, + split_render_job=False, + export_job=False, + dependency_job_ids=None + ): instance = self._instance context = instance.context From a0987388c9a3202e34a76f5057528f5f9f7d63ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 22:18:13 +0200 Subject: [PATCH 017/690] Revert "Add Houdini deadline submission settings" This reverts commit aab913acbc7f33e0c79d2a966a52b22fd99c54fc. --- .../defaults/project_settings/deadline.json | 15 --- .../schema_project_deadline.json | 91 ------------------- 2 files changed, 106 deletions(-) diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index d088ef5747..1b8c8397d7 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -19,21 +19,6 @@ "deadline" ] }, - "HoudiniSubmitDeadline": { - "enabled": true, - "active": true, - "use_published": true, - "priority": 50, - "render_chunk_size": 1, - "group": "none", - "export_priority": 50, - "export_chunk_size": 10, - "export_group": "none", - "department": "", - "env_allowed_keys": [], - "env_search_replace_values": {}, - "limit_groups": {} - }, "MayaSubmitDeadline": { "enabled": true, "optional": false, diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index dfbcd8ef27..6d59b5a92b 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -89,97 +89,6 @@ } ] }, - { - "type": "dict", - "collapsible": true, - "key": "HoudiniSubmitDeadline", - "label": "Houdini Submit to Deadline", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "active", - "label": "Active" - }, - { - "type": "splitter" - }, - { - "type": "boolean", - "key": "use_published", - "label": "Use Published scene" - }, - { - "type": "number", - "key": "priority", - "label": "Priority" - }, - { - "type": "number", - "key": "render_chunk_size", - "label": "Render Chunk Size" - }, - { - "type": "text", - "key": "group", - "label": "Group" - }, - { - "type": "splitter" - }, - { - "type": "number", - "key": "export_priority", - "label": "Export Priority" - }, - { - "type": "number", - "key": "export_chunk_size", - "label": "Export Chunk Size" - }, - { - "type": "text", - "key": "export_group", - "label": "Export Group" - }, - { - "type": "splitter" - }, - { - "type": "text", - "key": "department", - "label": "Department" - }, - { - "type": "list", - "key": "env_allowed_keys", - "object_type": "text", - "label": "Allowed environment keys" - }, - { - "type": "dict-modifiable", - "key": "env_search_replace_values", - "label": "Search & replace in environment values", - "object_type": { - "type": "text" - } - }, - { - "type": "dict-modifiable", - "key": "limit_groups", - "label": "Limit Groups", - "object_type": { - "type": "list", - "object_type": "text" - } - } - ] - }, { "type": "dict", "collapsible": true, From d309df3b49b2d20cdac28a4150f1546f83ee5a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 22:22:31 +0200 Subject: [PATCH 018/690] Remove Houdini Deadline settings as it's not relevant to feature --- .../publish/submit_houdini_render_deadline.py | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index e5cd6467f7..fdfc66b2c0 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -81,34 +81,6 @@ class HoudiniSubmitDeadline( env_allowed_keys = [] env_search_replace_values = {} - @classmethod - def apply_settings(cls, project_settings, system_settings): - settings = project_settings["deadline"]["publish"]["HoudiniSubmitDeadline"] # noqa - - # Take some defaults from settings - cls.use_published = settings.get( - "use_published", cls.use_published - ) - cls.priority = settings.get( - "priority", cls.priority - ) - cls.export_priority = settings.get( - "export_priority", cls.export_priority - ) - cls.chunk_size = settings.get("chunk_size", cls.chunk_size) - cls.export_chunk_size = settings.get( - "export_chunk_size", cls.export_chunk_size - ) - cls.group = settings.get("group", cls.group) - cls.export_group = settings.get("export_group", cls.export_group) - cls.department = settings.get("department", cls.department) - cls.env_allowed_keys = settings.get( - "env_allowed_keys", cls.env_allowed_keys - ) - cls.env_search_replace_values = settings.get( - "env_search_replace_values", cls.env_allowed_keys - ) - @classmethod def get_attribute_defs(cls): return [ From 20583173c663e84b84e0512692cf1495f51fb1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 22:26:02 +0200 Subject: [PATCH 019/690] Remove some other noise from PR feature --- .../publish/submit_houdini_render_deadline.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index fdfc66b2c0..d6c658944a 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -76,10 +76,6 @@ class HoudiniSubmitDeadline( export_chunk_size = 10 group = "" export_group = "" - department = "" - limit_groups = {} - env_allowed_keys = [] - env_search_replace_values = {} @classmethod def get_attribute_defs(cls): @@ -157,8 +153,6 @@ class HoudiniSubmitDeadline( "priority", self.priority ) - job_info.Department = self.department - if is_in_tests(): job_info.BatchName += datetime.now().strftime("%d%m%Y%H%M%S") @@ -210,18 +204,9 @@ class HoudiniSubmitDeadline( if self._instance.context.data.get("deadlinePassMongoUrl"): keys.append("OPENPYPE_MONGO") - # add allowed keys from preset if any - if self.env_allowed_keys: - keys += self.env_allowed_keys - environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **legacy_io.Session) - # finally search replace in values of any key - if self.env_search_replace_values: - for key, value in environment.items(): - for _k, _v in self.env_search_replace_values.items(): - environment[key] = value.replace(_k, _v) for key in keys: value = environment.get(key) From f58c4de0d4a284867eb0fb43b3d235abff9f26ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 22:44:45 +0200 Subject: [PATCH 020/690] Move some of the logic to Houdini submitter so abstract functions are a bit more generic --- .../deadline/abstract_submit_deadline.py | 19 +++++------- .../publish/submit_houdini_render_deadline.py | 30 +++++++++++-------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/openpype/modules/deadline/abstract_submit_deadline.py b/openpype/modules/deadline/abstract_submit_deadline.py index ae251f39b9..dddb4400c1 100644 --- a/openpype/modules/deadline/abstract_submit_deadline.py +++ b/openpype/modules/deadline/abstract_submit_deadline.py @@ -446,25 +446,20 @@ class AbstractSubmitDeadline(pyblish.api.InstancePlugin, self.scene_path = file_path self.log.info("Using {} for render/export.".format(file_path)) - # Check whether we are splitting render job in export + render - # and if so, create a separate task for the render - # TODO: Find a cleaner way so `get_job_info` can take extra args - # depending on host - export_job = instance.data["exportJob"] - self.job_info = self.get_job_info( - split_render_job=export_job, export_job=True - ) + self.job_info = self.get_job_info() self.plugin_info = self.get_plugin_info() self.aux_files = self.get_aux_files() job_id = self.process_submission() + self.log.info("Submitted job to Deadline: {}.".format(job_id)) + + # TODO: Find a way that's more generic and not render type specific + export_job = instance.data["exportJob"] if export_job: self.log.info("Splitting export and render in two jobs") self.log.info("Export job id: %s", job_id) - render_job_info = self.get_job_info( - split_render_job=True, dependency_job_ids=[job_id] - ) - render_plugin_info = self.get_plugin_info(split_render_job=True) + render_job_info = self.get_job_info(dependency_job_ids=[job_id]) + render_plugin_info = self.get_plugin_info(job_type="render") payload = self.assemble_payload( job_info=render_job_info, plugin_info=render_plugin_info diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index d6c658944a..83f6e81485 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -115,19 +115,24 @@ class HoudiniSubmitDeadline( ) ] - def get_job_info( - self, - split_render_job=False, - export_job=False, - dependency_job_ids=None - ): + def get_job_info(self, dependency_job_ids=None): instance = self._instance context = instance.context attribute_values = self.get_attr_values_from_data(instance.data) - if split_render_job and not export_job: + # Whether Deadline render submission is being split in two + # (extract + render) + split_render_job = instance.data["exportJob"] + + # If there's some dependency job ids we can assume this is a render job + # and not an export job + is_export_job = True + if dependency_job_ids: + is_export_job = False + + if split_render_job and not is_export_job: # Convert from family to Deadline plugin name # i.e., arnold_rop -> Arnold plugin = instance.data["family"].replace("_rop", "").capitalize() @@ -144,7 +149,7 @@ class HoudiniSubmitDeadline( job_info.UserName = context.data.get( "deadlineUser", getpass.getuser()) - if split_render_job and export_job: + if split_render_job and is_export_job: job_info.Priority = attribute_values.get( "export_priority", self.export_priority ) @@ -166,13 +171,13 @@ class HoudiniSubmitDeadline( # Make sure we make job frame dependent so render tasks pick up a soon # as export tasks are done - if split_render_job and not export_job: + if split_render_job and not is_export_job: job_info.IsFrameDependent = True job_info.Pool = instance.data.get("primaryPool") job_info.SecondaryPool = instance.data.get("secondaryPool") job_info.Group = self.group - if split_render_job and export_job: + if split_render_job and is_export_job: job_info.ChunkSize = attribute_values.get( "export_chunk", self.export_chunk_size ) @@ -207,7 +212,6 @@ class HoudiniSubmitDeadline( environment = dict({key: os.environ[key] for key in keys if key in os.environ}, **legacy_io.Session) - for key in keys: value = environment.get(key) if value: @@ -228,7 +232,7 @@ class HoudiniSubmitDeadline( return job_info - def get_plugin_info(self, split_render_job=False): + def get_plugin_info(self, job_type=None): instance = self._instance context = instance.context @@ -236,7 +240,7 @@ class HoudiniSubmitDeadline( hou_major_minor = hou.applicationVersionString().rsplit(".", 1)[0] # Output driver to render - if split_render_job: + if job_type == "render": family = instance.data.get("family") if family == "arnold_rop": plugin_info = ArnoldRenderDeadlinePluginInfo( From 12b2a74ea963a72737f9409f5bfd04acabb53f79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Mon, 7 Aug 2023 22:52:01 +0200 Subject: [PATCH 021/690] Fix docstring --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 83f6e81485..8434ddacd3 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -45,7 +45,7 @@ class HoudiniSubmitDeadline( abstract_submit_deadline.AbstractSubmitDeadline, OpenPypePyblishPluginMixin ): - """Submit Solaris USD Render ROPs to Deadline. + """Submit Render ROPs to Deadline. Renders are submitted to a Deadline Web Service as supplied via the environment variable AVALON_DEADLINE. From ad11a4d3d3c7ec8be0c605cf4da18deea3ab102e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabi=C3=A0=20Serra=20Arrizabalaga?= Date: Tue, 8 Aug 2023 16:08:45 +0200 Subject: [PATCH 022/690] Fix VRay submission parms --- openpype/hosts/houdini/plugins/create/create_vray_rop.py | 3 +-- openpype/hosts/houdini/plugins/publish/collect_vray_rop.py | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/houdini/plugins/create/create_vray_rop.py b/openpype/hosts/houdini/plugins/create/create_vray_rop.py index de3cfc3858..222088523a 100644 --- a/openpype/hosts/houdini/plugins/create/create_vray_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_vray_rop.py @@ -63,8 +63,7 @@ class CreateVrayROP(plugin.HoudiniCreator): export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), subset_name=subset_name, ) - # TODO: don't have VRay to check the names of these - parms["render_export_mode"] = 1 + parms["render_export_mode"] = "1" parms["render_export_filepath"] = scene_filepath if self.selected_nodes: diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index 4259f19eb2..d7d53ff566 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -44,7 +44,6 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): # TODO: add render elements if render element # Store whether we are splitting the render job in an export + render - # TODO: check names of VRay parms export_job = bool(rop.parm("render_export_mode").eval()) instance.data["exportJob"] = export_job export_prefix = None @@ -63,7 +62,7 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): instance.data["ifdFile"] = beauty_export_product instance.data["exportFiles"] = list(export_products) - beauty_product = self.get_beauty_render_product(default_prefix) + beauty_product = self.get_render_product_name(default_prefix) render_products.append(beauty_product) files_by_aov = { "RGB Color": self.generate_expected_files(instance, @@ -97,7 +96,7 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): instance.data["colorspaceDisplay"] = colorspace_data["display"] instance.data["colorspaceView"] = colorspace_data["view"] - def get_beauty_render_product(self, prefix, suffix=""): + def get_render_product_name(self, prefix, suffix=""): """Return the beauty output filename if render element enabled """ aov_parm = ".{}".format(suffix) From cb7274bf1a79d5c5d315b5ae08e7f6042c598539 Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Wed, 9 Aug 2023 15:19:24 +0200 Subject: [PATCH 023/690] Fix render_export_mode for VRay so it only exports --- openpype/hosts/houdini/plugins/create/create_vray_rop.py | 4 +++- openpype/hosts/houdini/plugins/publish/collect_vray_rop.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/plugins/create/create_vray_rop.py b/openpype/hosts/houdini/plugins/create/create_vray_rop.py index 222088523a..cd5ef2013d 100644 --- a/openpype/hosts/houdini/plugins/create/create_vray_rop.py +++ b/openpype/hosts/houdini/plugins/create/create_vray_rop.py @@ -63,7 +63,9 @@ class CreateVrayROP(plugin.HoudiniCreator): export_dir=hou.text.expandString("$HIP/pyblish/vrscene/"), subset_name=subset_name, ) - parms["render_export_mode"] = "1" + # Setting render_export_mode to "2" because that's for + # "Export only" ("1" is for "Export & Render") + parms["render_export_mode"] = "2" parms["render_export_filepath"] = scene_filepath if self.selected_nodes: diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index d7d53ff566..184c644fd6 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -44,7 +44,7 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): # TODO: add render elements if render element # Store whether we are splitting the render job in an export + render - export_job = bool(rop.parm("render_export_mode").eval()) + export_job = rop.parm("render_export_mode").eval() == "2" instance.data["exportJob"] = export_job export_prefix = None export_products = [] From bfe8f88b241e4a71f3a9aabbfda2d87087f26e38 Mon Sep 17 00:00:00 2001 From: Fabia Serra Arrizabalaga Date: Thu, 10 Aug 2023 13:43:27 +0200 Subject: [PATCH 024/690] Add SeparateFilesPerFrame attribute to Vray plugin --- .../deadline/plugins/publish/submit_houdini_render_deadline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 8434ddacd3..cc982cd2eb 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -39,6 +39,7 @@ class MantraRenderDeadlinePluginInfo(): @attr.s class VrayRenderPluginInfo(): InputFilename = attr.ib(default=None) + SeparateFilesPerFrame = attr.ib(default=True) class HoudiniSubmitDeadline( From 265dee372e8f4b99705fe7dbc5f6463241a433b6 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 12:20:53 +0200 Subject: [PATCH 025/690] Blender: Change logs to `debug` in favor of new publisher artist-facing report Note that Blender is still using old publisher currently --- .../hosts/blender/plugins/publish/extract_abc.py | 2 +- .../blender/plugins/publish/extract_abc_animation.py | 2 +- .../hosts/blender/plugins/publish/extract_blend.py | 2 +- .../plugins/publish/extract_blend_animation.py | 2 +- .../blender/plugins/publish/extract_camera_abc.py | 2 +- .../blender/plugins/publish/extract_camera_fbx.py | 2 +- .../hosts/blender/plugins/publish/extract_fbx.py | 2 +- .../blender/plugins/publish/extract_fbx_animation.py | 2 +- .../hosts/blender/plugins/publish/extract_layout.py | 2 +- .../blender/plugins/publish/extract_playblast.py | 12 +++++------- .../blender/plugins/publish/extract_thumbnail.py | 6 +++--- 11 files changed, 17 insertions(+), 19 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index f4babc94d3..f5b4c664a3 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -24,7 +24,7 @@ class ExtractABC(publish.Extractor): context = bpy.context # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") plugin.deselect_all() diff --git a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py index e141ccaa44..793e460390 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py @@ -23,7 +23,7 @@ class ExtractAnimationABC(publish.Extractor): context = bpy.context # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") plugin.deselect_all() diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index d4f26b4f3c..c8eeef7fd7 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -21,7 +21,7 @@ class ExtractBlend(publish.Extractor): filepath = os.path.join(stagingdir, filename) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") data_blocks = set() diff --git a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py index 477411b73d..661cecce81 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py @@ -21,7 +21,7 @@ class ExtractBlendAnimation(publish.Extractor): filepath = os.path.join(stagingdir, filename) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") data_blocks = set() diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py index a21a59b151..185259d987 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py @@ -24,7 +24,7 @@ class ExtractCameraABC(publish.Extractor): context = bpy.context # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") plugin.deselect_all() diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py index 315994140e..a541f5b375 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py @@ -21,7 +21,7 @@ class ExtractCamera(publish.Extractor): filepath = os.path.join(stagingdir, filename) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") plugin.deselect_all() diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx.py b/openpype/hosts/blender/plugins/publish/extract_fbx.py index 0ad797c226..f2ce117dcd 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx.py @@ -22,7 +22,7 @@ class ExtractFBX(publish.Extractor): filepath = os.path.join(stagingdir, filename) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") plugin.deselect_all() diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py index 062b42e99d..5fe5931e65 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py @@ -23,7 +23,7 @@ class ExtractAnimationFBX(publish.Extractor): stagingdir = self.staging_dir(instance) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") # The first collection object in the instance is taken, as there # should be only one that contains the asset group. diff --git a/openpype/hosts/blender/plugins/publish/extract_layout.py b/openpype/hosts/blender/plugins/publish/extract_layout.py index f2d04f1178..05f86b8370 100644 --- a/openpype/hosts/blender/plugins/publish/extract_layout.py +++ b/openpype/hosts/blender/plugins/publish/extract_layout.py @@ -117,7 +117,7 @@ class ExtractLayout(publish.Extractor): stagingdir = self.staging_dir(instance) # Perform extraction - self.log.info("Performing extraction..") + self.log.debug("Performing extraction..") if "representations" not in instance.data: instance.data["representations"] = [] diff --git a/openpype/hosts/blender/plugins/publish/extract_playblast.py b/openpype/hosts/blender/plugins/publish/extract_playblast.py index 196e75b8cc..b0099cce85 100644 --- a/openpype/hosts/blender/plugins/publish/extract_playblast.py +++ b/openpype/hosts/blender/plugins/publish/extract_playblast.py @@ -24,9 +24,7 @@ class ExtractPlayblast(publish.Extractor): order = pyblish.api.ExtractorOrder + 0.01 def process(self, instance): - self.log.info("Extracting capture..") - - self.log.info(instance.data) + self.log.debug("Extracting capture..") # get scene fps fps = instance.data.get("fps") @@ -34,14 +32,14 @@ class ExtractPlayblast(publish.Extractor): fps = bpy.context.scene.render.fps instance.data["fps"] = fps - self.log.info(f"fps: {fps}") + self.log.debug(f"fps: {fps}") # If start and end frames cannot be determined, # get them from Blender timeline. start = instance.data.get("frameStart", bpy.context.scene.frame_start) end = instance.data.get("frameEnd", bpy.context.scene.frame_end) - self.log.info(f"start: {start}, end: {end}") + self.log.debug(f"start: {start}, end: {end}") assert end > start, "Invalid time range !" # get cameras @@ -55,7 +53,7 @@ class ExtractPlayblast(publish.Extractor): filename = instance.name path = os.path.join(stagingdir, filename) - self.log.info(f"Outputting images to {path}") + self.log.debug(f"Outputting images to {path}") project_settings = instance.context.data["project_settings"]["blender"] presets = project_settings["publish"]["ExtractPlayblast"]["presets"] @@ -100,7 +98,7 @@ class ExtractPlayblast(publish.Extractor): frame_collection = collections[0] - self.log.info(f"We found collection of interest {frame_collection}") + self.log.debug(f"Found collection of interest {frame_collection}") instance.data.setdefault("representations", []) diff --git a/openpype/hosts/blender/plugins/publish/extract_thumbnail.py b/openpype/hosts/blender/plugins/publish/extract_thumbnail.py index 65c3627375..52e5d98fc4 100644 --- a/openpype/hosts/blender/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/blender/plugins/publish/extract_thumbnail.py @@ -24,13 +24,13 @@ class ExtractThumbnail(publish.Extractor): presets = {} def process(self, instance): - self.log.info("Extracting capture..") + self.log.debug("Extracting capture..") stagingdir = self.staging_dir(instance) filename = instance.name path = os.path.join(stagingdir, filename) - self.log.info(f"Outputting images to {path}") + self.log.debug(f"Outputting images to {path}") camera = instance.data.get("review_camera", "AUTO") start = instance.data.get("frameStart", bpy.context.scene.frame_start) @@ -61,7 +61,7 @@ class ExtractThumbnail(publish.Extractor): thumbnail = os.path.basename(self._fix_output_path(path)) - self.log.info(f"thumbnail: {thumbnail}") + self.log.debug(f"thumbnail: {thumbnail}") instance.data.setdefault("representations", []) From eadce2ce29f0df9da2a1b1c740e10bed4fa8a95e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 12:22:24 +0200 Subject: [PATCH 026/690] Fusion: Create Saver fix redeclaration of `default_variants` --- openpype/hosts/fusion/plugins/create/create_saver.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index 04898d0a45..27ff590cb3 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -30,10 +30,6 @@ class CreateSaver(NewCreator): instance_attributes = [ "reviewable" ] - default_variants = [ - "Main", - "Mask" - ] # TODO: This should be renamed together with Nuke so it is aligned temp_rendering_path_template = ( From 5d221cf476000483a307fa212dd0d1b5ce0c618e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 12:23:17 +0200 Subject: [PATCH 027/690] Fusion: Fix saver being created in incorrect state without saving directly after create Without this fix creating a saver, then resetting the publisher will leave the saver in a broken imprinted state and will not be found by the publisher --- openpype/hosts/fusion/plugins/create/create_saver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_saver.py b/openpype/hosts/fusion/plugins/create/create_saver.py index 27ff590cb3..81dd235242 100644 --- a/openpype/hosts/fusion/plugins/create/create_saver.py +++ b/openpype/hosts/fusion/plugins/create/create_saver.py @@ -69,8 +69,6 @@ class CreateSaver(NewCreator): # TODO Is this needed? saver[file_format]["SaveAlpha"] = 1 - self._imprint(saver, instance_data) - # Register the CreatedInstance instance = CreatedInstance( family=self.family, @@ -78,6 +76,8 @@ class CreateSaver(NewCreator): data=instance_data, creator=self, ) + data = instance.data_to_store() + self._imprint(saver, data) # Insert the transient data instance.transient_data["tool"] = saver From 56147ca26e5f994e02c4568d75be8bfcaf9fe2cb Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 12:23:41 +0200 Subject: [PATCH 028/690] Fusion: Allow reset frame range on `render` family --- openpype/hosts/fusion/plugins/load/actions.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/fusion/plugins/load/actions.py b/openpype/hosts/fusion/plugins/load/actions.py index f83ab433ee..94ba361b50 100644 --- a/openpype/hosts/fusion/plugins/load/actions.py +++ b/openpype/hosts/fusion/plugins/load/actions.py @@ -11,6 +11,7 @@ class FusionSetFrameRangeLoader(load.LoaderPlugin): families = ["animation", "camera", "imagesequence", + "render", "yeticache", "pointcache", "render"] @@ -46,6 +47,7 @@ class FusionSetFrameRangeWithHandlesLoader(load.LoaderPlugin): families = ["animation", "camera", "imagesequence", + "render", "yeticache", "pointcache", "render"] From 2e6bdad7a0ede6c1445ef4e154df14cfbd355f40 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 12:24:13 +0200 Subject: [PATCH 029/690] Fusion: Tweak logging level for artist-facing report --- openpype/hosts/fusion/plugins/publish/collect_instances.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/collect_instances.py b/openpype/hosts/fusion/plugins/publish/collect_instances.py index 6016baa2a9..4d6da79b77 100644 --- a/openpype/hosts/fusion/plugins/publish/collect_instances.py +++ b/openpype/hosts/fusion/plugins/publish/collect_instances.py @@ -85,5 +85,5 @@ class CollectInstanceData(pyblish.api.InstancePlugin): # Add review family if the instance is marked as 'review' # This could be done through a 'review' Creator attribute. if instance.data.get("review", False): - self.log.info("Adding review family..") + self.log.debug("Adding review family..") instance.data["families"].append("review") From 5eddd0f601b8cf61c83267bca031832af622b0c1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 17:21:44 +0200 Subject: [PATCH 030/690] Tweak code for readability --- .../publish/validator_saver_resolution.py | 148 +++++++++--------- 1 file changed, 77 insertions(+), 71 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py index 43e2ea5093..0dac040c7f 100644 --- a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py @@ -5,10 +5,56 @@ from openpype.pipeline import ( ) from openpype.hosts.fusion.api.action import SelectInvalidAction -from openpype.hosts.fusion.api import ( - get_current_comp, - comp_lock_and_undo_chunk, -) +from openpype.hosts.fusion.api import comp_lock_and_undo_chunk + + +def get_tool_resolution(tool, frame): + """Return the 2D input resolution to a Fusion tool + + If the current tool hasn't been rendered its input resolution + hasn't been saved. To combat this, add an expression in + the comments field to read the resolution + + Args + tool (Fusion Tool): The tool to query input resolution + frame (int): The frame to query the resolution on. + + Returns: + tuple: width, height as 2-tuple of integers + + """ + comp = tool.Composition + + # False undo removes the undo-stack from the undo list + with comp_lock_and_undo_chunk(comp, "Read resolution", False): + # Save old comment + old_comment = "" + has_expression = False + if tool["Comments"][frame] != "": + if tool["Comments"].GetExpression() is not None: + has_expression = True + old_comment = tool["Comments"].GetExpression() + tool["Comments"].SetExpression(None) + else: + old_comment = tool["Comments"][frame] + tool["Comments"][frame] = "" + + # Get input width + tool["Comments"].SetExpression("self.Input.OriginalWidth") + width = int(tool["Comments"][frame]) + + # Get input height + tool["Comments"].SetExpression("self.Input.OriginalHeight") + height = int(tool["Comments"][frame]) + + # Reset old comment + tool["Comments"].SetExpression(None) + if has_expression: + tool["Comments"].SetExpression(old_comment) + else: + tool["Comments"][frame] = old_comment + + return width, height class ValidateSaverResolution( @@ -23,74 +69,34 @@ class ValidateSaverResolution( optional = True actions = [SelectInvalidAction] - @classmethod - def get_invalid(cls, instance, wrong_resolution=None): - """Validate if the saver rescive the expected resolution""" - if wrong_resolution is None: - wrong_resolution = [] - - saver = instance[0] - firstFrame = saver.GetAttrs("TOOLNT_Region_Start")[1] - comp = get_current_comp() - - # If the current saver hasn't bin rendered its input resolution - # hasn't bin saved. To combat this, add an expression in - # the comments field to read the resolution - - # False undo removes the undo-stack from the undo list - with comp_lock_and_undo_chunk(comp, "Read resolution", False): - # Save old comment - oldComment = "" - hasExpression = False - if saver["Comments"][firstFrame] != "": - if saver["Comments"].GetExpression() is not None: - hasExpression = True - oldComment = saver["Comments"].GetExpression() - saver["Comments"].SetExpression(None) - else: - oldComment = saver["Comments"][firstFrame] - saver["Comments"][firstFrame] = "" - - # Get input width - saver["Comments"].SetExpression("self.Input.OriginalWidth") - width = int(saver["Comments"][firstFrame]) - - # Get input height - saver["Comments"].SetExpression("self.Input.OriginalHeight") - height = int(saver["Comments"][firstFrame]) - - # Reset old comment - saver["Comments"].SetExpression(None) - if hasExpression: - saver["Comments"].SetExpression(oldComment) - else: - saver["Comments"][firstFrame] = oldComment - - # Time to compare! - wrong_resolution.append("{}x{}".format(width, height)) - entityData = instance.data["assetEntity"]["data"] - if entityData["resolutionWidth"] != width: - return [saver] - if entityData["resolutionHeight"] != height: - return [saver] - - return [] - def process(self, instance): - if not self.is_active(instance.data): - return - - wrong_resolution = [] - invalid = self.get_invalid(instance, wrong_resolution) - if invalid: - entityData = instance.data["assetEntity"]["data"] + resolution = self.get_resolution(instance) + expected_resolution = self.get_expected_resolution(instance) + if resolution != expected_resolution: raise PublishValidationError( - "The input's resolution does not match" - " the asset's resolution of {}x{}.\n\n" + "The input's resolution does not match " + "the asset's resolution {}.\n\n" "The input's resolution is {}".format( - entityData["resolutionWidth"], - entityData["resolutionHeight"], - wrong_resolution[0], - ), - title=self.label, + expected_resolution, + resolution, + ) ) + + @classmethod + def get_invalid(cls, instance): + resolution = cls.get_resolution(instance) + expected_resolution = cls.get_expected_resolution(instance) + if resolution != expected_resolution: + saver = instance.data["tool"] + return [saver] + + @classmethod + def get_resolution(cls, instance): + saver = instance.data["tool"] + first_frame = saver.GetAttrs("TOOLNT_Region_Start")[1] + return get_tool_resolution(saver, frame=first_frame) + + @classmethod + def get_expected_resolution(cls, instance): + data = instance.data["assetEntity"]["data"] + return data["resolutionWidth"], data["resolutionHeight"] From 7b62a204a35bbd29ccbdfcc485020a63d1b26dee Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 17:22:09 +0200 Subject: [PATCH 031/690] Fix optional support --- .../hosts/fusion/plugins/publish/validator_saver_resolution.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py index 0dac040c7f..1c38533cf9 100644 --- a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py @@ -70,6 +70,9 @@ class ValidateSaverResolution( actions = [SelectInvalidAction] def process(self, instance): + if not self.is_active(instance.data): + return + resolution = self.get_resolution(instance) expected_resolution = self.get_expected_resolution(instance) if resolution != expected_resolution: From 7a2cc22e6d2e4b949b78243a467547be63e56104 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 17:24:22 +0200 Subject: [PATCH 032/690] Fix docstring --- .../hosts/fusion/plugins/publish/validator_saver_resolution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py index 1c38533cf9..8317864fcf 100644 --- a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py @@ -60,7 +60,7 @@ def get_tool_resolution(tool, frame): class ValidateSaverResolution( pyblish.api.InstancePlugin, OptionalPyblishPluginMixin ): - """Validate that the saver input resolution matches the projects""" + """Validate that the saver input resolution matches the asset resolution""" order = pyblish.api.ValidatorOrder label = "Validate Saver Resolution" From c3e299f9adfd49b8f87a2be1a3ef58804cf22eb4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 17:26:13 +0200 Subject: [PATCH 033/690] Use `frameStartHandle` since we only care about the saver during the publish frame range --- .../hosts/fusion/plugins/publish/validator_saver_resolution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py index 8317864fcf..bcc101ba16 100644 --- a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py @@ -96,7 +96,7 @@ class ValidateSaverResolution( @classmethod def get_resolution(cls, instance): saver = instance.data["tool"] - first_frame = saver.GetAttrs("TOOLNT_Region_Start")[1] + first_frame = instance.data["frameStartHandle"] return get_tool_resolution(saver, frame=first_frame) @classmethod From bed16ae663c7d4dbb7e4c32db72d7e5e53d277d4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 18:07:32 +0200 Subject: [PATCH 034/690] Match filename with other validators --- ...validator_saver_resolution.py => validate_saver_resolution.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename openpype/hosts/fusion/plugins/publish/{validator_saver_resolution.py => validate_saver_resolution.py} (100%) diff --git a/openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py similarity index 100% rename from openpype/hosts/fusion/plugins/publish/validator_saver_resolution.py rename to openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py From a50ab622b7968ec0bbf377f152db603b1cf1984c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 18:08:59 +0200 Subject: [PATCH 035/690] Fix message readability --- .../fusion/plugins/publish/validate_saver_resolution.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py index bcc101ba16..b43a5023fa 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py @@ -78,10 +78,10 @@ class ValidateSaverResolution( if resolution != expected_resolution: raise PublishValidationError( "The input's resolution does not match " - "the asset's resolution {}.\n\n" - "The input's resolution is {}".format( - expected_resolution, - resolution, + "the asset's resolution {}x{}.\n\n" + "The input's resolution is {}x{}.".format( + expected_resolution[0], expected_resolution[1], + resolution[0], resolution[1] ) ) From 49e29116414e87b92732094e5a5cdf95a5d8c8d7 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 4 Sep 2023 20:25:50 +0200 Subject: [PATCH 036/690] Expose ValidateSaverResolution in settings --- .../defaults/project_settings/fusion.json | 7 +++++++ .../projects_schema/schema_project_fusion.json | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/openpype/settings/defaults/project_settings/fusion.json b/openpype/settings/defaults/project_settings/fusion.json index 0ee7d6127d..ab24727db5 100644 --- a/openpype/settings/defaults/project_settings/fusion.json +++ b/openpype/settings/defaults/project_settings/fusion.json @@ -27,5 +27,12 @@ "farm_rendering" ] } + }, + "publish": { + "ValidateSaverResolution": { + "enabled": true, + "optional": true, + "active": true + } } } diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json index 656c50dd98..342411f8a5 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_fusion.json @@ -84,6 +84,24 @@ ] } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "publish", + "label": "Publish plugins", + "children": [ + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateSaverResolution", + "label": "Validate Saver Resolution" + } + ] + } + ] } ] } From bd049da6f93fdffac69d673a66d9387351471576 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 20 Sep 2023 16:11:13 +0200 Subject: [PATCH 037/690] Update openpype/hosts/fusion/plugins/load/load_usd.py --- openpype/hosts/fusion/plugins/load/load_usd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index 8c2c69f52f..f12fbd5ed0 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -9,7 +9,7 @@ from openpype.hosts.fusion.api import ( ) -class FusionLoadAlembicMesh(load.LoaderPlugin): +class FusionLoadUSD(load.LoaderPlugin): """Load USD into Fusion Support for USD was added since Fusion 18.5 From 5e5db076d1795256ecf7b1cebe064651452cefaa Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 11:42:42 +0800 Subject: [PATCH 038/690] remove unrelated codes to this pull request --- openpype/hosts/houdini/api/lib.py | 50 +- .../plugins/create/create_arnold_ass.py | 16 + .../houdini/plugins/create/create_bgeo.py | 16 +- .../plugins/create/create_mantra_ifd.py | 56 ++ .../plugins/create/create_pointcache.py | 17 + .../plugins/create/create_redshift_proxy.py | 16 + .../plugins/create/create_vbd_cache.py | 22 +- .../hosts/houdini/plugins/load/load_camera.py | 81 ++- .../plugins/publish/collect_cache_farm.py | 75 +++ .../plugins/publish/collect_chunk_size.py | 39 ++ .../houdini/plugins/publish/collect_frames.py | 3 +- .../plugins/publish/extract_alembic.py | 4 + .../houdini/plugins/publish/extract_ass.py | 5 +- .../houdini/plugins/publish/extract_bgeo.py | 4 +- .../plugins/publish/extract_mantra_ifd.py | 51 ++ .../plugins/publish/extract_redshift_proxy.py | 5 +- .../plugins/publish/extract_vdb_cache.py | 4 +- .../plugins/publish/increment_current_file.py | 3 +- .../publish/submit_houdini_cache_deadline.py | 183 +++++++ .../publish/submit_publish_cache_job.py | 501 ++++++++++++++++++ .../publish/validate_deadline_pools.py | 3 +- openpype/pipeline/farm/pyblish_functions.py | 232 ++++++++ .../defaults/project_settings/deadline.json | 8 + .../defaults/project_settings/houdini.json | 5 + .../schemas/schema_houdini_publish.json | 25 + .../server/settings/publish_plugins.py | 22 + server_addon/deadline/server/version.py | 2 +- .../server/settings/publish_plugins.py | 15 + website/docs/artist_hosts_houdini.md | 24 + .../assets/houdini_farm_cache_creator.png | Bin 0 -> 95572 bytes .../docs/assets/houdini_farm_cache_loader.png | Bin 0 -> 134816 bytes .../docs/assets/houdini_frame_per_task.png | Bin 0 -> 59257 bytes 32 files changed, 1380 insertions(+), 107 deletions(-) create mode 100644 openpype/hosts/houdini/plugins/create/create_mantra_ifd.py create mode 100644 openpype/hosts/houdini/plugins/publish/collect_cache_farm.py create mode 100644 openpype/hosts/houdini/plugins/publish/collect_chunk_size.py create mode 100644 openpype/hosts/houdini/plugins/publish/extract_mantra_ifd.py create mode 100644 openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py create mode 100644 openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py create mode 100644 website/docs/assets/houdini_farm_cache_creator.png create mode 100644 website/docs/assets/houdini_farm_cache_loader.png create mode 100644 website/docs/assets/houdini_frame_per_task.png diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index eff98c05f1..856e7abbd3 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -138,6 +138,9 @@ def get_output_parameter(node): return node.parm("ar_ass_file") elif node_type == "Redshift_Proxy_Output": return node.parm("RS_archive_file") + elif node_type == "ifd": + if node.evalParm("soho_outputmode"): + return node.parm("soho_diskfile") raise TypeError("Node type '%s' not supported" % node_type) @@ -649,50 +652,3 @@ def get_color_management_preferences(): "display": hou.Color.ocio_defaultDisplay(), "view": hou.Color.ocio_defaultView() } - - -def get_resolution_from_doc(doc): - """Get resolution from the given asset document. """ - - if not doc or "data" not in doc: - print("Entered document is not valid. \"{}\"".format(str(doc))) - return None - - resolution_width = doc["data"].get("resolutionWidth") - resolution_height = doc["data"].get("resolutionHeight") - - # Make sure both width and height are set - if resolution_width is None or resolution_height is None: - print("No resolution information found for \"{}\"".format(doc["name"])) - return None - - return int(resolution_width), int(resolution_height) - - -def set_camera_resolution(camera, asset_doc=None): - """Apply resolution to camera from asset document of the publish""" - - if not asset_doc: - asset_doc = get_current_project_asset() - - resolution = get_resolution_from_doc(asset_doc) - - if resolution: - print("Setting camera resolution: {} -> {}x{}".format( - camera.name(), resolution[0], resolution[1] - )) - camera.parm("resx").set(resolution[0]) - camera.parm("resy").set(resolution[1]) - - -def get_camera_from_container(container): - """Get camera from container node. """ - - cameras = container.recursiveGlob( - "*", - filter=hou.nodeTypeFilter.ObjCamera, - include_subnets=False - ) - - assert len(cameras) == 1, "Camera instance must have only one camera" - return cameras[0] diff --git a/openpype/hosts/houdini/plugins/create/create_arnold_ass.py b/openpype/hosts/houdini/plugins/create/create_arnold_ass.py index 12d08f7d83..437a14c723 100644 --- a/openpype/hosts/houdini/plugins/create/create_arnold_ass.py +++ b/openpype/hosts/houdini/plugins/create/create_arnold_ass.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin for creating Arnold ASS files.""" from openpype.hosts.houdini.api import plugin +from openpype.lib import BoolDef class CreateArnoldAss(plugin.HoudiniCreator): @@ -21,6 +22,9 @@ class CreateArnoldAss(plugin.HoudiniCreator): instance_data.pop("active", None) instance_data.update({"node_type": "arnold"}) + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] instance = super(CreateArnoldAss, self).create( subset_name, @@ -52,3 +56,15 @@ class CreateArnoldAss(plugin.HoudiniCreator): # Lock any parameters in this list to_lock = ["ar_ass_export_enable", "family", "id"] self.lock_parameters(instance_node, to_lock) + + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + # Use same attributes as for instance attributes + return attrs + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/create/create_bgeo.py b/openpype/hosts/houdini/plugins/create/create_bgeo.py index a3f31e7e94..6d903fb02d 100644 --- a/openpype/hosts/houdini/plugins/create/create_bgeo.py +++ b/openpype/hosts/houdini/plugins/create/create_bgeo.py @@ -2,7 +2,7 @@ """Creator plugin for creating pointcache bgeo files.""" from openpype.hosts.houdini.api import plugin from openpype.pipeline import CreatedInstance, CreatorError -from openpype.lib import EnumDef +from openpype.lib import EnumDef, BoolDef class CreateBGEO(plugin.HoudiniCreator): @@ -18,6 +18,9 @@ class CreateBGEO(plugin.HoudiniCreator): instance_data.pop("active", None) instance_data.update({"node_type": "geometry"}) + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] instance = super(CreateBGEO, self).create( subset_name, @@ -58,6 +61,13 @@ class CreateBGEO(plugin.HoudiniCreator): instance_node.setParms(parms) + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + def get_pre_create_attr_defs(self): attrs = super().get_pre_create_attr_defs() bgeo_enum = [ @@ -88,5 +98,5 @@ class CreateBGEO(plugin.HoudiniCreator): ] return attrs + [ - EnumDef("bgeo_type", bgeo_enum, label="BGEO Options"), - ] + EnumDef("bgeo_type", bgeo_enum, label="BGEO Options") + ] + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/create/create_mantra_ifd.py b/openpype/hosts/houdini/plugins/create/create_mantra_ifd.py new file mode 100644 index 0000000000..7ea7d1042f --- /dev/null +++ b/openpype/hosts/houdini/plugins/create/create_mantra_ifd.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- +"""Creator plugin for creating pointcache alembics.""" +from openpype.hosts.houdini.api import plugin +from openpype.pipeline import CreatedInstance +from openpype.lib import BoolDef + + +class CreateMantraIFD(plugin.HoudiniCreator): + """Mantra .ifd Archive""" + identifier = "io.openpype.creators.houdini.mantraifd" + label = "Mantra IFD" + family = "mantraifd" + icon = "gears" + + def create(self, subset_name, instance_data, pre_create_data): + import hou + instance_data.pop("active", None) + instance_data.update({"node_type": "ifd"}) + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] + instance = super(CreateMantraIFD, self).create( + subset_name, + instance_data, + pre_create_data) # type: CreatedInstance + + instance_node = hou.node(instance.get("instance_node")) + + filepath = "{}{}".format( + hou.text.expandString("$HIP/pyblish/"), + "{}.$F4.ifd".format(subset_name)) + parms = { + # Render frame range + "trange": 1, + # Arnold ROP settings + "soho_diskfile": filepath, + "soho_outputmode": 1 + } + + instance_node.setParms(parms) + + # Lock any parameters in this list + to_lock = ["soho_outputmode", "family", "id"] + self.lock_parameters(instance_node, to_lock) + + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + # Use same attributes as for instance attributes + return attrs + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/create/create_pointcache.py b/openpype/hosts/houdini/plugins/create/create_pointcache.py index 7eaf2aff2b..2d2f89cc48 100644 --- a/openpype/hosts/houdini/plugins/create/create_pointcache.py +++ b/openpype/hosts/houdini/plugins/create/create_pointcache.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- """Creator plugin for creating pointcache alembics.""" from openpype.hosts.houdini.api import plugin +from openpype.lib import BoolDef import hou + class CreatePointCache(plugin.HoudiniCreator): """Alembic ROP to pointcache""" identifier = "io.openpype.creators.houdini.pointcache" @@ -15,6 +17,9 @@ class CreatePointCache(plugin.HoudiniCreator): def create(self, subset_name, instance_data, pre_create_data): instance_data.pop("active", None) instance_data.update({"node_type": "alembic"}) + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] instance = super(CreatePointCache, self).create( subset_name, @@ -105,3 +110,15 @@ class CreatePointCache(plugin.HoudiniCreator): else: return min(outputs, key=lambda node: node.evalParm('outputidx')) + + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + # Use same attributes as for instance attributes + return attrs + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py b/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py index b814dd9d57..de1f1719fb 100644 --- a/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py +++ b/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py @@ -2,6 +2,7 @@ """Creator plugin for creating Redshift proxies.""" from openpype.hosts.houdini.api import plugin from openpype.pipeline import CreatedInstance +from openpype.lib import BoolDef class CreateRedshiftProxy(plugin.HoudiniCreator): @@ -24,6 +25,9 @@ class CreateRedshiftProxy(plugin.HoudiniCreator): # TODO: Somehow enforce so that it only shows the original limited # attributes of the Redshift_Proxy_Output node type instance_data.update({"node_type": "Redshift_Proxy_Output"}) + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] instance = super(CreateRedshiftProxy, self).create( subset_name, @@ -44,3 +48,15 @@ class CreateRedshiftProxy(plugin.HoudiniCreator): # Lock some Avalon attributes to_lock = ["family", "id", "prim_to_detail_pattern"] self.lock_parameters(instance_node, to_lock) + + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + # Use same attributes as for instance attributes + return attrs + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/create/create_vbd_cache.py b/openpype/hosts/houdini/plugins/create/create_vbd_cache.py index 9c96e48e3a..8589600fc6 100644 --- a/openpype/hosts/houdini/plugins/create/create_vbd_cache.py +++ b/openpype/hosts/houdini/plugins/create/create_vbd_cache.py @@ -2,6 +2,7 @@ """Creator plugin for creating VDB Caches.""" from openpype.hosts.houdini.api import plugin from openpype.pipeline import CreatedInstance +from openpype.lib import BoolDef import hou @@ -19,15 +20,20 @@ class CreateVDBCache(plugin.HoudiniCreator): instance_data.pop("active", None) instance_data.update({"node_type": "geometry"}) - + creator_attributes = instance_data.setdefault( + "creator_attributes", dict()) + creator_attributes["farm"] = pre_create_data["farm"] instance = super(CreateVDBCache, self).create( subset_name, instance_data, pre_create_data) # type: CreatedInstance instance_node = hou.node(instance.get("instance_node")) + file_path = "{}{}".format( + hou.text.expandString("$HIP/pyblish/"), + "{}.$F4.vdb".format(subset_name)) parms = { - "sopoutput": "$HIP/pyblish/{}.$F4.vdb".format(subset_name), + "sopoutput": file_path, "initsim": True, "trange": 1 } @@ -102,3 +108,15 @@ class CreateVDBCache(plugin.HoudiniCreator): else: return min(outputs, key=lambda node: node.evalParm('outputidx')) + + def get_instance_attr_defs(self): + return [ + BoolDef("farm", + label="Submitting to Farm", + default=False) + ] + + def get_pre_create_attr_defs(self): + attrs = super().get_pre_create_attr_defs() + # Use same attributes as for instance attributes + return attrs + self.get_instance_attr_defs() diff --git a/openpype/hosts/houdini/plugins/load/load_camera.py b/openpype/hosts/houdini/plugins/load/load_camera.py index e16146a267..7b4a04809e 100644 --- a/openpype/hosts/houdini/plugins/load/load_camera.py +++ b/openpype/hosts/houdini/plugins/load/load_camera.py @@ -4,13 +4,6 @@ from openpype.pipeline import ( ) from openpype.hosts.houdini.api import pipeline -from openpype.hosts.houdini.api.lib import ( - set_camera_resolution, - get_camera_from_container -) - -import hou - ARCHIVE_EXPRESSION = ('__import__("_alembic_hom_extensions")' '.alembicGetCameraDict') @@ -32,15 +25,7 @@ def transfer_non_default_values(src, dest, ignore=None): channel expression and ignore certain Parm types. """ - - ignore_types = { - hou.parmTemplateType.Toggle, - hou.parmTemplateType.Menu, - hou.parmTemplateType.Button, - hou.parmTemplateType.FolderSet, - hou.parmTemplateType.Separator, - hou.parmTemplateType.Label, - } + import hou src.updateParmStates() @@ -77,6 +62,14 @@ def transfer_non_default_values(src, dest, ignore=None): continue # Ignore folders, separators, etc. + ignore_types = { + hou.parmTemplateType.Toggle, + hou.parmTemplateType.Menu, + hou.parmTemplateType.Button, + hou.parmTemplateType.FolderSet, + hou.parmTemplateType.Separator, + hou.parmTemplateType.Label, + } if parm.parmTemplate().type() in ignore_types: continue @@ -97,8 +90,13 @@ class CameraLoader(load.LoaderPlugin): def load(self, context, name=None, namespace=None, data=None): + import os + import hou + # Format file name, Houdini only wants forward slashes - file_path = self.filepath_from_context(context).replace("\\", "/") + file_path = self.filepath_from_context(context) + file_path = os.path.normpath(file_path) + file_path = file_path.replace("\\", "/") # Get the root node obj = hou.node("/obj") @@ -108,21 +106,19 @@ class CameraLoader(load.LoaderPlugin): node_name = "{}_{}".format(namespace, name) if namespace else name # Create a archive node - node = self.create_and_connect(obj, "alembicarchive", node_name) + container = self.create_and_connect(obj, "alembicarchive", node_name) # TODO: add FPS of project / asset - node.setParms({"fileName": file_path, "channelRef": True}) + container.setParms({"fileName": file_path, + "channelRef": True}) # Apply some magic - node.parm("buildHierarchy").pressButton() - node.moveToGoodPosition() + container.parm("buildHierarchy").pressButton() + container.moveToGoodPosition() # Create an alembic xform node - nodes = [node] + nodes = [container] - camera = get_camera_from_container(node) - self._match_maya_render_mask(camera) - set_camera_resolution(camera, asset_doc=context["asset"]) self[:] = nodes return pipeline.containerise(node_name, @@ -147,14 +143,14 @@ class CameraLoader(load.LoaderPlugin): # Store the cam temporarily next to the Alembic Archive # so that we can preserve parm values the user set on it # after build hierarchy was triggered. - old_camera = get_camera_from_container(node) + old_camera = self._get_camera(node) temp_camera = old_camera.copyTo(node.parent()) # Rebuild node.parm("buildHierarchy").pressButton() # Apply values to the new camera - new_camera = get_camera_from_container(node) + new_camera = self._get_camera(node) transfer_non_default_values(temp_camera, new_camera, # The hidden uniform scale attribute @@ -162,9 +158,6 @@ class CameraLoader(load.LoaderPlugin): # "icon_scale" just skip that completely ignore={"scale"}) - self._match_maya_render_mask(new_camera) - set_camera_resolution(new_camera) - temp_camera.destroy() def remove(self, container): @@ -172,6 +165,15 @@ class CameraLoader(load.LoaderPlugin): node = container["node"] node.destroy() + def _get_camera(self, node): + import hou + cameras = node.recursiveGlob("*", + filter=hou.nodeTypeFilter.ObjCamera, + include_subnets=False) + + assert len(cameras) == 1, "Camera instance must have only one camera" + return cameras[0] + def create_and_connect(self, node, node_type, name=None): """Create a node within a node which and connect it to the input @@ -192,20 +194,5 @@ class CameraLoader(load.LoaderPlugin): new_node.moveToGoodPosition() return new_node - def _match_maya_render_mask(self, camera): - """Workaround to match Maya render mask in Houdini""" - - # print("Setting match maya render mask ") - parm = camera.parm("aperture") - expression = parm.expression() - expression = expression.replace("return ", "aperture = ") - expression += """ -# Match maya render mask (logic from Houdini's own FBX importer) -node = hou.pwd() -resx = node.evalParm('resx') -resy = node.evalParm('resy') -aspect = node.evalParm('aspect') -aperture *= min(1, (resx / resy * aspect) / 1.5) -return aperture -""" - parm.setExpression(expression, language=hou.exprLanguage.Python) + def switch(self, container, representation): + self.update(container, representation) diff --git a/openpype/hosts/houdini/plugins/publish/collect_cache_farm.py b/openpype/hosts/houdini/plugins/publish/collect_cache_farm.py new file mode 100644 index 0000000000..36ade32a35 --- /dev/null +++ b/openpype/hosts/houdini/plugins/publish/collect_cache_farm.py @@ -0,0 +1,75 @@ +import os +import pyblish.api +import hou +from openpype.hosts.houdini.api import lib + + +class CollectDataforCache(pyblish.api.InstancePlugin): + """Collect data for caching to Deadline.""" + + order = pyblish.api.CollectorOrder + 0.04 + families = ["ass", "pointcache", + "mantraifd", "redshiftproxy", + "vdbcache"] + hosts = ["houdini"] + targets = ["local", "remote"] + label = "Collect Data for Cache" + + def process(self, instance): + creator_attribute = instance.data["creator_attributes"] + farm_enabled = creator_attribute["farm"] + instance.data["farm"] = farm_enabled + if not farm_enabled: + self.log.debug("Caching on farm is disabled. " + "Skipping farm collecting.") + return + # Why do we need this particular collector to collect the expected + # output files from a ROP node. Don't we have a dedicated collector + # for that yet? + # Collect expected files + ropnode = hou.node(instance.data["instance_node"]) + output_parm = lib.get_output_parameter(ropnode) + expected_filepath = output_parm.eval() + instance.data.setdefault("files", list()) + instance.data.setdefault("expectedFiles", list()) + if instance.data.get("frames"): + files = self.get_files(instance, expected_filepath) + # list of files + instance.data["files"].extend(files) + else: + # single file + instance.data["files"].append(output_parm.eval()) + cache_files = {"_": instance.data["files"]} + # Convert instance family to pointcache if it is bgeo or abc + # because ??? + for family in instance.data["families"]: + if family == "bgeo" or "abc": + instance.data["family"] = "pointcache" + break + instance.data.update({ + "plugin": "Houdini", + "publish": True + }) + instance.data["families"].append("publish.hou") + instance.data["expectedFiles"].append(cache_files) + + self.log.debug("{}".format(instance.data)) + + def get_files(self, instance, output_parm): + """Get the files with the frame range data + + Args: + instance (_type_): instance + output_parm (_type_): path of output parameter + + Returns: + files: a list of files + """ + directory = os.path.dirname(output_parm) + + files = [ + os.path.join(directory, frame).replace("\\", "/") + for frame in instance.data["frames"] + ] + + return files diff --git a/openpype/hosts/houdini/plugins/publish/collect_chunk_size.py b/openpype/hosts/houdini/plugins/publish/collect_chunk_size.py new file mode 100644 index 0000000000..1c867e930a --- /dev/null +++ b/openpype/hosts/houdini/plugins/publish/collect_chunk_size.py @@ -0,0 +1,39 @@ +import pyblish.api +from openpype.lib import NumberDef +from openpype.pipeline import OpenPypePyblishPluginMixin + + +class CollectChunkSize(pyblish.api.InstancePlugin, + OpenPypePyblishPluginMixin): + """Collect chunk size for cache submission to Deadline.""" + + order = pyblish.api.CollectorOrder + 0.05 + families = ["ass", "pointcache", + "vdbcache", "mantraifd", + "redshiftproxy"] + hosts = ["houdini"] + targets = ["local", "remote"] + label = "Collect Chunk Size" + chunkSize = 999999 + + def process(self, instance): + # need to get the chunk size info from the setting + attr_values = self.get_attr_values_from_data(instance.data) + instance.data["chunkSize"] = attr_values.get("chunkSize") + + @classmethod + def apply_settings(cls, project_settings): + project_setting = project_settings["houdini"]["publish"]["CollectChunkSize"] # noqa + cls.chunkSize = project_setting["chunk_size"] + + @classmethod + def get_attribute_defs(cls): + return [ + NumberDef("chunkSize", + minimum=1, + maximum=999999, + decimals=0, + default=cls.chunkSize, + label="Frame Per Task") + + ] diff --git a/openpype/hosts/houdini/plugins/publish/collect_frames.py b/openpype/hosts/houdini/plugins/publish/collect_frames.py index 01df809d4c..cb4ff1a45b 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_frames.py +++ b/openpype/hosts/houdini/plugins/publish/collect_frames.py @@ -14,7 +14,8 @@ class CollectFrames(pyblish.api.InstancePlugin): order = pyblish.api.CollectorOrder + 0.01 label = "Collect Frames" families = ["vdbcache", "imagesequence", "ass", - "redshiftproxy", "review", "bgeo"] + "mantraifd", "redshiftproxy", "review", + "bgeo"] def process(self, instance): diff --git a/openpype/hosts/houdini/plugins/publish/extract_alembic.py b/openpype/hosts/houdini/plugins/publish/extract_alembic.py index bdd19b23d4..df2fdda241 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_alembic.py +++ b/openpype/hosts/houdini/plugins/publish/extract_alembic.py @@ -14,8 +14,12 @@ class ExtractAlembic(publish.Extractor): label = "Extract Alembic" hosts = ["houdini"] families = ["abc", "camera"] + targets = ["local", "remote"] def process(self, instance): + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return ropnode = hou.node(instance.data["instance_node"]) diff --git a/openpype/hosts/houdini/plugins/publish/extract_ass.py b/openpype/hosts/houdini/plugins/publish/extract_ass.py index 0d246625ba..cf04a3994e 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_ass.py +++ b/openpype/hosts/houdini/plugins/publish/extract_ass.py @@ -14,9 +14,12 @@ class ExtractAss(publish.Extractor): label = "Extract Ass" families = ["ass"] hosts = ["houdini"] + targets = ["local", "remote"] def process(self, instance): - + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return ropnode = hou.node(instance.data["instance_node"]) # Get the filename from the filename parameter diff --git a/openpype/hosts/houdini/plugins/publish/extract_bgeo.py b/openpype/hosts/houdini/plugins/publish/extract_bgeo.py index c9625ec880..fc5cf0bb65 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_bgeo.py +++ b/openpype/hosts/houdini/plugins/publish/extract_bgeo.py @@ -17,7 +17,9 @@ class ExtractBGEO(publish.Extractor): families = ["bgeo"] def process(self, instance): - + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return ropnode = hou.node(instance.data["instance_node"]) # Get the filename from the filename parameter diff --git a/openpype/hosts/houdini/plugins/publish/extract_mantra_ifd.py b/openpype/hosts/houdini/plugins/publish/extract_mantra_ifd.py new file mode 100644 index 0000000000..894260d1bf --- /dev/null +++ b/openpype/hosts/houdini/plugins/publish/extract_mantra_ifd.py @@ -0,0 +1,51 @@ +import os + +import pyblish.api + +from openpype.pipeline import publish + +import hou + + +class ExtractMantraIFD(publish.Extractor): + + order = pyblish.api.ExtractorOrder + label = "Extract Mantra ifd" + hosts = ["houdini"] + families = ["mantraifd"] + targets = ["local", "remote"] + + def process(self, instance): + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return + + ropnode = hou.node(instance.data.get("instance_node")) + output = ropnode.evalParm("soho_diskfile") + staging_dir = os.path.dirname(output) + instance.data["stagingDir"] = staging_dir + + files = instance.data["frames"] + missing_frames = [ + frame + for frame in instance.data["frames"] + if not os.path.exists( + os.path.normpath(os.path.join(staging_dir, frame))) + ] + if missing_frames: + raise RuntimeError("Failed to complete Mantra ifd extraction. " + "Missing output files: {}".format( + missing_frames)) + + if "representations" not in instance.data: + instance.data["representations"] = [] + + representation = { + 'name': 'ifd', + 'ext': 'ifd', + 'files': files, + "stagingDir": staging_dir, + "frameStart": instance.data["frameStart"], + "frameEnd": instance.data["frameEnd"], + } + instance.data["representations"].append(representation) diff --git a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py index 1d99ac665c..0ca0a01c5c 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py +++ b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py @@ -14,9 +14,12 @@ class ExtractRedshiftProxy(publish.Extractor): label = "Extract Redshift Proxy" families = ["redshiftproxy"] hosts = ["houdini"] + targets = ["local", "remote"] def process(self, instance): - + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return ropnode = hou.node(instance.data.get("instance_node")) # Get the filename from the filename parameter diff --git a/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py b/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py index 4bca758f08..7d8634b83c 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py +++ b/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py @@ -16,7 +16,9 @@ class ExtractVDBCache(publish.Extractor): hosts = ["houdini"] def process(self, instance): - + if instance.data.get("farm"): + self.log.debug("Should be processed on farm, skipping.") + return ropnode = hou.node(instance.data["instance_node"]) # Get the filename from the filename parameter diff --git a/openpype/hosts/houdini/plugins/publish/increment_current_file.py b/openpype/hosts/houdini/plugins/publish/increment_current_file.py index 3569de7693..4788cca3cf 100644 --- a/openpype/hosts/houdini/plugins/publish/increment_current_file.py +++ b/openpype/hosts/houdini/plugins/publish/increment_current_file.py @@ -22,7 +22,8 @@ class IncrementCurrentFile(pyblish.api.ContextPlugin): "arnold_rop", "mantra_rop", "karma_rop", - "usdrender"] + "usdrender", + "publish.hou"] optional = True def process(self, context): diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py new file mode 100644 index 0000000000..b1717d09ee --- /dev/null +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -0,0 +1,183 @@ +import os +import getpass +from datetime import datetime + +import hou + +import attr +import pyblish.api +from openpype.lib import ( + TextDef, + NumberDef, +) +from openpype.pipeline import ( + legacy_io, + OpenPypePyblishPluginMixin +) +from openpype.tests.lib import is_in_tests +from openpype.lib import is_running_from_build +from openpype_modules.deadline import abstract_submit_deadline +from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo + + +@attr.s +class HoudiniPluginInfo(object): + Build = attr.ib(default=None) + IgnoreInputs = attr.ib(default=True) + ScriptJob = attr.ib(default=True) + SceneFile = attr.ib(default=None) # Input + SaveFile = attr.ib(default=True) + ScriptFilename = attr.ib(default=None) + OutputDriver = attr.ib(default=None) + Version = attr.ib(default=None) # Mandatory for Deadline + ProjectPath = attr.ib(default=None) + + +class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, # noqa + OpenPypePyblishPluginMixin): + """Submit Houdini scene to perform a local publish in Deadline. + + Publishing in Deadline can be helpful for scenes that publish very slow. + This way it can process in the background on another machine without the + Artist having to wait for the publish to finish on their local machine. + + Submission is done through the Deadline Web Service as + supplied via the environment variable AVALON_DEADLINE. + + """ + + label = "Submit Scene to Deadline" + order = pyblish.api.IntegratorOrder + hosts = ["houdini"] + families = ["publish.hou"] + targets = ["local"] + + priority = 50 + jobInfo = {} + pluginInfo = {} + group = None + + def get_job_info(self): + job_info = DeadlineJobInfo(Plugin="Houdini") + + job_info.update(self.jobInfo) + instance = self._instance + context = instance.context + assert all( + result["success"] for result in context.data["results"] + ), "Errors found, aborting integration.." + + # Deadline connection + AVALON_DEADLINE = legacy_io.Session.get( + "AVALON_DEADLINE", "http://localhost:8082" + ) + assert AVALON_DEADLINE, "Requires AVALON_DEADLINE" + + project_name = instance.context.data["projectName"] + filepath = context.data["currentFile"] + scenename = os.path.basename(filepath) + job_name = "{scene} - {instance} [PUBLISH]".format( + scene=scenename, instance=instance.name) + batch_name = "{code} - {scene}".format(code=project_name, + scene=scenename) + if is_in_tests(): + batch_name += datetime.now().strftime("%d%m%Y%H%M%S") + + job_info.Name = job_name + job_info.BatchName = batch_name + job_info.Plugin = instance.data["plugin"] + job_info.UserName = context.data.get("deadlineUser", getpass.getuser()) + rop_node = self.get_rop_node(instance) + if rop_node.type().name() != "alembic": + frames = "{start}-{end}x{step}".format( + start=int(instance.data["frameStart"]), + end=int(instance.data["frameEnd"]), + step=int(instance.data["byFrameStep"]), + ) + + job_info.Frames = frames + + job_info.Pool = instance.data.get("primaryPool") + job_info.SecondaryPool = instance.data.get("secondaryPool") + + attr_values = self.get_attr_values_from_data(instance.data) + + job_info.ChunkSize = instance.data["chunkSize"] + job_info.Comment = context.data.get("comment") + job_info.Priority = attr_values.get("priority", self.priority) + job_info.Group = attr_values.get("group", self.group) + + keys = [ + "FTRACK_API_USER", + "FTRACK_API_KEY", + "FTRACK_SERVER" + ] + + # Add OpenPype version if we are running from build. + if is_running_from_build(): + keys.append("OPENPYPE_VERSION") + # Add mongo url if it's enabled + if self._instance.context.data.get("deadlinePassMongoUrl"): + keys.append("OPENPYPE_MONGO") + + environment = dict({key: os.environ[key] for key in keys + if key in os.environ}, **legacy_io.Session) + + for key in keys: + value = environment.get(key) + if not value: + continue + job_info.EnvironmentKeyValue[key] = value + # to recognize render jobs + job_info.add_render_job_env_var() + + return job_info + + def get_plugin_info(self): + instance = self._instance + version = hou.applicationVersionString() + version = ".".join(version.split(".")[:2]) + rop = self.get_rop_node(instance) + plugin_info = HoudiniPluginInfo( + Build=None, + IgnoreInputs=True, + ScriptJob=True, + SceneFile=self.scene_path, + SaveFile=True, + OutputDriver=rop.path(), + Version=version, + ProjectPath=os.path.dirname(self.scene_path) + ) + + plugin_payload = attr.asdict(plugin_info) + + return plugin_payload + + def process(self, instance): + super(HoudiniCacheSubmitDeadline, self).process(instance) + output_dir = os.path.dirname(instance.data["files"][0]) + instance.data["outputDir"] = output_dir + instance.data["toBeRenderedOn"] = "deadline" + + def get_rop_node(self, instance): + rop = instance.data.get("instance_node") + rop_node = hou.node(rop) + + return rop_node + + @classmethod + def get_attribute_defs(cls): + defs = super(HoudiniCacheSubmitDeadline, cls).get_attribute_defs() + defs.extend([ + NumberDef("priority", + minimum=1, + maximum=250, + decimals=0, + default=cls.priority, + label="Priority"), + TextDef("group", + default=cls.group, + label="Group Name"), + ]) + + return defs diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py new file mode 100644 index 0000000000..5651ff4c83 --- /dev/null +++ b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -0,0 +1,501 @@ +# -*- coding: utf-8 -*- +"""Submit publishing job to farm.""" +import os +import json +import re +from copy import deepcopy +import requests + +import pyblish.api + +from openpype import AYON_SERVER_ENABLED +from openpype.client import ( + get_last_version_by_subset_name, +) +from openpype.pipeline import publish, legacy_io +from openpype.lib import EnumDef, is_running_from_build +from openpype.tests.lib import is_in_tests +from openpype.pipeline.version_start import get_versioning_start + +from openpype.pipeline.farm.pyblish_functions import ( + create_skeleton_instance_cache, + create_instances_for_cache, + attach_instances_to_subset, + prepare_cache_representations, + create_metadata_path +) + + +class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, + publish.OpenPypePyblishPluginMixin, + publish.ColormanagedPyblishPluginMixin): + """Process Cache Job submitted on farm + This is replicated version of submit publish job + specifically for cache(s). + + These jobs are dependent on a deadline job + submission prior to this plug-in. + + - In case of Deadline, it creates dependent job on farm publishing + rendered image sequence. + + Options in instance.data: + - deadlineSubmissionJob (dict, Required): The returned .json + data from the job submission to deadline. + + - outputDir (str, Required): The output directory where the metadata + file should be generated. It's assumed that this will also be + final folder containing the output files. + + - ext (str, Optional): The extension (including `.`) that is required + in the output filename to be picked up for image sequence + publishing. + + - expectedFiles (list or dict): explained below + + """ + + label = "Submit cache jobs to Deadline" + order = pyblish.api.IntegratorOrder + 0.2 + icon = "tractor" + + targets = ["local"] + + hosts = ["houdini"] + + families = ["publish.hou"] + + environ_job_filter = [ + "OPENPYPE_METADATA_FILE" + ] + + environ_keys = [ + "AVALON_APP_NAME", + "OPENPYPE_USERNAME", + "OPENPYPE_SG_USER", + ] + + # custom deadline attributes + deadline_department = "" + deadline_pool = "" + deadline_pool_secondary = "" + deadline_group = "" + deadline_chunk_size = 1 + deadline_priority = None + + # regex for finding frame number in string + R_FRAME_NUMBER = re.compile(r'.+\.(?P[0-9]+)\..+') + + plugin_pype_version = "3.0" + + # script path for publish_filesequence.py + publishing_script = None + + def _submit_deadline_post_job(self, instance, job): + """Submit publish job to Deadline. + + Deadline specific code separated from :meth:`process` for sake of + more universal code. Muster post job is sent directly by Muster + submitter, so this type of code isn't necessary for it. + + Returns: + (str): deadline_publish_job_id + """ + data = instance.data.copy() + subset = data["subset"] + job_name = "Publish - {subset}".format(subset=subset) + + anatomy = instance.context.data['anatomy'] + + # instance.data.get("subset") != instances[0]["subset"] + # 'Main' vs 'renderMain' + override_version = None + instance_version = instance.data.get("version") # take this if exists + if instance_version != 1: + override_version = instance_version + + output_dir = self._get_publish_folder( + anatomy, + deepcopy(instance.data["anatomyData"]), + instance.data.get("asset"), + instance.data["subset"], + instance.context, + instance.data["family"], + override_version + ) + + # Transfer the environment from the original job to this dependent + # job so they use the same environment + metadata_path, rootless_metadata_path = \ + create_metadata_path(instance, anatomy) + + environment = { + "AVALON_PROJECT": instance.context.data["projectName"], + "AVALON_ASSET": instance.context.data["asset"], + "AVALON_TASK": instance.context.data["task"], + "OPENPYPE_USERNAME": instance.context.data["user"], + "OPENPYPE_LOG_NO_COLORS": "1", + "IS_TEST": str(int(is_in_tests())) + } + + if AYON_SERVER_ENABLED: + environment["AYON_PUBLISH_JOB"] = "1" + environment["AYON_RENDER_JOB"] = "0" + environment["AYON_REMOTE_PUBLISH"] = "0" + environment["AYON_BUNDLE_NAME"] = os.environ["AYON_BUNDLE_NAME"] + deadline_plugin = "Ayon" + else: + environment["OPENPYPE_PUBLISH_JOB"] = "1" + environment["OPENPYPE_RENDER_JOB"] = "0" + environment["OPENPYPE_REMOTE_PUBLISH"] = "0" + deadline_plugin = "OpenPype" + # Add OpenPype version if we are running from build. + if is_running_from_build(): + self.environ_keys.append("OPENPYPE_VERSION") + + # 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.environ_job_filter + job_environ = job["Props"].get("Env", {}) + 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] + + # Add mongo url if it's enabled + if instance.context.data.get("deadlinePassMongoUrl"): + mongo_url = os.environ.get("OPENPYPE_MONGO") + if mongo_url: + environment["OPENPYPE_MONGO"] = mongo_url + + priority = self.deadline_priority or instance.data.get("priority", 50) + + instance_settings = self.get_attr_values_from_data(instance.data) + initial_status = instance_settings.get("publishJobState", "Active") + # TODO: Remove this backwards compatibility of `suspend_publish` + if instance.data.get("suspend_publish"): + initial_status = "Suspended" + + args = [ + "--headless", + 'publish', + '"{}"'.format(rootless_metadata_path), + "--targets", "deadline", + "--targets", "farm" + ] + + if is_in_tests(): + args.append("--automatic-tests") + + # Generate the payload for Deadline submission + secondary_pool = ( + self.deadline_pool_secondary or instance.data.get("secondaryPool") + ) + payload = { + "JobInfo": { + "Plugin": deadline_plugin, + "BatchName": job["Props"]["Batch"], + "Name": job_name, + "UserName": job["Props"]["User"], + "Comment": instance.context.data.get("comment", ""), + + "Department": self.deadline_department, + "ChunkSize": self.deadline_chunk_size, + "Priority": priority, + "InitialStatus": initial_status, + + "Group": self.deadline_group, + "Pool": self.deadline_pool or instance.data.get("primaryPool"), + "SecondaryPool": secondary_pool, + # ensure the outputdirectory with correct slashes + "OutputDirectory0": output_dir.replace("\\", "/") + }, + "PluginInfo": { + "Version": self.plugin_pype_version, + "Arguments": " ".join(args), + "SingleFrameOnly": "True", + }, + # Mandatory for Deadline, may be empty + "AuxFiles": [], + } + + if job.get("_id"): + payload["JobInfo"]["JobDependency0"] = job["_id"] + + 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) + + self.log.debug("Submitting Deadline publish job ...") + + url = "{}/api/jobs".format(self.deadline_url) + response = requests.post(url, json=payload, timeout=10) + if not response.ok: + raise Exception(response.text) + + deadline_publish_job_id = response.json()["_id"] + + return deadline_publish_job_id + + def process(self, instance): + # type: (pyblish.api.Instance) -> None + """Process plugin. + + Detect type of render farm submission and create and post dependent + job in case of Deadline. It creates json file with metadata needed for + publishing in directory of render. + + Args: + instance (pyblish.api.Instance): Instance data. + + """ + if not instance.data.get("farm"): + self.log.debug("Skipping local instance.") + return + + anatomy = instance.context.data["anatomy"] + + instance_skeleton_data = create_skeleton_instance_cache(instance) + """ + if content of `expectedFiles` list are dictionaries, we will handle + it as list of AOVs, creating instance for every one of them. + + Example: + -------- + + expectedFiles = [ + { + "beauty": [ + "foo_v01.0001.exr", + "foo_v01.0002.exr" + ], + + "Z": [ + "boo_v01.0001.exr", + "boo_v01.0002.exr" + ] + } + ] + + This will create instances for `beauty` and `Z` subset + adding those files to their respective representations. + + If we have only list of files, we collect all file sequences. + More then one doesn't probably make sense, but we'll handle it + like creating one instance with multiple representations. + + Example: + -------- + + expectedFiles = [ + "foo_v01.0001.exr", + "foo_v01.0002.exr", + "xxx_v01.0001.exr", + "xxx_v01.0002.exr" + ] + + This will result in one instance with two representations: + `foo` and `xxx` + """ + + if isinstance(instance.data.get("expectedFiles")[0], dict): + instances = create_instances_for_cache( + instance, instance_skeleton_data) + else: + representations = prepare_cache_representations( + instance_skeleton_data, + instance.data.get("expectedFiles"), + anatomy + ) + + if "representations" not in instance_skeleton_data.keys(): + instance_skeleton_data["representations"] = [] + + # add representation + instance_skeleton_data["representations"] += representations + instances = [instance_skeleton_data] + + # attach instances to subset + if instance.data.get("attachTo"): + instances = attach_instances_to_subset( + instance.data.get("attachTo"), instances + ) + + r''' SUBMiT PUBLiSH JOB 2 D34DLiN3 + ____ + ' ' .---. .---. .--. .---. .--..--..--..--. .---. + | | --= \ | . \/ _|/ \| . \ || || \ |/ _| + | JOB | --= / | | || __| .. | | | |;_ || \ || __| + | | |____./ \.__|._||_.|___./|_____|||__|\__|\.___| + ._____. + + ''' + + render_job = None + submission_type = "" + if instance.data.get("toBeRenderedOn") == "deadline": + render_job = instance.data.pop("deadlineSubmissionJob", None) + submission_type = "deadline" + + if not render_job: + import getpass + + render_job = {} + self.log.debug("Faking job data ...") + render_job["Props"] = {} + # Render job doesn't exist because we do not have prior submission. + # We still use data from it so lets fake it. + # + # Batch name reflect original scene name + + if instance.data.get("assemblySubmissionJobs"): + render_job["Props"]["Batch"] = instance.data.get( + "jobBatchName") + else: + batch = os.path.splitext(os.path.basename( + instance.context.data.get("currentFile")))[0] + render_job["Props"]["Batch"] = batch + # User is deadline user + render_job["Props"]["User"] = instance.context.data.get( + "deadlineUser", getpass.getuser()) + + deadline_publish_job_id = None + if submission_type == "deadline": + # get default deadline webservice url from deadline module + self.deadline_url = instance.context.data["defaultDeadline"] + # if custom one is set in instance, use that + if instance.data.get("deadlineUrl"): + self.deadline_url = instance.data.get("deadlineUrl") + assert self.deadline_url, "Requires Deadline Webservice URL" + + deadline_publish_job_id = \ + self._submit_deadline_post_job(instance, render_job) + + # Inject deadline url to instances. + for inst in instances: + inst["deadlineUrl"] = self.deadline_url + + # publish job file + publish_job = { + "asset": instance_skeleton_data["asset"], + "frameStart": instance_skeleton_data["frameStart"], + "frameEnd": instance_skeleton_data["frameEnd"], + "fps": instance_skeleton_data["fps"], + "source": instance_skeleton_data["source"], + "user": instance.context.data["user"], + "version": instance.context.data["version"], # workfile version + "intent": instance.context.data.get("intent"), + "comment": instance.context.data.get("comment"), + "job": render_job or None, + "session": legacy_io.Session.copy(), + "instances": instances + } + + if deadline_publish_job_id: + publish_job["deadline_publish_job_id"] = deadline_publish_job_id + + metadata_path, rootless_metadata_path = \ + create_metadata_path(instance, anatomy) + + with open(metadata_path, "w") as f: + json.dump(publish_job, f, indent=4, sort_keys=True) + + def _get_publish_folder(self, anatomy, template_data, + asset, subset, context, + family, version=None): + """ + Extracted logic to pre-calculate real publish folder, which is + calculated in IntegrateNew inside of Deadline process. + This should match logic in: + 'collect_anatomy_instance_data' - to + get correct anatomy, family, version for subset and + 'collect_resources_path' + get publish_path + + Args: + anatomy (openpype.pipeline.anatomy.Anatomy): + template_data (dict): pre-calculated collected data for process + asset (string): asset name + subset (string): subset name (actually group name of subset) + family (string): for current deadline process it's always 'render' + TODO - for generic use family needs to be dynamically + calculated like IntegrateNew does + version (int): override version from instance if exists + + Returns: + (string): publish folder where rendered and published files will + be stored + based on 'publish' template + """ + + project_name = context.data["projectName"] + if not version: + version = get_last_version_by_subset_name( + project_name, + subset, + asset_name=asset + ) + if version: + version = int(version["name"]) + 1 + else: + version = get_versioning_start( + project_name, + template_data["app"], + task_name=template_data["task"]["name"], + task_type=template_data["task"]["type"], + family="render", + subset=subset, + project_settings=context.data["project_settings"] + ) + + host_name = context.data["hostName"] + task_info = template_data.get("task") or {} + + template_name = publish.get_publish_template_name( + project_name, + host_name, + family, + task_info.get("name"), + task_info.get("type"), + ) + + template_data["subset"] = subset + template_data["family"] = family + template_data["version"] = version + + render_templates = anatomy.templates_obj[template_name] + if "folder" in render_templates: + publish_folder = render_templates["folder"].format_strict( + template_data + ) + else: + # solve deprecated situation when `folder` key is not underneath + # `publish` anatomy + self.log.warning(( + "Deprecation warning: Anatomy does not have set `folder`" + " key underneath `publish` (in global of for project `{}`)." + ).format(project_name)) + + file_path = render_templates["path"].format_strict(template_data) + publish_folder = os.path.dirname(file_path) + + return publish_folder + + @classmethod + def get_attribute_defs(cls): + return [ + EnumDef("publishJobState", + label="Publish Job State", + items=["Active", "Suspended"], + default="Active") + ] diff --git a/openpype/modules/deadline/plugins/publish/validate_deadline_pools.py b/openpype/modules/deadline/plugins/publish/validate_deadline_pools.py index 949caff7d8..90b8241803 100644 --- a/openpype/modules/deadline/plugins/publish/validate_deadline_pools.py +++ b/openpype/modules/deadline/plugins/publish/validate_deadline_pools.py @@ -22,7 +22,8 @@ class ValidateDeadlinePools(OptionalPyblishPluginMixin, "render.frames_farm", "renderFarm", "renderlayer", - "maxrender"] + "maxrender", + "publish.hou"] optional = True # cache diff --git a/openpype/pipeline/farm/pyblish_functions.py b/openpype/pipeline/farm/pyblish_functions.py index fe3ab97de8..33ec770be0 100644 --- a/openpype/pipeline/farm/pyblish_functions.py +++ b/openpype/pipeline/farm/pyblish_functions.py @@ -744,6 +744,238 @@ def get_resources(project_name, version, extension=None): return resources +def create_skeleton_instance_cache(instance): + # type: (pyblish.api.Instance, list, dict) -> dict + """Create skeleton instance from original instance data. + + This will create dictionary containing skeleton + - common - data used for publishing rendered instances. + This skeleton instance is then extended with additional data + and serialized to be processed by farm job. + + Args: + instance (pyblish.api.Instance): Original instance to + be used as a source of data. + + Returns: + dict: Dictionary with skeleton instance data. + + """ + # list of family names to transfer to new family if present + + context = instance.context + data = instance.data.copy() + anatomy = instance.context.data["anatomy"] # type: Anatomy + + # get time related data from instance (or context) + time_data = get_time_data_from_instance_or_context(instance) + + if data.get("extendFrames", False): + time_data.start, time_data.end = extend_frames( + data["asset"], + data["subset"], + time_data.start, + time_data.end, + ) + + source = data.get("source") or context.data.get("currentFile") + success, rootless_path = ( + anatomy.find_root_template_from_path(source) + ) + if success: + source = rootless_path + else: + # `rootless_path` is not set to `source` if none of roots match + log = Logger.get_logger("farm_publishing") + log.warning(("Could not find root path for remapping \"{}\". " + "This may cause issues.").format(source)) + + family = instance.data["family"] + # Make sure "render" is in the families to go through + # validating expected and rendered files + # during publishing job. + families = ["render", family] + + instance_skeleton_data = { + "family": family, + "subset": data["subset"], + "families": families, + "asset": data["asset"], + "frameStart": time_data.start, + "frameEnd": time_data.end, + "handleStart": time_data.handle_start, + "handleEnd": time_data.handle_end, + "frameStartHandle": time_data.start - time_data.handle_start, + "frameEndHandle": time_data.end + time_data.handle_end, + "comment": data.get("comment"), + "fps": time_data.fps, + "source": source, + "extendFrames": data.get("extendFrames"), + "overrideExistingFrame": data.get("overrideExistingFrame"), + "jobBatchName": data.get("jobBatchName", ""), + # map inputVersions `ObjectId` -> `str` so json supports it + "inputVersions": list(map(str, data.get("inputVersions", []))), + } + + # skip locking version if we are creating v01 + instance_version = data.get("version") # take this if exists + if instance_version != 1: + instance_skeleton_data["version"] = instance_version + + representations = get_transferable_representations(instance) + instance_skeleton_data["representations"] = representations + + persistent = instance.data.get("stagingDir_persistent") is True + instance_skeleton_data["stagingDir_persistent"] = persistent + + return instance_skeleton_data + + +def prepare_cache_representations(skeleton_data, exp_files, anatomy): + """Create representations for file sequences. + + This will return representations of expected files if they are not + in hierarchy of aovs. There should be only one sequence of files for + most cases, but if not - we create representation from each of them. + + Arguments: + skeleton_data (dict): instance data for which we are + setting representations + exp_files (list): list of expected files + anatomy (Anatomy) + Returns: + list of representations + + """ + representations = [] + collections, remainders = clique.assemble(exp_files) + + log = Logger.get_logger("farm_publishing") + + # create representation for every collected sequence + for collection in collections: + ext = collection.tail.lstrip(".") + + staging = os.path.dirname(list(collection)[0]) + success, rootless_staging_dir = ( + anatomy.find_root_template_from_path(staging) + ) + if success: + staging = rootless_staging_dir + else: + log.warning(( + "Could not find root path for remapping \"{}\"." + " This may cause issues on farm." + ).format(staging)) + + frame_start = int(skeleton_data.get("frameStartHandle")) + rep = { + "name": ext, + "ext": ext, + "files": [os.path.basename(f) for f in list(collection)], + "frameStart": frame_start, + "frameEnd": int(skeleton_data.get("frameEndHandle")), + # If expectedFile are absolute, we need only filenames + "stagingDir": staging, + "fps": skeleton_data.get("fps") + } + + representations.append(rep) + + return representations + + +def create_instances_for_cache(instance, skeleton): + """Create instance for cache. + + This will create new instance for every AOV it can detect in expected + files list. + + Args: + instance (pyblish.api.Instance): Original instance. + skeleton (dict): Skeleton data for instance (those needed) later + by collector. + + + Returns: + list of instances + + Throws: + ValueError: + + """ + anatomy = instance.context.data["anatomy"] + subset = skeleton["subset"] + family = skeleton["family"] + exp_files = instance.data["expectedFiles"] + log = Logger.get_logger("farm_publishing") + + instances = [] + # go through AOVs in expected files + for _, files in exp_files[0].items(): + cols, rem = clique.assemble(files) + # we shouldn't have any reminders. And if we do, it should + # be just one item for single frame renders. + if not cols and rem: + if len(rem) != 1: + raise ValueError("Found multiple non related files " + "to render, don't know what to do " + "with them.") + col = rem[0] + ext = os.path.splitext(col)[1].lstrip(".") + else: + # but we really expect only one collection. + # Nothing else make sense. + if len(cols) != 1: + raise ValueError("Only one image sequence type is expected.") # noqa: E501 + ext = cols[0].tail.lstrip(".") + col = list(cols[0]) + + if isinstance(col, (list, tuple)): + staging = os.path.dirname(col[0]) + else: + staging = os.path.dirname(col) + + try: + staging = remap_source(staging, anatomy) + except ValueError as e: + log.warning(e) + + new_instance = deepcopy(skeleton) + + new_instance["subset"] = subset + log.info("Creating data for: {}".format(subset)) + new_instance["family"] = family + new_instance["families"] = skeleton["families"] + # create representation + if isinstance(col, (list, tuple)): + files = [os.path.basename(f) for f in col] + else: + files = os.path.basename(col) + + rep = { + "name": ext, + "ext": ext, + "files": files, + "frameStart": int(skeleton["frameStartHandle"]), + "frameEnd": int(skeleton["frameEndHandle"]), + # If expectedFile are absolute, we need only filenames + "stagingDir": staging, + "fps": new_instance.get("fps"), + "tags": [], + } + + new_instance["representations"] = [rep] + + # if extending frames from existing version, copy files from there + # into our destination directory + if new_instance.get("extendFrames", False): + copy_extend_frames(new_instance, rep) + instances.append(new_instance) + log.debug("instances:{}".format(instances)) + return instances + + def copy_extend_frames(instance, representation): """Copy existing frames from latest version. diff --git a/openpype/settings/defaults/project_settings/deadline.json b/openpype/settings/defaults/project_settings/deadline.json index 1b8c8397d7..3becb4e32d 100644 --- a/openpype/settings/defaults/project_settings/deadline.json +++ b/openpype/settings/defaults/project_settings/deadline.json @@ -99,6 +99,14 @@ "deadline_chunk_size": 10, "deadline_job_delay": "00:00:00:00" }, + "ProcessSubmittedCacheJobOnFarm": { + "enabled": true, + "deadline_department": "", + "deadline_pool": "", + "deadline_group": "", + "deadline_chunk_size": 1, + "deadline_priority": 50 + }, "ProcessSubmittedJobOnFarm": { "enabled": true, "deadline_department": "", diff --git a/openpype/settings/defaults/project_settings/houdini.json b/openpype/settings/defaults/project_settings/houdini.json index 93d5c50d5e..c0052185e8 100644 --- a/openpype/settings/defaults/project_settings/houdini.json +++ b/openpype/settings/defaults/project_settings/houdini.json @@ -81,6 +81,11 @@ } }, "publish": { + "CollectChunkSize": { + "enabled": true, + "optional": true, + "chunk_size": 999999 + }, "ValidateWorkfilePaths": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json index b57089007e..e2f1be8e3e 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json @@ -4,6 +4,31 @@ "key": "publish", "label": "Publish plugins", "children": [ + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "CollectChunkSize", + "label": "Collect Chunk Size", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "number", + "key": "chunk_size", + "label": "Frames Per Task" + } + ] + }, { "type": "dict", "collapsible": true, diff --git a/server_addon/deadline/server/settings/publish_plugins.py b/server_addon/deadline/server/settings/publish_plugins.py index 8d1b667345..2a60ab4aa8 100644 --- a/server_addon/deadline/server/settings/publish_plugins.py +++ b/server_addon/deadline/server/settings/publish_plugins.py @@ -217,6 +217,17 @@ class AOVFilterSubmodel(BaseSettingsModel): ) +class ProcessCacheJobFarmModel(BaseSettingsModel): + """Process submitted job on farm.""" + + enabled: bool = Field(title="Enabled") + deadline_department: str = Field(title="Department") + deadline_pool: str = Field(title="Pool") + deadline_group: str = Field(title="Group") + deadline_chunk_size: int = Field(title="Chunk Size") + deadline_priority: int = Field(title="Priority") + + class ProcessSubmittedJobOnFarmModel(BaseSettingsModel): """Process submitted job on farm.""" @@ -278,6 +289,9 @@ class PublishPluginsModel(BaseSettingsModel): default_factory=CelactionSubmitDeadlineModel, title="Celaction Submit Deadline" ) + ProcessSubmittedCacheJobOnFarm: ProcessCacheJobFarmModel = Field( + default_factory=ProcessCacheJobFarmModel, + title="Process submitted cache Job on farm.") ProcessSubmittedJobOnFarm: ProcessSubmittedJobOnFarmModel = Field( default_factory=ProcessSubmittedJobOnFarmModel, title="Process submitted job on farm.") @@ -384,6 +398,14 @@ DEFAULT_DEADLINE_PLUGINS_SETTINGS = { "deadline_chunk_size": 10, "deadline_job_delay": "00:00:00:00" }, + "ProcessSubmittedCacheJobOnFarm": { + "enabled": True, + "deadline_department": "", + "deadline_pool": "", + "deadline_group": "", + "deadline_chunk_size": 1, + "deadline_priority": 50 + }, "ProcessSubmittedJobOnFarm": { "enabled": True, "deadline_department": "", diff --git a/server_addon/deadline/server/version.py b/server_addon/deadline/server/version.py index 485f44ac21..b3f4756216 100644 --- a/server_addon/deadline/server/version.py +++ b/server_addon/deadline/server/version.py @@ -1 +1 @@ -__version__ = "0.1.1" +__version__ = "0.1.2" diff --git a/server_addon/houdini/server/settings/publish_plugins.py b/server_addon/houdini/server/settings/publish_plugins.py index 4534d8d0d9..e3092c103e 100644 --- a/server_addon/houdini/server/settings/publish_plugins.py +++ b/server_addon/houdini/server/settings/publish_plugins.py @@ -107,6 +107,12 @@ DEFAULT_HOUDINI_CREATE_SETTINGS = { # Publish Plugins +class CollectChunkSizeModel(BaseSettingsModel): + enabled: bool = Field(title="Enabled") + optional: bool = Field(title="Optional") + chunk_size: int = Field(title="Frame Per Task") + + class ValidateWorkfilePathsModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") optional: bool = Field(title="Optional") @@ -127,6 +133,10 @@ class BasicValidateModel(BaseSettingsModel): class PublishPluginsModel(BaseSettingsModel): + CollectChunkSize: CollectChunkSizeModel = Field( + default_factory=CollectChunkSizeModel, + title="Collect Chunk Size" + ) ValidateWorkfilePaths: ValidateWorkfilePathsModel = Field( default_factory=ValidateWorkfilePathsModel, title="Validate workfile paths settings.") @@ -139,6 +149,11 @@ class PublishPluginsModel(BaseSettingsModel): DEFAULT_HOUDINI_PUBLISH_SETTINGS = { + "CollectChunkSize": { + "enabled": True, + "optional": True, + "chunk_size": 999999 + }, "ValidateWorkfilePaths": { "enabled": True, "optional": True, diff --git a/website/docs/artist_hosts_houdini.md b/website/docs/artist_hosts_houdini.md index 940d5ac351..c4e8293c36 100644 --- a/website/docs/artist_hosts_houdini.md +++ b/website/docs/artist_hosts_houdini.md @@ -83,6 +83,30 @@ select your render camera. All the render outputs are stored in the pyblish/render directory within your project path.\ For Karma-specific render, it also outputs the USD render as default. +## Publishing cache to Deadline +Artist can publish cache to deadline which increases productivity as artist can use local machine +could be used for other tasks. +Caching on the farm is supported for: + +**Arnold ASS (.ass)** +**Pointcache (.bgeo and .abc)** +**VDB (.vdb)** +**Redshift Proxy (.rs)** + +To submit your cache to deadline, you need to create the instance(s) with clicking +**Submitting to Farm** and you can also enable **Use selection** to +select the object for caching in farm. +![Houdini Farm Cache Creator](assets/houdini_farm_cache_creator.png) + +When you go to Publish Tab and click the instance(s), you can set up your preferred +**Frame per task**. +![Houdini Farm Per Task](assets/houdini_frame_per_task.png) + +Once you hit **Publish**, the cache would be submitted and rendered in deadline. +When the render is finished, all the caches would be located in your publish folder. +You can see them in the Loader. +![Houdini Farm Per Task](assets/houdini_farm_cache_loader.png) + ## USD (experimental support) ### Publishing USD You can publish your Solaris Stage as USD file. diff --git a/website/docs/assets/houdini_farm_cache_creator.png b/website/docs/assets/houdini_farm_cache_creator.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0af8033614d37d8e988bf1b060ce17bc07b085 GIT binary patch literal 95572 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 Z5bNbauk6me<0ZB`p9u~>B|3TG`d_-PdpH09 literal 0 HcmV?d00001 diff --git a/website/docs/assets/houdini_farm_cache_loader.png b/website/docs/assets/houdini_farm_cache_loader.png new file mode 100644 index 0000000000000000000000000000000000000000..27b0122fab3e2f1b0509148fd1c7c00246c63264 GIT binary patch literal 134816 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

tWIr~7{r5kDaf^&o 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 literal 0 HcmV?d00001 diff --git a/website/docs/assets/houdini_frame_per_task.png b/website/docs/assets/houdini_frame_per_task.png new file mode 100644 index 0000000000000000000000000000000000000000..a7d8b33114e640499c892657fcd9ec9f3a79ef3c GIT binary patch literal 59257 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 Kjy4>*aO-bXs4lty literal 0 HcmV?d00001 From 82b75d53b319c2b7ddbc3da7b3773154a255a88a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 15:03:58 +0800 Subject: [PATCH 039/690] update the latest lib --- openpype/hosts/houdini/api/lib.py | 48 ++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index 856e7abbd3..1ab38ae2c1 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -141,7 +141,6 @@ def get_output_parameter(node): elif node_type == "ifd": if node.evalParm("soho_outputmode"): return node.parm("soho_diskfile") - raise TypeError("Node type '%s' not supported" % node_type) @@ -652,3 +651,50 @@ def get_color_management_preferences(): "display": hou.Color.ocio_defaultDisplay(), "view": hou.Color.ocio_defaultView() } + + +def get_resolution_from_doc(doc): + """Get resolution from the given asset document. """ + + if not doc or "data" not in doc: + print("Entered document is not valid. \"{}\"".format(str(doc))) + return None + + resolution_width = doc["data"].get("resolutionWidth") + resolution_height = doc["data"].get("resolutionHeight") + + # Make sure both width and height are set + if resolution_width is None or resolution_height is None: + print("No resolution information found for \"{}\"".format(doc["name"])) + return None + + return int(resolution_width), int(resolution_height) + + +def set_camera_resolution(camera, asset_doc=None): + """Apply resolution to camera from asset document of the publish""" + + if not asset_doc: + asset_doc = get_current_project_asset() + + resolution = get_resolution_from_doc(asset_doc) + + if resolution: + print("Setting camera resolution: {} -> {}x{}".format( + camera.name(), resolution[0], resolution[1] + )) + camera.parm("resx").set(resolution[0]) + camera.parm("resy").set(resolution[1]) + + +def get_camera_from_container(container): + """Get camera from container node. """ + + cameras = container.recursiveGlob( + "*", + filter=hou.nodeTypeFilter.ObjCamera, + include_subnets=False + ) + + assert len(cameras) == 1, "Camera instance must have only one camera" + return cameras[0] From 6ab3f2d0a9fc3599461b7ea3ad052956b2bcad7a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 15:05:44 +0800 Subject: [PATCH 040/690] update to exlcude unncessary codes --- .../hosts/houdini/plugins/load/load_camera.py | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/openpype/hosts/houdini/plugins/load/load_camera.py b/openpype/hosts/houdini/plugins/load/load_camera.py index 7b4a04809e..e16146a267 100644 --- a/openpype/hosts/houdini/plugins/load/load_camera.py +++ b/openpype/hosts/houdini/plugins/load/load_camera.py @@ -4,6 +4,13 @@ from openpype.pipeline import ( ) from openpype.hosts.houdini.api import pipeline +from openpype.hosts.houdini.api.lib import ( + set_camera_resolution, + get_camera_from_container +) + +import hou + ARCHIVE_EXPRESSION = ('__import__("_alembic_hom_extensions")' '.alembicGetCameraDict') @@ -25,7 +32,15 @@ def transfer_non_default_values(src, dest, ignore=None): channel expression and ignore certain Parm types. """ - import hou + + ignore_types = { + hou.parmTemplateType.Toggle, + hou.parmTemplateType.Menu, + hou.parmTemplateType.Button, + hou.parmTemplateType.FolderSet, + hou.parmTemplateType.Separator, + hou.parmTemplateType.Label, + } src.updateParmStates() @@ -62,14 +77,6 @@ def transfer_non_default_values(src, dest, ignore=None): continue # Ignore folders, separators, etc. - ignore_types = { - hou.parmTemplateType.Toggle, - hou.parmTemplateType.Menu, - hou.parmTemplateType.Button, - hou.parmTemplateType.FolderSet, - hou.parmTemplateType.Separator, - hou.parmTemplateType.Label, - } if parm.parmTemplate().type() in ignore_types: continue @@ -90,13 +97,8 @@ class CameraLoader(load.LoaderPlugin): def load(self, context, name=None, namespace=None, data=None): - import os - import hou - # Format file name, Houdini only wants forward slashes - file_path = self.filepath_from_context(context) - file_path = os.path.normpath(file_path) - file_path = file_path.replace("\\", "/") + file_path = self.filepath_from_context(context).replace("\\", "/") # Get the root node obj = hou.node("/obj") @@ -106,19 +108,21 @@ class CameraLoader(load.LoaderPlugin): node_name = "{}_{}".format(namespace, name) if namespace else name # Create a archive node - container = self.create_and_connect(obj, "alembicarchive", node_name) + node = self.create_and_connect(obj, "alembicarchive", node_name) # TODO: add FPS of project / asset - container.setParms({"fileName": file_path, - "channelRef": True}) + node.setParms({"fileName": file_path, "channelRef": True}) # Apply some magic - container.parm("buildHierarchy").pressButton() - container.moveToGoodPosition() + node.parm("buildHierarchy").pressButton() + node.moveToGoodPosition() # Create an alembic xform node - nodes = [container] + nodes = [node] + camera = get_camera_from_container(node) + self._match_maya_render_mask(camera) + set_camera_resolution(camera, asset_doc=context["asset"]) self[:] = nodes return pipeline.containerise(node_name, @@ -143,14 +147,14 @@ class CameraLoader(load.LoaderPlugin): # Store the cam temporarily next to the Alembic Archive # so that we can preserve parm values the user set on it # after build hierarchy was triggered. - old_camera = self._get_camera(node) + old_camera = get_camera_from_container(node) temp_camera = old_camera.copyTo(node.parent()) # Rebuild node.parm("buildHierarchy").pressButton() # Apply values to the new camera - new_camera = self._get_camera(node) + new_camera = get_camera_from_container(node) transfer_non_default_values(temp_camera, new_camera, # The hidden uniform scale attribute @@ -158,6 +162,9 @@ class CameraLoader(load.LoaderPlugin): # "icon_scale" just skip that completely ignore={"scale"}) + self._match_maya_render_mask(new_camera) + set_camera_resolution(new_camera) + temp_camera.destroy() def remove(self, container): @@ -165,15 +172,6 @@ class CameraLoader(load.LoaderPlugin): node = container["node"] node.destroy() - def _get_camera(self, node): - import hou - cameras = node.recursiveGlob("*", - filter=hou.nodeTypeFilter.ObjCamera, - include_subnets=False) - - assert len(cameras) == 1, "Camera instance must have only one camera" - return cameras[0] - def create_and_connect(self, node, node_type, name=None): """Create a node within a node which and connect it to the input @@ -194,5 +192,20 @@ class CameraLoader(load.LoaderPlugin): new_node.moveToGoodPosition() return new_node - def switch(self, container, representation): - self.update(container, representation) + def _match_maya_render_mask(self, camera): + """Workaround to match Maya render mask in Houdini""" + + # print("Setting match maya render mask ") + parm = camera.parm("aperture") + expression = parm.expression() + expression = expression.replace("return ", "aperture = ") + expression += """ +# Match maya render mask (logic from Houdini's own FBX importer) +node = hou.pwd() +resx = node.evalParm('resx') +resy = node.evalParm('resy') +aspect = node.evalParm('aspect') +aperture *= min(1, (resx / resy * aspect) / 1.5) +return aperture +""" + parm.setExpression(expression, language=hou.exprLanguage.Python) From 7a765bd52836f50f90088d7738990130da957bcb Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 20:09:59 +0800 Subject: [PATCH 041/690] mustafa's comment on deadline plugin and fix the bug of not getting right env variable --- .../publish/submit_houdini_cache_deadline.py | 2 - .../publish/submit_publish_cache_job.py | 2 +- .../schema_project_deadline.json | 40 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index b1717d09ee..985f29a814 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -128,8 +128,6 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline if not value: continue job_info.EnvironmentKeyValue[key] = value - # to recognize render jobs - job_info.add_render_job_env_var() return job_info diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py index 5651ff4c83..f8e4613b1c 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -239,7 +239,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, self.log.debug("Submitting Deadline publish job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10) + response = requests.post(url, json=payload, timeout=10, verify=False) if not response.ok: raise Exception(response.text) diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json index 6d59b5a92b..4e582209bb 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_deadline.json @@ -531,6 +531,46 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "ProcessSubmittedCacheJobOnFarm", + "label": "ProcessSubmittedCacheJobOnFarm", + "checkbox_key": "enabled", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "text", + "key": "deadline_department", + "label": "Deadline department" + }, + { + "type": "text", + "key": "deadline_pool", + "label": "Deadline Pool" + }, + { + "type": "text", + "key": "deadline_group", + "label": "Deadline Group" + }, + { + "type": "number", + "key": "deadline_chunk_size", + "label": "Deadline Chunk Size" + }, + { + "type": "number", + "key": "deadline_priority", + "label": "Deadline Priotity" + } + ] + }, { "type": "dict", "collapsible": true, From 98cc7357d30bc1966c8c48d7604dcac3d7ee0c70 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 22:44:38 +0800 Subject: [PATCH 042/690] make sure all the necessary environment variables needed to be there --- .../plugins/publish/submit_houdini_cache_deadline.py | 12 +++++++++--- .../plugins/publish/submit_publish_cache_job.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index 985f29a814..f3b4d37a0f 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -108,9 +108,13 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline job_info.Group = attr_values.get("group", self.group) keys = [ - "FTRACK_API_USER", - "FTRACK_API_KEY", - "FTRACK_SERVER" + "OPENPYPE_SG_USER", + "AVALON_PROJECT", + "AVALON_ASSET", + "AVALON_TASK", + "AVALON_APP_NAME", + "OPENPYPE_DEV", + "OPENPYPE_LOG_NO_COLORS", ] # Add OpenPype version if we are running from build. @@ -128,6 +132,8 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline if not value: continue job_info.EnvironmentKeyValue[key] = value + # to recognize render jobs + job_info.add_render_job_env_var() return job_info diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py index f8e4613b1c..5651ff4c83 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -239,7 +239,7 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, self.log.debug("Submitting Deadline publish job ...") url = "{}/api/jobs".format(self.deadline_url) - response = requests.post(url, json=payload, timeout=10, verify=False) + response = requests.post(url, json=payload, timeout=10) if not response.ok: raise Exception(response.text) From 559e49abccd8bbed9920a069b945ac1d8004c95a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 21 Sep 2023 23:41:54 +0800 Subject: [PATCH 043/690] add ftrack and kitsu environments --- .../plugins/publish/submit_houdini_cache_deadline.py | 3 +++ .../deadline/plugins/publish/submit_publish_cache_job.py | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py index f3b4d37a0f..2b6231e916 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_cache_deadline.py @@ -108,6 +108,9 @@ class HoudiniCacheSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline job_info.Group = attr_values.get("group", self.group) keys = [ + "FTRACK_API_KEY", + "FTRACK_API_USER", + "FTRACK_SERVER", "OPENPYPE_SG_USER", "AVALON_PROJECT", "AVALON_ASSET", diff --git a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py index 5651ff4c83..b2ebebc303 100644 --- a/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py +++ b/openpype/modules/deadline/plugins/publish/submit_publish_cache_job.py @@ -70,9 +70,14 @@ class ProcessSubmittedCacheJobOnFarm(pyblish.api.InstancePlugin, ] environ_keys = [ + "FTRACK_API_USER", + "FTRACK_API_KEY", + "FTRACK_SERVER", "AVALON_APP_NAME", "OPENPYPE_USERNAME", "OPENPYPE_SG_USER", + "KITSU_LOGIN", + "KITSU_PWD" ] # custom deadline attributes From 759dc59132bc32ce07b6f204c8da7df8ae9f2715 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 29 Sep 2023 17:33:27 +0200 Subject: [PATCH 044/690] add clip to timeline in correct place --- openpype/hosts/resolve/api/lib.py | 9 ++++++++- openpype/hosts/resolve/api/plugin.py | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index eaee3bb9ba..4e8b3a4107 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -246,7 +246,8 @@ def get_media_pool_item(fpath, root: object = None) -> object: def create_timeline_item(media_pool_item: object, timeline: object = None, source_start: int = None, - source_end: int = None) -> object: + source_end: int = None, + timeline_in: int = None) -> object: """ Add media pool item to current or defined timeline. @@ -278,6 +279,12 @@ def create_timeline_item(media_pool_item: object, clip_data.update({"endFrame": source_end}) print(clip_data) + + if timeline_in: + timeline_start = timeline.GetStartFrame() + # Create a clipInfo dictionary with the necessary information + clip_data["recordFrame"] = int(timeline_start + timeline_in) + # add to timeline media_pool.AppendToTimeline([clip_data]) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index e2bd76ffa2..c679aa062d 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -402,6 +402,9 @@ class ClipLoader: if handle_end is None: handle_end = int(self.data["assetData"]["handleEnd"]) + self.timeline_in = int(self.data["assetData"]["clipIn"]) + + source_in = int(_clip_property("Start")) source_out = int(_clip_property("End")) @@ -416,7 +419,12 @@ class ClipLoader: # make track item from source in bin as item timeline_item = lib.create_timeline_item( - media_pool_item, self.active_timeline, source_in, source_out) + media_pool_item, + self.active_timeline, + source_in, + source_out, + self.timeline_in + ) print("Loading clips: `{}`".format(self.data["clip_name"])) return timeline_item From 7cd8be0afa68005bc615523fd4a0ee55f73e1a30 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 2 Oct 2023 11:49:51 +0200 Subject: [PATCH 045/690] resolve: add option for adding clips sequentially - or to asset define place - also create track with a name --- openpype/hosts/resolve/api/lib.py | 12 +++--- openpype/hosts/resolve/api/plugin.py | 55 +++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 4e8b3a4107..8f7eba8a90 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -274,17 +274,15 @@ def create_timeline_item(media_pool_item: object, # add source time range if input was given if source_start is not None: - clip_data.update({"startFrame": source_start}) + clip_data["startFrame"] = source_start if source_end is not None: - clip_data.update({"endFrame": source_end}) + clip_data["endFrame"] = source_end + + # Create a clipInfo dictionary with the necessary information + clip_data["recordFrame"] = timeline_in print(clip_data) - if timeline_in: - timeline_start = timeline.GetStartFrame() - # Create a clipInfo dictionary with the necessary information - clip_data["recordFrame"] = int(timeline_start + timeline_in) - # add to timeline media_pool.AppendToTimeline([clip_data]) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index c679aa062d..b1bde212fe 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -312,6 +312,9 @@ class ClipLoader: # try to get value from options or evaluate key value for `load_to` self.new_timeline = options.get("newTimeline") or bool( "New timeline" in options.get("load_to", "")) + # try to get value from options or evaluate key value for `load_how` + self.sequential_load = options.get("sequentially") or bool( + "Sequentially in order" in options.get("load_how", "")) assert self._populate_data(), str( "Cannot Load selected data, look into database " @@ -352,6 +355,7 @@ class ClipLoader: asset = str(repr_cntx["asset"]) subset = str(repr_cntx["subset"]) representation = str(repr_cntx["representation"]) + self.data["track_name"] = "{}_{}".format(asset, representation) self.data["clip_name"] = "_".join([asset, subset, representation]) self.data["versionData"] = self.context["version"]["data"] # gets file path @@ -383,6 +387,33 @@ class ClipLoader: asset_name = self.context["representation"]["context"]["asset"] self.data["assetData"] = get_current_project_asset(asset_name)["data"] + def _set_active_track(self): + """ Set active track to `track` """ + track_type = "video" + track_name = self.data["track_name"] + track_exists = False + + # get total track count + track_count = self.active_timeline.GetTrackCount(track_type) + # loop all tracks by track indexes + for track_index in range(1, int(track_count) + 1): + # get current track name + _track_name = self.active_timeline.GetTrackName( + track_type, track_index) + if track_name != _track_name: + continue + track_exists = True + break + + if not track_exists: + self.active_timeline.AddTrack(track_type) + self.active_timeline.SetTrackName( + track_type, + track_index + 1, + track_name + ) + + def load(self): # create project bin for the media to be imported into self.active_bin = lib.create_bin(self.data["binPath"]) @@ -402,8 +433,18 @@ class ClipLoader: if handle_end is None: handle_end = int(self.data["assetData"]["handleEnd"]) - self.timeline_in = int(self.data["assetData"]["clipIn"]) + # handle timeline tracks + self._set_active_track() + # get timeline in + timeline_start = self.active_timeline.GetStartFrame() + if self.sequential_load: + # set timeline start frame + timeline_in = int(timeline_start) + else: + # set timeline start frame + original clip in frame + timeline_in = int( + timeline_start + self.data["assetData"]["clipIn"]) source_in = int(_clip_property("Start")) source_out = int(_clip_property("End")) @@ -423,7 +464,7 @@ class ClipLoader: self.active_timeline, source_in, source_out, - self.timeline_in + timeline_in ) print("Loading clips: `{}`".format(self.data["clip_name"])) @@ -478,6 +519,16 @@ class TimelineItemLoader(LoaderPlugin): ], default=0, help="Where do you want clips to be loaded?" + ), + qargparse.Choice( + "load_how", + label="How to load clips", + items=[ + "Original timing", + "Sequentially in order" + ], + default="Original timing", + help="Would you like to place it at original timing?" ) ] From ec893d45e3e47ac95ec6f9d3ba16513c70009a78 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 2 Oct 2023 11:50:10 +0200 Subject: [PATCH 046/690] updating docs readme to latest python api --- ...0.4.txt => RESOLVE_API_v18.5.1-build6.txt} | 81 +++++++++++++++---- 1 file changed, 65 insertions(+), 16 deletions(-) rename openpype/hosts/resolve/{RESOLVE_API_v18.0.4.txt => RESOLVE_API_v18.5.1-build6.txt} (89%) diff --git a/openpype/hosts/resolve/RESOLVE_API_v18.0.4.txt b/openpype/hosts/resolve/RESOLVE_API_v18.5.1-build6.txt similarity index 89% rename from openpype/hosts/resolve/RESOLVE_API_v18.0.4.txt rename to openpype/hosts/resolve/RESOLVE_API_v18.5.1-build6.txt index 98597a12cb..7d1d6edf61 100644 --- a/openpype/hosts/resolve/RESOLVE_API_v18.0.4.txt +++ b/openpype/hosts/resolve/RESOLVE_API_v18.5.1-build6.txt @@ -1,4 +1,4 @@ -Updated as of 9 May 2022 +Updated as of 26 May 2023 ---------------------------- In this package, you will find a brief introduction to the Scripting API for DaVinci Resolve Studio. Apart from this README.txt file, this package contains folders containing the basic import modules for scripting access (DaVinciResolve.py) and some representative examples. @@ -19,7 +19,7 @@ DaVinci Resolve scripting requires one of the following to be installed (for all Lua 5.1 Python 2.7 64-bit - Python 3.6 64-bit + Python >= 3.6 64-bit Using a script @@ -171,6 +171,10 @@ Project GetRenderResolutions(format, codec) --> [{Resolution}] # Returns list of resolutions applicable for the given render format (string) and render codec (string). Returns full list of resolutions if no argument is provided. Each element in the list is a dictionary with 2 keys "Width" and "Height". RefreshLUTList() --> Bool # Refreshes LUT List GetUniqueId() --> string # Returns a unique ID for the project item + InsertAudioToCurrentTrackAtPlayhead(mediaPath, --> Bool # Inserts the media specified by mediaPath (string) with startOffsetInSamples (int) and durationInSamples (int) at the playhead on a selected track on the Fairlight page. Returns True if successful, otherwise False. + startOffsetInSamples, durationInSamples) + LoadBurnInPreset(presetName) --> Bool # Loads user defined data burn in preset for project when supplied presetName (string). Returns true if successful. + ExportCurrentFrameAsStill(filePath) --> Bool # Exports current frame as still to supplied filePath. filePath must end in valid export file format. Returns True if succssful, False otherwise. MediaStorage GetMountedVolumeList() --> [paths...] # Returns list of folder paths corresponding to mounted volumes displayed in Resolve’s Media Storage. @@ -179,6 +183,7 @@ MediaStorage RevealInStorage(path) --> Bool # Expands and displays given file/folder path in Resolve’s Media Storage. AddItemListToMediaPool(item1, item2, ...) --> [clips...] # Adds specified file/folder paths from Media Storage into current Media Pool folder. Input is one or more file/folder paths. Returns a list of the MediaPoolItems created. AddItemListToMediaPool([items...]) --> [clips...] # Adds specified file/folder paths from Media Storage into current Media Pool folder. Input is an array of file/folder paths. Returns a list of the MediaPoolItems created. + AddItemListToMediaPool([{itemInfo}, ...]) --> [clips...] # Adds list of itemInfos specified as dict of "media", "startFrame" (int), "endFrame" (int) from Media Storage into current Media Pool folder. Returns a list of the MediaPoolItems created. AddClipMattesToMediaPool(MediaPoolItem, [paths], stereoEye) --> Bool # Adds specified media files as mattes for the specified MediaPoolItem. StereoEye is an optional argument for specifying which eye to add the matte to for stereo clips ("left" or "right"). Returns True if successful. AddTimelineMattesToMediaPool([paths]) --> [MediaPoolItems] # Adds specified media files as timeline mattes in current media pool folder. Returns a list of created MediaPoolItems. @@ -189,20 +194,22 @@ MediaPool CreateEmptyTimeline(name) --> Timeline # Adds new timeline with given name. AppendToTimeline(clip1, clip2, ...) --> [TimelineItem] # Appends specified MediaPoolItem objects in the current timeline. Returns the list of appended timelineItems. AppendToTimeline([clips]) --> [TimelineItem] # Appends specified MediaPoolItem objects in the current timeline. Returns the list of appended timelineItems. - AppendToTimeline([{clipInfo}, ...]) --> [TimelineItem] # Appends list of clipInfos specified as dict of "mediaPoolItem", "startFrame" (int), "endFrame" (int), (optional) "mediaType" (int; 1 - Video only, 2 - Audio only). Returns the list of appended timelineItems. + AppendToTimeline([{clipInfo}, ...]) --> [TimelineItem] # Appends list of clipInfos specified as dict of "mediaPoolItem", "startFrame" (int), "endFrame" (int), (optional) "mediaType" (int; 1 - Video only, 2 - Audio only), "trackIndex" (int) and "recordFrame" (int). Returns the list of appended timelineItems. CreateTimelineFromClips(name, clip1, clip2,...) --> Timeline # Creates new timeline with specified name, and appends the specified MediaPoolItem objects. CreateTimelineFromClips(name, [clips]) --> Timeline # Creates new timeline with specified name, and appends the specified MediaPoolItem objects. - CreateTimelineFromClips(name, [{clipInfo}]) --> Timeline # Creates new timeline with specified name, appending the list of clipInfos specified as a dict of "mediaPoolItem", "startFrame" (int), "endFrame" (int). - ImportTimelineFromFile(filePath, {importOptions}) --> Timeline # Creates timeline based on parameters within given file and optional importOptions dict, with support for the keys: - # "timelineName": string, specifies the name of the timeline to be created - # "importSourceClips": Bool, specifies whether source clips should be imported, True by default + CreateTimelineFromClips(name, [{clipInfo}]) --> Timeline # Creates new timeline with specified name, appending the list of clipInfos specified as a dict of "mediaPoolItem", "startFrame" (int), "endFrame" (int), "recordFrame" (int). + ImportTimelineFromFile(filePath, {importOptions}) --> Timeline # Creates timeline based on parameters within given file (AAF/EDL/XML/FCPXML/DRT/ADL) and optional importOptions dict, with support for the keys: + # "timelineName": string, specifies the name of the timeline to be created. Not valid for DRT import + # "importSourceClips": Bool, specifies whether source clips should be imported, True by default. Not valid for DRT import # "sourceClipsPath": string, specifies a filesystem path to search for source clips if the media is inaccessible in their original path and if "importSourceClips" is True - # "sourceClipsFolders": List of Media Pool folder objects to search for source clips if the media is not present in current folder and if "importSourceClips" is False + # "sourceClipsFolders": List of Media Pool folder objects to search for source clips if the media is not present in current folder and if "importSourceClips" is False. Not valid for DRT import # "interlaceProcessing": Bool, specifies whether to enable interlace processing on the imported timeline being created. valid only for AAF import DeleteTimelines([timeline]) --> Bool # Deletes specified timelines in the media pool. GetCurrentFolder() --> Folder # Returns currently selected Folder. SetCurrentFolder(Folder) --> Bool # Sets current folder by given Folder. DeleteClips([clips]) --> Bool # Deletes specified clips or timeline mattes in the media pool + ImportFolderFromFile(filePath, sourceClipsPath="") --> Bool # Returns true if import from given DRB filePath is successful, false otherwise + # sourceClipsPath is a string that specifies a filesystem path to search for source clips if the media is inaccessible in their original path, empty by default DeleteFolders([subfolders]) --> Bool # Deletes specified subfolders in the media pool MoveClips([clips], targetFolder) --> Bool # Moves specified clips to target folder. MoveFolders([folders], targetFolder) --> Bool # Moves specified folders to target folder. @@ -225,6 +232,7 @@ Folder GetSubFolderList() --> [folders...] # Returns a list of subfolders in the folder. GetIsFolderStale() --> bool # Returns true if folder is stale in collaboration mode, false otherwise GetUniqueId() --> string # Returns a unique ID for the media pool folder + Export(filePath) --> bool # Returns true if export of DRB folder to filePath is successful, false otherwise MediaPoolItem GetName() --> string # Returns the clip name. @@ -257,6 +265,8 @@ MediaPoolItem UnlinkProxyMedia() --> Bool # Unlinks any proxy media associated with clip. ReplaceClip(filePath) --> Bool # Replaces the underlying asset and metadata of MediaPoolItem with the specified absolute clip path. GetUniqueId() --> string # Returns a unique ID for the media pool item + TranscribeAudio() --> Bool # Transcribes audio of the MediaPoolItem. Returns True if successful; False otherwise + ClearTranscription() --> Bool # Clears audio transcription of the MediaPoolItem. Returns True if successful; False otherwise. Timeline GetName() --> string # Returns the timeline name. @@ -266,6 +276,23 @@ Timeline SetStartTimecode(timecode) --> Bool # Set the start timecode of the timeline to the string 'timecode'. Returns true when the change is successful, false otherwise. GetStartTimecode() --> string # Returns the start timecode for the timeline. GetTrackCount(trackType) --> int # Returns the number of tracks for the given track type ("audio", "video" or "subtitle"). + AddTrack(trackType, optionalSubTrackType) --> Bool # Adds track of trackType ("video", "subtitle", "audio"). Second argument optionalSubTrackType is required for "audio" + # optionalSubTrackType can be one of {"mono", "stereo", "5.1", "5.1film", "7.1", "7.1film", "adaptive1", ... , "adaptive24"} + DeleteTrack(trackType, trackIndex) --> Bool # Deletes track of trackType ("video", "subtitle", "audio") and given trackIndex. 1 <= trackIndex <= GetTrackCount(trackType). + SetTrackEnable(trackType, trackIndex, Bool) --> Bool # Enables/Disables track with given trackType and trackIndex + # trackType is one of {"audio", "video", "subtitle"} + # 1 <= trackIndex <= GetTrackCount(trackType). + GetIsTrackEnabled(trackType, trackIndex) --> Bool # Returns True if track with given trackType and trackIndex is enabled and False otherwise. + # trackType is one of {"audio", "video", "subtitle"} + # 1 <= trackIndex <= GetTrackCount(trackType). + SetTrackLock(trackType, trackIndex, Bool) --> Bool # Locks/Unlocks track with given trackType and trackIndex + # trackType is one of {"audio", "video", "subtitle"} + # 1 <= trackIndex <= GetTrackCount(trackType). + GetIsTrackLocked(trackType, trackIndex) --> Bool # Returns True if track with given trackType and trackIndex is locked and False otherwise. + # trackType is one of {"audio", "video", "subtitle"} + # 1 <= trackIndex <= GetTrackCount(trackType). + DeleteClips([timelineItems], Bool) --> Bool # Deletes specified TimelineItems from the timeline, performing ripple delete if the second argument is True. Second argument is optional (The default for this is False) + SetClipsLinked([timelineItems], Bool) --> Bool # Links or unlinks the specified TimelineItems depending on second argument. GetItemListInTrack(trackType, index) --> [items...] # Returns a list of timeline items on that track (based on trackType and index). 1 <= index <= GetTrackCount(trackType). AddMarker(frameId, color, name, note, duration, --> Bool # Creates a new marker at given frameId position and with given marker information. 'customData' is optional and helps to attach user specific data to the marker. customData) @@ -301,7 +328,7 @@ Timeline # "sourceClipsFolders": string, list of Media Pool folder objects to search for source clips if the media is not present in current folder Export(fileName, exportType, exportSubtype) --> Bool # Exports timeline to 'fileName' as per input exportType & exportSubtype format. - # Refer to section "Looking up timeline exports properties" for information on the parameters. + # Refer to section "Looking up timeline export properties" for information on the parameters. GetSetting(settingName) --> string # Returns value of timeline setting (indicated by settingName : string). Check the section below for more information. SetSetting(settingName, settingValue) --> Bool # Sets timeline setting (indicated by settingName : string) to the value (settingValue : string). Check the section below for more information. InsertGeneratorIntoTimeline(generatorName) --> TimelineItem # Inserts a generator (indicated by generatorName : string) into the timeline. @@ -313,6 +340,8 @@ Timeline GrabStill() --> galleryStill # Grabs still from the current video clip. Returns a GalleryStill object. GrabAllStills(stillFrameSource) --> [galleryStill] # Grabs stills from all the clips of the timeline at 'stillFrameSource' (1 - First frame, 2 - Middle frame). Returns the list of GalleryStill objects. GetUniqueId() --> string # Returns a unique ID for the timeline + CreateSubtitlesFromAudio() --> Bool # Creates subtitles from audio for the timeline. Returns True on success, False otherwise. + DetectSceneCuts() --> Bool # Detects and makes scene cuts along the timeline. Returns True if successful, False otherwise. TimelineItem GetName() --> string # Returns the item name. @@ -362,6 +391,7 @@ TimelineItem GetStereoLeftFloatingWindowParams() --> {keyframes...} # For the LEFT eye -> returns a dict (offset -> dict) of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values. GetStereoRightFloatingWindowParams() --> {keyframes...} # For the RIGHT eye -> returns a dict (offset -> dict) of keyframe offsets and respective floating window params. Value at particular offset includes the left, right, top and bottom floating window values. GetNumNodes() --> int # Returns the number of nodes in the current graph for the timeline item + ApplyArriCdlLut() --> Bool # Applies ARRI CDL and LUT. Returns True if successful, False otherwise. SetLUT(nodeIndex, lutPath) --> Bool # Sets LUT on the node mapping the node index provided, 1 <= nodeIndex <= total number of nodes. # The lutPath can be an absolute path, or a relative path (based off custom LUT paths or the master LUT path). # The operation is successful for valid lut paths that Resolve has already discovered (see Project.RefreshLUTList). @@ -376,8 +406,16 @@ TimelineItem SelectTakeByIndex(idx) --> Bool # Selects a take by index, 1 <= idx <= number of takes. FinalizeTake() --> Bool # Finalizes take selection. CopyGrades([tgtTimelineItems]) --> Bool # Copies the current grade to all the items in tgtTimelineItems list. Returns True on success and False if any error occurred. + SetClipEnabled(Bool) --> Bool # Sets clip enabled based on argument. + GetClipEnabled() --> Bool # Gets clip enabled status. UpdateSidecar() --> Bool # Updates sidecar file for BRAW clips or RMD file for R3D clips. GetUniqueId() --> string # Returns a unique ID for the timeline item + LoadBurnInPreset(presetName) --> Bool # Loads user defined data burn in preset for clip when supplied presetName (string). Returns true if successful. + GetNodeLabel(nodeIndex) --> string # Returns the label of the node at nodeIndex. + CreateMagicMask(mode) --> Bool # Returns True if magic mask was created successfully, False otherwise. mode can "F" (forward), "B" (backward), or "BI" (bidirection) + RegenerateMagicMask() --> Bool # Returns True if magic mask was regenerated successfully, False otherwise. + Stabilize() --> Bool # Returns True if stabilization was successful, False otherwise + SmartReframe() --> Bool # Performs Smart Reframe. Returns True if successful, False otherwise. Gallery GetAlbumName(galleryStillAlbum) --> string # Returns the name of the GalleryStillAlbum object 'galleryStillAlbum'. @@ -422,9 +460,11 @@ Invoke "Project:SetSetting", "Timeline:SetSetting" or "MediaPoolItem:SetClipProp ensure the success of the operation. You can troubleshoot the validity of keys and values by setting the desired result from the UI and checking property snapshots before and after the change. The following Project properties have specifically enumerated values: -"superScale" - the property value is an enumerated integer between 0 and 3 with these meanings: 0=Auto, 1=no scaling, and 2, 3 and 4 represent the Super Scale multipliers 2x, 3x and 4x. +"superScale" - the property value is an enumerated integer between 0 and 4 with these meanings: 0=Auto, 1=no scaling, and 2, 3 and 4 represent the Super Scale multipliers 2x, 3x and 4x. + for super scale multiplier '2x Enhanced', exactly 4 arguments must be passed as outlined below. If less than 4 arguments are passed, it will default to 2x. Affects: • x = Project:GetSetting('superScale') and Project:SetSetting('superScale', x) +• for '2x Enhanced' --> Project:SetSetting('superScale', 2, sharpnessValue, noiseReductionValue), where sharpnessValue is a float in the range [0.0, 1.0] and noiseReductionValue is a float in the range [0.0, 1.0] "timelineFrameRate" - the property value is one of the frame rates available to the user in project settings under "Timeline frame rate" option. Drop Frame can be configured for supported frame rates by appending the frame rate with "DF", e.g. "29.97 DF" will enable drop frame and "29.97" will disable drop frame @@ -432,9 +472,11 @@ Affects: • x = Project:GetSetting('timelineFrameRate') and Project:SetSetting('timelineFrameRate', x) The following Clip properties have specifically enumerated values: -"superScale" - the property value is an enumerated integer between 1 and 3 with these meanings: 1=no scaling, and 2, 3 and 4 represent the Super Scale multipliers 2x, 3x and 4x. +"Super Scale" - the property value is an enumerated integer between 1 and 4 with these meanings: 1=no scaling, and 2, 3 and 4 represent the Super Scale multipliers 2x, 3x and 4x. + for super scale multiplier '2x Enhanced', exactly 4 arguments must be passed as outlined below. If less than 4 arguments are passed, it will default to 2x. Affects: • x = MediaPoolItem:GetClipProperty('Super Scale') and MediaPoolItem:SetClipProperty('Super Scale', x) +• for '2x Enhanced' --> MediaPoolItem:SetClipProperty('Super Scale', 2, sharpnessValue, noiseReductionValue), where sharpnessValue is a float in the range [0.0, 1.0] and noiseReductionValue is a float in the range [0.0, 1.0] Looking up Render Settings @@ -478,11 +520,6 @@ exportType can be one of the following constants: - resolve.EXPORT_DRT - resolve.EXPORT_EDL - resolve.EXPORT_FCP_7_XML - - resolve.EXPORT_FCPXML_1_3 - - resolve.EXPORT_FCPXML_1_4 - - resolve.EXPORT_FCPXML_1_5 - - resolve.EXPORT_FCPXML_1_6 - - resolve.EXPORT_FCPXML_1_7 - resolve.EXPORT_FCPXML_1_8 - resolve.EXPORT_FCPXML_1_9 - resolve.EXPORT_FCPXML_1_10 @@ -492,6 +529,8 @@ exportType can be one of the following constants: - resolve.EXPORT_TEXT_TAB - resolve.EXPORT_DOLBY_VISION_VER_2_9 - resolve.EXPORT_DOLBY_VISION_VER_4_0 + - resolve.EXPORT_DOLBY_VISION_VER_5_1 + - resolve.EXPORT_OTIO exportSubtype can be one of the following enums: - resolve.EXPORT_NONE - resolve.EXPORT_AAF_NEW @@ -504,6 +543,16 @@ When exportType is resolve.EXPORT_AAF, valid exportSubtype values are resolve.EX When exportType is resolve.EXPORT_EDL, valid exportSubtype values are resolve.EXPORT_CDL, resolve.EXPORT_SDL, resolve.EXPORT_MISSING_CLIPS and resolve.EXPORT_NONE. Note: Replace 'resolve.' when using the constants above, if a different Resolve class instance name is used. +Unsupported exportType types +--------------------------------- +Starting with DaVinci Resolve 18.1, the following export types are not supported: + - resolve.EXPORT_FCPXML_1_3 + - resolve.EXPORT_FCPXML_1_4 + - resolve.EXPORT_FCPXML_1_5 + - resolve.EXPORT_FCPXML_1_6 + - resolve.EXPORT_FCPXML_1_7 + + Looking up Timeline item properties ----------------------------------- This section covers additional notes for the function "TimelineItem:SetProperty" and "TimelineItem:GetProperty". These functions are used to get and set properties mentioned. From fac33119ec0e7a7087b053b95711b85dd13dc791 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 13:28:57 +0200 Subject: [PATCH 047/690] Enable only in Fusion 18.5+ --- openpype/hosts/fusion/plugins/load/load_usd.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index f12fbd5ed0..beab0c8ecf 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -7,6 +7,7 @@ from openpype.hosts.fusion.api import ( get_current_comp, comp_lock_and_undo_chunk ) +from openpype.hosts.fusion.api.lib import get_fusion_module class FusionLoadUSD(load.LoaderPlugin): @@ -26,6 +27,19 @@ class FusionLoadUSD(load.LoaderPlugin): tool_type = "uLoader" + @classmethod + def apply_settings(cls, project_settings, system_settings): + super(FusionLoadUSD, cls).apply_settings(project_settings, + system_settings) + if cls.enabled: + # Enable only in Fusion 18.5+ + fusion = get_fusion_module() + version = fusion.GetVersion() + major = version[1] + minor = version[2] + is_usd_supported = (major, minor) >= (18, 5) + cls.enabled = is_usd_supported + def load(self, context, name, namespace, data): # Fallback to asset name when namespace is None if namespace is None: From 277a0baa7bbe89b2a58fbe9568271e4d5f72e86b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 13:29:49 +0200 Subject: [PATCH 048/690] Hound --- openpype/hosts/fusion/plugins/load/load_usd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/load/load_usd.py b/openpype/hosts/fusion/plugins/load/load_usd.py index beab0c8ecf..4f1813a646 100644 --- a/openpype/hosts/fusion/plugins/load/load_usd.py +++ b/openpype/hosts/fusion/plugins/load/load_usd.py @@ -29,7 +29,7 @@ class FusionLoadUSD(load.LoaderPlugin): @classmethod def apply_settings(cls, project_settings, system_settings): - super(FusionLoadUSD, cls).apply_settings(project_settings, + super(FusionLoadUSD, cls).apply_settings(project_settings, system_settings) if cls.enabled: # Enable only in Fusion 18.5+ From df5fc6154dcd26cda86247e484c4798aae4a099f Mon Sep 17 00:00:00 2001 From: Ember Light <49758407+EmberLightVFX@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:23:42 +0200 Subject: [PATCH 049/690] Change name from Validate Saver to Validate Asset Co-authored-by: Roy Nieterau --- .../hosts/fusion/plugins/publish/validate_saver_resolution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py b/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py index b43a5023fa..efa7295d11 100644 --- a/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py +++ b/openpype/hosts/fusion/plugins/publish/validate_saver_resolution.py @@ -63,7 +63,7 @@ class ValidateSaverResolution( """Validate that the saver input resolution matches the asset resolution""" order = pyblish.api.ValidatorOrder - label = "Validate Saver Resolution" + label = "Validate Asset Resolution" families = ["render"] hosts = ["fusion"] optional = True From ffeb0282b93b05a1d345bfa39928c195d5f1ff74 Mon Sep 17 00:00:00 2001 From: Jacob Danell Date: Mon, 2 Oct 2023 14:39:27 +0200 Subject: [PATCH 050/690] Restore formatting of non-modified code --- openpype/hosts/fusion/api/lib.py | 75 ++++++++++++-------------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 19db484856..8a18080393 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -21,15 +21,8 @@ from openpype.pipeline.context_tools import get_current_project_asset self = sys.modules[__name__] self._project = None - -def update_frame_range( - start, - end, - comp=None, - set_render_range=True, - handle_start=0, - handle_end=0, -): +def update_frame_range(start, end, comp=None, set_render_range=True, + handle_start=0, handle_end=0): """Set Fusion comp's start and end frame range Args: @@ -55,17 +48,15 @@ def update_frame_range( attrs = { "COMPN_GlobalStart": start - handle_start, - "COMPN_GlobalEnd": end + handle_end, + "COMPN_GlobalEnd": end + handle_end } # set frame range if set_render_range: - attrs.update( - { - "COMPN_RenderStart": start, - "COMPN_RenderEnd": end, - } - ) + attrs.update({ + "COMPN_RenderStart": start, + "COMPN_RenderEnd": end + }) with comp_lock_and_undo_chunk(comp): comp.SetAttrs(attrs) @@ -78,13 +69,9 @@ def set_asset_framerange(): end = asset_doc["data"]["frameEnd"] handle_start = asset_doc["data"]["handleStart"] handle_end = asset_doc["data"]["handleEnd"] - update_frame_range( - start, - end, - set_render_range=True, - handle_start=handle_start, - handle_end=handle_end, - ) + update_frame_range(start, end, set_render_range=True, + handle_start=handle_start, + handle_end=handle_end) def set_asset_resolution(): @@ -94,15 +81,12 @@ def set_asset_resolution(): height = asset_doc["data"]["resolutionHeight"] comp = get_current_comp() - print( - "Setting comp frame format resolution to {}x{}".format(width, height) - ) - comp.SetPrefs( - { - "Comp.FrameFormat.Width": width, - "Comp.FrameFormat.Height": height, - } - ) + print("Setting comp frame format resolution to {}x{}".format(width, + height)) + comp.SetPrefs({ + "Comp.FrameFormat.Width": width, + "Comp.FrameFormat.Height": height, + }) def validate_comp_prefs(comp=None, force_repair=False): @@ -123,7 +107,7 @@ def validate_comp_prefs(comp=None, force_repair=False): "data.fps", "data.resolutionWidth", "data.resolutionHeight", - "data.pixelAspect", + "data.pixelAspect" ] asset_doc = get_current_project_asset(fields=fields) asset_data = asset_doc["data"] @@ -140,7 +124,7 @@ def validate_comp_prefs(comp=None, force_repair=False): ("resolutionWidth", "Width", "Resolution Width"), ("resolutionHeight", "Height", "Resolution Height"), ("pixelAspectX", "AspectX", "Pixel Aspect Ratio X"), - ("pixelAspectY", "AspectY", "Pixel Aspect Ratio Y"), + ("pixelAspectY", "AspectY", "Pixel Aspect Ratio Y") ] invalid = [] @@ -148,9 +132,9 @@ def validate_comp_prefs(comp=None, force_repair=False): asset_value = asset_data[key] comp_value = comp_frame_format_prefs.get(comp_key) if asset_value != comp_value: - invalid_msg = "{} {} should be {}".format( - label, comp_value, asset_value - ) + invalid_msg = "{} {} should be {}".format(label, + comp_value, + asset_value) invalid.append(invalid_msg) if not force_repair: @@ -161,8 +145,7 @@ def validate_comp_prefs(comp=None, force_repair=False): pref=label, value=comp_value, asset_name=asset_doc["name"], - asset_value=asset_value, - ) + asset_value=asset_value) ) if invalid: @@ -299,13 +282,11 @@ def maintained_selection(comp=None): @contextlib.contextmanager -def maintained_comp_range( - comp=None, - global_start=True, - global_end=True, - render_start=True, - render_end=True, -): +def maintained_comp_range(comp=None, + global_start=True, + global_end=True, + render_start=True, + render_end=True): """Reset comp frame ranges from before the context after the context""" if comp is None: comp = get_current_comp() @@ -349,7 +330,7 @@ def get_frame_path(path): filename, ext = os.path.splitext(path) # Find a final number group - match = re.match(".*?([0-9]+)$", filename) + match = re.match('.*?([0-9]+)$', filename) if match: padding = len(match.group(1)) # remove number from end since fusion From 80febccf0ef2162623d02a83b362b85df7d33c8b Mon Sep 17 00:00:00 2001 From: Jacob Danell Date: Mon, 2 Oct 2023 14:41:54 +0200 Subject: [PATCH 051/690] hound --- openpype/hosts/fusion/api/lib.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/fusion/api/lib.py b/openpype/hosts/fusion/api/lib.py index 0393c1f7d5..85f9c54a73 100644 --- a/openpype/hosts/fusion/api/lib.py +++ b/openpype/hosts/fusion/api/lib.py @@ -21,6 +21,7 @@ from openpype.pipeline.context_tools import get_current_project_asset self = sys.modules[__name__] self._project = None + def update_frame_range(start, end, comp=None, set_render_range=True, handle_start=0, handle_end=0): """Set Fusion comp's start and end frame range @@ -70,8 +71,8 @@ def set_asset_framerange(): handle_start = asset_doc["data"]["handleStart"] handle_end = asset_doc["data"]["handleEnd"] update_frame_range(start, end, set_render_range=True, - handle_start=handle_start, - handle_end=handle_end) + handle_start=handle_start, + handle_end=handle_end) def set_asset_resolution(): @@ -133,8 +134,8 @@ def validate_comp_prefs(comp=None, force_repair=False): comp_value = comp_frame_format_prefs.get(comp_key) if asset_value != comp_value: invalid_msg = "{} {} should be {}".format(label, - comp_value, - asset_value) + comp_value, + asset_value) invalid.append(invalid_msg) if not force_repair: @@ -166,7 +167,6 @@ def validate_comp_prefs(comp=None, force_repair=False): from . import menu from openpype.widgets import popup from openpype.style import load_stylesheet - dialog = popup.Popup(parent=menu.menu) dialog.setWindowTitle("Fusion comp has invalid configuration") From 8c508b4b00082e7f0427fa929a5d2e0d8be19d99 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 2 Oct 2023 15:45:38 +0200 Subject: [PATCH 052/690] removing testing scripts --- .../utility_scripts/tests/test_otio_as_edl.py | 49 ------------- .../testing_create_timeline_item_from_path.py | 73 ------------------- .../tests/testing_load_media_pool_item.py | 24 ------ .../tests/testing_startup_script.py | 5 -- .../tests/testing_timeline_op.py | 13 ---- 5 files changed, 164 deletions(-) delete mode 100644 openpype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py delete mode 100644 openpype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py delete mode 100644 openpype/hosts/resolve/utility_scripts/tests/testing_load_media_pool_item.py delete mode 100644 openpype/hosts/resolve/utility_scripts/tests/testing_startup_script.py delete mode 100644 openpype/hosts/resolve/utility_scripts/tests/testing_timeline_op.py diff --git a/openpype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py b/openpype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py deleted file mode 100644 index 92f2e43a72..0000000000 --- a/openpype/hosts/resolve/utility_scripts/tests/test_otio_as_edl.py +++ /dev/null @@ -1,49 +0,0 @@ -#! python3 -import os -import sys - -import opentimelineio as otio - -from openpype.pipeline import install_host - -import openpype.hosts.resolve.api as bmdvr -from openpype.hosts.resolve.api.testing_utils import TestGUI -from openpype.hosts.resolve.otio import davinci_export as otio_export - - -class ThisTestGUI(TestGUI): - extensions = [".exr", ".jpg", ".mov", ".png", ".mp4", ".ari", ".arx"] - - def __init__(self): - super(ThisTestGUI, self).__init__() - # activate resolve from openpype - install_host(bmdvr) - - def _open_dir_button_pressed(self, event): - # selected_path = self.fu.RequestFile(os.path.expanduser("~")) - selected_path = self.fu.RequestDir(os.path.expanduser("~")) - self._widgets["inputTestSourcesFolder"].Text = selected_path - - # main function - def process(self, event): - self.input_dir_path = self._widgets["inputTestSourcesFolder"].Text - project = bmdvr.get_current_project() - otio_timeline = otio_export.create_otio_timeline(project) - print(f"_ otio_timeline: `{otio_timeline}`") - edl_path = os.path.join(self.input_dir_path, "this_file_name.edl") - print(f"_ edl_path: `{edl_path}`") - # xml_string = otio_adapters.fcpx_xml.write_to_string(otio_timeline) - # print(f"_ xml_string: `{xml_string}`") - otio.adapters.write_to_file( - otio_timeline, edl_path, adapter_name="cmx_3600") - project = bmdvr.get_current_project() - media_pool = project.GetMediaPool() - timeline = media_pool.ImportTimelineFromFile(edl_path) - # at the end close the window - self._close_window(None) - - -if __name__ == "__main__": - test_gui = ThisTestGUI() - test_gui.show_gui() - sys.exit(not bool(True)) diff --git a/openpype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py b/openpype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py deleted file mode 100644 index 91a361ec08..0000000000 --- a/openpype/hosts/resolve/utility_scripts/tests/testing_create_timeline_item_from_path.py +++ /dev/null @@ -1,73 +0,0 @@ -#! python3 -import os -import sys - -import clique - -from openpype.pipeline import install_host -from openpype.hosts.resolve.api.testing_utils import TestGUI -import openpype.hosts.resolve.api as bmdvr -from openpype.hosts.resolve.api.lib import ( - create_media_pool_item, - create_timeline_item, -) - - -class ThisTestGUI(TestGUI): - extensions = [".exr", ".jpg", ".mov", ".png", ".mp4", ".ari", ".arx"] - - def __init__(self): - super(ThisTestGUI, self).__init__() - # activate resolve from openpype - install_host(bmdvr) - - def _open_dir_button_pressed(self, event): - # selected_path = self.fu.RequestFile(os.path.expanduser("~")) - selected_path = self.fu.RequestDir(os.path.expanduser("~")) - self._widgets["inputTestSourcesFolder"].Text = selected_path - - # main function - def process(self, event): - self.input_dir_path = self._widgets["inputTestSourcesFolder"].Text - - self.dir_processing(self.input_dir_path) - - # at the end close the window - self._close_window(None) - - def dir_processing(self, dir_path): - collections, reminders = clique.assemble(os.listdir(dir_path)) - - # process reminders - for _rem in reminders: - _rem_path = os.path.join(dir_path, _rem) - - # go deeper if directory - if os.path.isdir(_rem_path): - print(_rem_path) - self.dir_processing(_rem_path) - else: - self.file_processing(_rem_path) - - # process collections - for _coll in collections: - _coll_path = os.path.join(dir_path, list(_coll).pop()) - self.file_processing(_coll_path) - - def file_processing(self, fpath): - print(f"_ fpath: `{fpath}`") - _base, ext = os.path.splitext(fpath) - # skip if unwanted extension - if ext not in self.extensions: - return - media_pool_item = create_media_pool_item(fpath) - print(media_pool_item) - - track_item = create_timeline_item(media_pool_item) - print(track_item) - - -if __name__ == "__main__": - test_gui = ThisTestGUI() - test_gui.show_gui() - sys.exit(not bool(True)) diff --git a/openpype/hosts/resolve/utility_scripts/tests/testing_load_media_pool_item.py b/openpype/hosts/resolve/utility_scripts/tests/testing_load_media_pool_item.py deleted file mode 100644 index 2e83188bde..0000000000 --- a/openpype/hosts/resolve/utility_scripts/tests/testing_load_media_pool_item.py +++ /dev/null @@ -1,24 +0,0 @@ -#! python3 -from openpype.pipeline import install_host -from openpype.hosts.resolve import api as bmdvr -from openpype.hosts.resolve.api.lib import ( - create_media_pool_item, - create_timeline_item, -) - - -def file_processing(fpath): - media_pool_item = create_media_pool_item(fpath) - print(media_pool_item) - - track_item = create_timeline_item(media_pool_item) - print(track_item) - - -if __name__ == "__main__": - path = "C:/CODE/__openpype_projects/jtest03dev/shots/sq01/mainsq01sh030/publish/plate/plateMain/v006/jt3d_mainsq01sh030_plateMain_v006.0996.exr" - - # activate resolve from openpype - install_host(bmdvr) - - file_processing(path) diff --git a/openpype/hosts/resolve/utility_scripts/tests/testing_startup_script.py b/openpype/hosts/resolve/utility_scripts/tests/testing_startup_script.py deleted file mode 100644 index b64714ab16..0000000000 --- a/openpype/hosts/resolve/utility_scripts/tests/testing_startup_script.py +++ /dev/null @@ -1,5 +0,0 @@ -#! python3 -from openpype.hosts.resolve.startup import main - -if __name__ == "__main__": - main() diff --git a/openpype/hosts/resolve/utility_scripts/tests/testing_timeline_op.py b/openpype/hosts/resolve/utility_scripts/tests/testing_timeline_op.py deleted file mode 100644 index 8270496f64..0000000000 --- a/openpype/hosts/resolve/utility_scripts/tests/testing_timeline_op.py +++ /dev/null @@ -1,13 +0,0 @@ -#! python3 -from openpype.pipeline import install_host -from openpype.hosts.resolve import api as bmdvr -from openpype.hosts.resolve.api.lib import get_current_project - -if __name__ == "__main__": - install_host(bmdvr) - project = get_current_project() - timeline_count = project.GetTimelineCount() - print(f"Timeline count: {timeline_count}") - timeline = project.GetTimelineByIndex(timeline_count) - print(f"Timeline name: {timeline.GetName()}") - print(timeline.GetTrackCount("video")) From 88a1f97ad595000b6a440643b61cbcd3b8f659c9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Mon, 2 Oct 2023 15:48:27 +0200 Subject: [PATCH 053/690] resolve: improving loading --- openpype/hosts/resolve/api/lib.py | 54 +++++++++++++++++----------- openpype/hosts/resolve/api/plugin.py | 43 ++++------------------ 2 files changed, 40 insertions(+), 57 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 8f7eba8a90..22be929412 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -6,7 +6,10 @@ import contextlib from opentimelineio import opentime from openpype.lib import Logger -from openpype.pipeline.editorial import is_overlapping_otio_ranges +from openpype.pipeline.editorial import ( + is_overlapping_otio_ranges, + frames_to_timecode +) from ..otio import davinci_export as otio_export @@ -243,11 +246,13 @@ def get_media_pool_item(fpath, root: object = None) -> object: return None -def create_timeline_item(media_pool_item: object, - timeline: object = None, - source_start: int = None, - source_end: int = None, - timeline_in: int = None) -> object: +def create_timeline_item( + media_pool_item: object, + source_start: int, + source_end: int, + timeline_in: int, + timeline: object = None +) -> object: """ Add media pool item to current or defined timeline. @@ -267,20 +272,24 @@ def create_timeline_item(media_pool_item: object, clip_name = _clip_property("File Name") timeline = timeline or get_current_timeline() + # timing variables + fps = project.GetSetting("timelineFrameRate") + duration = source_end - source_start + timecode_in = frames_to_timecode(timeline_in, fps) + timecode_out = frames_to_timecode(timeline_in + duration, fps) + # if timeline was used then switch it to current timeline with maintain_current_timeline(timeline): # Add input mediaPoolItem to clip data - clip_data = {"mediaPoolItem": media_pool_item} - - # add source time range if input was given - if source_start is not None: - clip_data["startFrame"] = source_start - if source_end is not None: - clip_data["endFrame"] = source_end - - # Create a clipInfo dictionary with the necessary information - clip_data["recordFrame"] = timeline_in + clip_data = { + "mediaPoolItem": media_pool_item, + "startFrame": source_start, + "endFrame": source_end, + "recordFrame": timeline_in, + } + print("clip_data", "_" * 50) + print(media_pool_item.GetName()) print(clip_data) # add to timeline @@ -289,10 +298,15 @@ def create_timeline_item(media_pool_item: object, output_timeline_item = get_timeline_item( media_pool_item, timeline) - assert output_timeline_item, AssertionError( - "Track Item with name `{}` doesn't exist on the timeline: `{}`".format( - clip_name, timeline.GetName() - )) + assert output_timeline_item, AssertionError(( + "Clip name '{}' was't created on the timeline: '{}' \n\n" + "Please check if the clip is in the media pool or if the timeline \n" + "is having activated correct track name, or if it is not already \n" + "having any clip add place on the timeline in: '{}' out: '{}'. \n\n" + "Clip data: {}" + ).format( + clip_name, timeline.GetName(), timecode_in, timecode_out, clip_data + )) return output_timeline_item diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index b1bde212fe..1c817d8e0d 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -355,7 +355,6 @@ class ClipLoader: asset = str(repr_cntx["asset"]) subset = str(repr_cntx["subset"]) representation = str(repr_cntx["representation"]) - self.data["track_name"] = "{}_{}".format(asset, representation) self.data["clip_name"] = "_".join([asset, subset, representation]) self.data["versionData"] = self.context["version"]["data"] # gets file path @@ -387,32 +386,6 @@ class ClipLoader: asset_name = self.context["representation"]["context"]["asset"] self.data["assetData"] = get_current_project_asset(asset_name)["data"] - def _set_active_track(self): - """ Set active track to `track` """ - track_type = "video" - track_name = self.data["track_name"] - track_exists = False - - # get total track count - track_count = self.active_timeline.GetTrackCount(track_type) - # loop all tracks by track indexes - for track_index in range(1, int(track_count) + 1): - # get current track name - _track_name = self.active_timeline.GetTrackName( - track_type, track_index) - if track_name != _track_name: - continue - track_exists = True - break - - if not track_exists: - self.active_timeline.AddTrack(track_type) - self.active_timeline.SetTrackName( - track_type, - track_index + 1, - track_name - ) - def load(self): # create project bin for the media to be imported into @@ -420,7 +393,6 @@ class ClipLoader: # create mediaItem in active project bin # create clip media - media_pool_item = lib.create_media_pool_item( self.data["path"], self.active_bin) _clip_property = media_pool_item.GetClipProperty @@ -433,9 +405,6 @@ class ClipLoader: if handle_end is None: handle_end = int(self.data["assetData"]["handleEnd"]) - # handle timeline tracks - self._set_active_track() - # get timeline in timeline_start = self.active_timeline.GetStartFrame() if self.sequential_load: @@ -454,17 +423,17 @@ class ClipLoader: source_out -= handle_end # include handles - if self.with_handles: - source_in -= handle_start - source_out += handle_end + if not self.with_handles: + source_in += handle_start + source_out -= handle_end # make track item from source in bin as item timeline_item = lib.create_timeline_item( media_pool_item, - self.active_timeline, source_in, source_out, - timeline_in + timeline_in, + self.active_timeline, ) print("Loading clips: `{}`".format(self.data["clip_name"])) @@ -504,7 +473,7 @@ class TimelineItemLoader(LoaderPlugin): """ options = [ - qargparse.Toggle( + qargparse.Boolean( "handles", label="Include handles", default=0, From 8267736bed9968a314658b45de2cbc904c0f2547 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 16:24:23 +0200 Subject: [PATCH 054/690] Fix Fusion 18.6+ support: Avoid issues with Fusion's `BlackmagicFusion.PyRemoteObject` instances being unhashable. ```python Traceback (most recent call last): File "E:\openpype\OpenPype\.venv\lib\site-packages\pyblish\plugin.py", line 527, in __explicit_process runner(*args) File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 61, in process result = self.render(instance) File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 118, in render with enabled_savers(current_comp, savers_to_render): File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\contextlib.py", line 119, in __enter__ return next(self.gen) File "E:\openpype\OpenPype\openpype\hosts\fusion\plugins\publish\extract_render_local.py", line 33, in enabled_savers original_states[saver] = original_state TypeError: unhashable type: 'BlackmagicFusion.PyRemoteObject' ``` --- .../hosts/fusion/plugins/publish/extract_render_local.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/extract_render_local.py b/openpype/hosts/fusion/plugins/publish/extract_render_local.py index 25c101cf00..e7bf010a9d 100644 --- a/openpype/hosts/fusion/plugins/publish/extract_render_local.py +++ b/openpype/hosts/fusion/plugins/publish/extract_render_local.py @@ -25,12 +25,13 @@ def enabled_savers(comp, savers): """ passthrough_key = "TOOLB_PassThrough" original_states = {} + savers_by_name = {saver.Name: saver for saver in savers} enabled_save_names = {saver.Name for saver in savers} try: all_savers = comp.GetToolList(False, "Saver").values() for saver in all_savers: original_state = saver.GetAttrs()[passthrough_key] - original_states[saver] = original_state + original_states[saver.Name] = original_state # The passthrough state we want to set (passthrough != enabled) state = saver.Name not in enabled_save_names @@ -38,7 +39,8 @@ def enabled_savers(comp, savers): saver.SetAttrs({passthrough_key: state}) yield finally: - for saver, original_state in original_states.items(): + for saver_name, original_state in original_states.items(): + saver = savers_by_name.get(saver_name) saver.SetAttrs({"TOOLB_PassThrough": original_state}) From 74070e0f25d9b53ec16512057e8e08ad228040ae Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 16:28:46 +0200 Subject: [PATCH 055/690] Be more explicit that key should exist --- openpype/hosts/fusion/plugins/publish/extract_render_local.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/fusion/plugins/publish/extract_render_local.py b/openpype/hosts/fusion/plugins/publish/extract_render_local.py index e7bf010a9d..7cc03410c6 100644 --- a/openpype/hosts/fusion/plugins/publish/extract_render_local.py +++ b/openpype/hosts/fusion/plugins/publish/extract_render_local.py @@ -40,7 +40,7 @@ def enabled_savers(comp, savers): yield finally: for saver_name, original_state in original_states.items(): - saver = savers_by_name.get(saver_name) + saver = savers_by_name[saver_name] saver.SetAttrs({"TOOLB_PassThrough": original_state}) From 33ebd706a9232a3d8b0c34f79eb46474fde2f640 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 2 Oct 2023 16:31:25 +0200 Subject: [PATCH 056/690] Correctly produce the `savers_by_name` dict to include all savers --- .../fusion/plugins/publish/extract_render_local.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/fusion/plugins/publish/extract_render_local.py b/openpype/hosts/fusion/plugins/publish/extract_render_local.py index 7cc03410c6..08d608139d 100644 --- a/openpype/hosts/fusion/plugins/publish/extract_render_local.py +++ b/openpype/hosts/fusion/plugins/publish/extract_render_local.py @@ -25,16 +25,18 @@ def enabled_savers(comp, savers): """ passthrough_key = "TOOLB_PassThrough" original_states = {} - savers_by_name = {saver.Name: saver for saver in savers} - enabled_save_names = {saver.Name for saver in savers} + enabled_saver_names = {saver.Name for saver in savers} + + all_savers = comp.GetToolList(False, "Saver").values() + savers_by_name = {saver.Name: saver for saver in all_savers} + try: - all_savers = comp.GetToolList(False, "Saver").values() for saver in all_savers: original_state = saver.GetAttrs()[passthrough_key] original_states[saver.Name] = original_state # The passthrough state we want to set (passthrough != enabled) - state = saver.Name not in enabled_save_names + state = saver.Name not in enabled_saver_names if state != original_state: saver.SetAttrs({passthrough_key: state}) yield From 2ccc2a101cfd304d1767e8f667fb6db3a73c2cab Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 3 Oct 2023 22:10:51 +0200 Subject: [PATCH 057/690] Add save current file button + "Save" shortcut when menu is active --- openpype/hosts/resolve/api/menu.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/api/menu.py b/openpype/hosts/resolve/api/menu.py index b3717e01ea..fd5a4cec78 100644 --- a/openpype/hosts/resolve/api/menu.py +++ b/openpype/hosts/resolve/api/menu.py @@ -1,13 +1,14 @@ import os import sys -from qtpy import QtWidgets, QtCore +from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.utils import host_tools +from openpype.pipeline import registered_host from .pipeline import ( publish, - launch_workfiles_app + launch_workfiles_app, ) @@ -54,6 +55,7 @@ class OpenPypeMenu(QtWidgets.QWidget): ) self.setWindowTitle("OpenPype") + save_current_btn = QtWidgets.QPushButton("Save current file", self) workfiles_btn = QtWidgets.QPushButton("Workfiles ...", self) create_btn = QtWidgets.QPushButton("Create ...", self) publish_btn = QtWidgets.QPushButton("Publish ...", self) @@ -75,6 +77,10 @@ class OpenPypeMenu(QtWidgets.QWidget): layout = QtWidgets.QVBoxLayout(self) layout.setContentsMargins(10, 20, 10, 20) + layout.addWidget(save_current_btn) + + layout.addWidget(Spacer(15, self)) + layout.addWidget(workfiles_btn) layout.addWidget(create_btn) layout.addWidget(publish_btn) @@ -99,6 +105,8 @@ class OpenPypeMenu(QtWidgets.QWidget): self.setLayout(layout) + save_current_btn.clicked.connect(self.on_save_current_clicked) + save_current_btn.setShortcut(QtGui.QKeySequence.Save) workfiles_btn.clicked.connect(self.on_workfile_clicked) create_btn.clicked.connect(self.on_create_clicked) publish_btn.clicked.connect(self.on_publish_clicked) @@ -111,6 +119,15 @@ class OpenPypeMenu(QtWidgets.QWidget): # reset_resolution_btn.clicked.connect(self.on_set_resolution_clicked) experimental_btn.clicked.connect(self.on_experimental_clicked) + def on_save_current_clicked(self): + host = registered_host() + current_file = host.current_file() + if not current_file: + return + + print(f"Saving current file to: {current_file}") + host.save_file(current_file) + def on_workfile_clicked(self): print("Clicked Workfile") launch_workfiles_app() From fe11a3aed27cf3b0b215209c2148fa4167d52e96 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 4 Oct 2023 08:50:52 +0200 Subject: [PATCH 058/690] Revert cosmetic change --- openpype/hosts/resolve/api/menu.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/resolve/api/menu.py b/openpype/hosts/resolve/api/menu.py index fd5a4cec78..024b367235 100644 --- a/openpype/hosts/resolve/api/menu.py +++ b/openpype/hosts/resolve/api/menu.py @@ -8,7 +8,7 @@ from openpype.pipeline import registered_host from .pipeline import ( publish, - launch_workfiles_app, + launch_workfiles_app ) From f94cd729f6d88565f593979921748920e48e05ec Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 6 Oct 2023 17:49:20 +0200 Subject: [PATCH 059/690] Refactor to new style host --- openpype/hosts/resolve/api/menu.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/api/menu.py b/openpype/hosts/resolve/api/menu.py index ff8d5d4c6a..160cc44fdb 100644 --- a/openpype/hosts/resolve/api/menu.py +++ b/openpype/hosts/resolve/api/menu.py @@ -116,12 +116,12 @@ class OpenPypeMenu(QtWidgets.QWidget): def on_save_current_clicked(self): host = registered_host() - current_file = host.current_file() + current_file = host.get_current_workfile() if not current_file: return print(f"Saving current file to: {current_file}") - host.save_file(current_file) + host.save_workfile(current_file) def on_workfile_clicked(self): print("Clicked Workfile") From 523633c1aaa1f3d54f518a5a3a3f2e8240f3479a Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Mon, 9 Oct 2023 12:53:46 +0100 Subject: [PATCH 060/690] Optional workfile dependency --- .../plugins/publish/submit_nuke_deadline.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 0295c2b760..0e57c54959 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -48,6 +48,7 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, use_gpu = False env_allowed_keys = [] env_search_replace_values = {} + workfile_dependency = True @classmethod def get_attribute_defs(cls): @@ -83,6 +84,11 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, "suspend_publish", default=False, label="Suspend publish" + ), + BoolDef( + "workfile_dependency", + default=True, + label="Workfile Dependency" ) ] @@ -313,6 +319,13 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, "AuxFiles": [] } + # Add workfile dependency. + workfile_dependency = instance.data["attributeValues"].get( + "workfile_dependency", self.workfile_dependency + ) + if workfile_dependency: + payload["JobInfo"].update({"AssetDependency0": script_path}) + # TODO: rewrite for baking with sequences if baking_submission: payload["JobInfo"].update({ From 1f1676f5bb98aea465371641693b63ff2326abbd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 13 Oct 2023 14:36:36 +0200 Subject: [PATCH 061/690] Refactor to use variable `node_value` instead of `value` - `value` only exists as the last variable value in the `for value in values` loop and might not be declared if `values` is an empty iterable. --- openpype/hosts/nuke/plugins/publish/validate_write_nodes.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py b/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py index 9aae53e59d..b882e240e6 100644 --- a/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py +++ b/openpype/hosts/nuke/plugins/publish/validate_write_nodes.py @@ -111,7 +111,6 @@ class ValidateNukeWriteNode( for value in values: if type(node_value) in (int, float): try: - if isinstance(value, list): value = color_gui_to_int(value) else: @@ -130,7 +129,7 @@ class ValidateNukeWriteNode( and key != "file" and key != "tile_color" ): - check.append([key, value, write_node[key].value()]) + check.append([key, node_value, write_node[key].value()]) if check: self._make_error(check) From 908b8e3fb69a2347d6b6208f32c546dc55ba061a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 17 Oct 2023 12:22:01 +0200 Subject: [PATCH 062/690] Add MayaUsdReferenceLoader to reference USD as Maya native geometry using `mayaUSDImport` file translator --- openpype/hosts/maya/api/plugin.py | 3 +- .../hosts/maya/plugins/load/load_reference.py | 100 +++++++++++++++++- 2 files changed, 101 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 3b54954c8a..07167a9a32 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -771,7 +771,8 @@ class ReferenceLoader(Loader): "ma": "mayaAscii", "mb": "mayaBinary", "abc": "Alembic", - "fbx": "FBX" + "fbx": "FBX", + "usd": "USD Import" }.get(representation["name"]) assert file_type, "Unsupported representation: %s" % representation diff --git a/openpype/hosts/maya/plugins/load/load_reference.py b/openpype/hosts/maya/plugins/load/load_reference.py index 4b704fa706..0d7f08d3c3 100644 --- a/openpype/hosts/maya/plugins/load/load_reference.py +++ b/openpype/hosts/maya/plugins/load/load_reference.py @@ -1,7 +1,9 @@ import os import difflib import contextlib + from maya import cmds +import qargparse from openpype.settings import get_project_settings import openpype.hosts.maya.api.plugin @@ -128,6 +130,12 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): if not attach_to_root: group_name = namespace + kwargs = {} + if "file_options" in options: + kwargs["options"] = options["file_options"] + if "file_type" in options: + kwargs["type"] = options["file_type"] + path = self.filepath_from_context(context) with maintained_selection(): cmds.loadPlugin("AbcImport.mll", quiet=True) @@ -139,7 +147,8 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): reference=True, returnNewNodes=True, groupReference=attach_to_root, - groupName=group_name) + groupName=group_name, + **kwargs) shapes = cmds.ls(nodes, shapes=True, long=True) @@ -251,3 +260,92 @@ class ReferenceLoader(openpype.hosts.maya.api.plugin.ReferenceLoader): else: self.log.warning("This version of Maya does not support locking of" " transforms of cameras.") + + +class MayaUSDReferenceLoader(ReferenceLoader): + """Reference USD file to native Maya nodes using MayaUSDImport reference""" + + families = ["usd"] + representations = ["usd"] + extensions = {"usd", "usda", "usdc"} + + options = ReferenceLoader.options + [ + qargparse.Boolean( + "readAnimData", + label="Load anim data", + default=True, + help="Load animation data from USD file" + ), + qargparse.Boolean( + "useAsAnimationCache", + label="Use as animation cache", + default=True, + help=( + "Imports geometry prims with time-sampled point data using a " + "point-based deformer that references the imported " + "USD file.\n" + "This provides better import and playback performance when " + "importing time-sampled geometry from USD, and should " + "reduce the weight of the resulting Maya scene." + ) + ), + qargparse.Boolean( + "importInstances", + label="Import instances", + default=True, + help=( + "Import USD instanced geometries as Maya instanced shapes. " + "Will flatten the scene otherwise." + ) + ), + qargparse.String( + "primPath", + label="Prim Path", + default="/", + help=( + "Name of the USD scope where traversing will begin.\n" + "The prim at the specified primPath (including the prim) will " + "be imported.\n" + "Specifying the pseudo-root (/) means you want " + "to import everything in the file.\n" + "If the passed prim path is empty, it will first try to " + "import the defaultPrim for the rootLayer if it exists.\n" + "Otherwise, it will behave as if the pseudo-root was passed " + "in." + ) + ) + ] + + file_type = "USD Import" + + def process_reference(self, context, name, namespace, options): + cmds.loadPlugin("mayaUsdPlugin", quiet=True) + + def bool_option(key, default): + # Shorthand for getting optional boolean file option from options + value = int(bool(options.get(key, default))) + return "{}={}".format(key, value) + + def string_option(key, default): + # Shorthand for getting optional string file option from options + value = str(options.get(key, default)) + return "{}={}".format(key, value) + + options["file_options"] = ";".join([ + string_option("primPath", default="/"), + bool_option("importInstances", default=True), + bool_option("useAsAnimationCache", default=True), + bool_option("readAnimData", default=True), + # TODO: Expose more parameters + # "preferredMaterial=none", + # "importRelativeTextures=Automatic", + # "useCustomFrameRange=0", + # "startTime=0", + # "endTime=0", + # "importUSDZTextures=0" + ]) + options["file_type"] = self.file_type + + return super(MayaUSDReferenceLoader, self).process_reference( + context, name, namespace, options + ) From b1ea0b099dd13e13515d3a4f32b2830702496488 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Oct 2023 15:32:42 +0200 Subject: [PATCH 063/690] merging if conditions for handles exclusion also updating docstring --- openpype/hosts/resolve/api/lib.py | 5 +++-- openpype/hosts/resolve/api/plugin.py | 9 ++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 22be929412..2d91609679 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -258,9 +258,10 @@ def create_timeline_item( Args: media_pool_item (resolve.MediaPoolItem): resolve's object + source_start (int): media source input frame (sequence frame) + source_end (int): media source output frame (sequence frame) + timeline_in (int): timeline input frame (sequence frame) timeline (resolve.Timeline)[optional]: resolve's object - source_start (int)[optional]: media source input frame (sequence frame) - source_end (int)[optional]: media source output frame (sequence frame) Returns: object: resolve.TimelineItem diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 1c817d8e0d..314d066890 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -418,12 +418,11 @@ class ClipLoader: source_in = int(_clip_property("Start")) source_out = int(_clip_property("End")) - if _clip_property("Type") == "Video": - source_in += handle_start - source_out -= handle_end - # include handles - if not self.with_handles: + if ( + not self.with_handles + or _clip_property("Type") == "Video" + ): source_in += handle_start source_out -= handle_end From 41136557250175dcb829e62b12420b9316f7e2ae Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Oct 2023 17:19:58 +0200 Subject: [PATCH 064/690] updating pr changes to latest changes --- openpype/lib/transcoding.py | 17 +++- openpype/plugins/publish/extract_thumbnail.py | 77 ++++++++++--------- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 1b75b96525..7cd3671dd1 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -1149,9 +1149,9 @@ def convert_colorspace( target_colorspace=None, view=None, display=None, + additional_input_args=None, additional_command_args=None, logger=None, - input_args=None ): """Convert source file from one color space to another. @@ -1170,6 +1170,8 @@ def convert_colorspace( view (str): name for viewer space (ocio valid) both 'view' and 'display' must be filled (if 'target_colorspace') display (str): name for display-referred reference space (ocio valid) + both 'view' and 'display' must be filled (if 'target_colorspace') + additional_input_args (list): input arguments for oiiotool additional_command_args (list): arguments for oiiotool (like binary depth for .dpx) logger (logging.Logger): Logger used for logging. @@ -1179,12 +1181,21 @@ def convert_colorspace( if logger is None: logger = logging.getLogger(__name__) - oiio_cmd = get_oiio_tool_args( - "oiiotool", + # prepare main oiio command args + args = [ input_path, # Don't add any additional attributes "--nosoftwareattrib", "--colorconfig", config_path + ] + + # prepand any additional args if available + if additional_input_args: + args = additional_input_args + args + + oiio_cmd = get_oiio_tool_args( + "oiiotool", + *args ) if all([target_colorspace, view, display]): diff --git a/openpype/plugins/publish/extract_thumbnail.py b/openpype/plugins/publish/extract_thumbnail.py index ff416ecb23..5b75a374ba 100644 --- a/openpype/plugins/publish/extract_thumbnail.py +++ b/openpype/plugins/publish/extract_thumbnail.py @@ -5,7 +5,6 @@ import tempfile import pyblish.api from openpype.lib import ( get_ffmpeg_tool_args, - get_oiio_tool_args, is_oiio_supported, run_subprocess, @@ -26,7 +25,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): hosts = ["shell", "fusion", "resolve", "traypublisher", "substancepainter"] enabled = False - # presetable attribute + # presentable attribute ffmpeg_args = None def process(self, instance): @@ -95,27 +94,26 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): filename = os.path.splitext(input_file)[0] jpeg_file = filename + "_thumb.jpg" full_output_path = os.path.join(dst_staging, jpeg_file) + colorspace_data = repre.get("colorspaceData") - if oiio_supported: - self.log.debug("Trying to convert with OIIO") + # only use OIIO if it is supported and representation has + # colorspace data + if oiio_supported and colorspace_data: + self.log.debug( + "Trying to convert with OIIO " + "with colorspace data: {}".format(colorspace_data) + ) # If the input can read by OIIO then use OIIO method for # conversion otherwise use ffmpeg - colorspace_data = repre["colorspaceData"] - source_colorspace = colorspace_data["colorspace"] - config_path = colorspace_data.get("config", {}).get("path") - display = colorspace_data["display"] - view = colorspace_data["view"] thumbnail_created = self.create_thumbnail_oiio( full_input_path, full_output_path, - config_path, - source_colorspace, - display, - view + colorspace_data ) # Try to use FFMPEG if OIIO is not supported or for cases when - # oiiotool isn't available + # oiiotool isn't available or representation is not having + # colorspace data if not thumbnail_created: if oiio_supported: self.log.debug( @@ -149,7 +147,7 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): break if not thumbnail_created: - self.log.warning("Thumbanil has not been created.") + self.log.warning("Thumbnail has not been created.") def _is_review_instance(self, instance): # TODO: We should probably handle "not creating" of thumbnail @@ -188,21 +186,36 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): self, src_path, dst_path, - config_path, - source_colorspace, - display, - view + colorspace_data, ): + """Create thumbnail using OIIO tool oiiotool + + Args: + src_path (str): path to source file + dst_path (str): path to destination file + colorspace_data (dict): colorspace data from representation + keys: + colorspace (str) + config (dict) + display (Optional[str]) + view (Optional[str]) + + Returns: + str: path to created thumbnail + """ self.log.info("Extracting thumbnail {}".format(dst_path)) - oiio_cmd = get_oiio_tool_args( - "oiiotool", - "-a", src_path, - "-o", dst_path - ) - self.log.debug("running: {}".format(" ".join(oiio_cmd))) + try: - run_subprocess(oiio_cmd, logger=self.log) - return True + convert_colorspace( + src_path, + dst_path, + colorspace_data["config"]["path"], + colorspace_data["colorspace"], + display=colorspace_data.get("display"), + view=colorspace_data.get("view"), + additional_input_args=["-i:ch=R,G,B"], + logger=self.log, + ) except Exception: self.log.warning( "Failed to create thumbnail using oiiotool", @@ -210,16 +223,6 @@ class ExtractThumbnail(pyblish.api.InstancePlugin): ) return False - convert_colorspace( - src_path, - dst_path, - config_path, - source_colorspace, - view=view, - display=display, - input_args=["-i:ch=R,G,B"] - ) - return dst_path def create_thumbnail_ffmpeg(self, src_path, dst_path): From fc900780cd97fc15e4c91d24340dba02dd015aed Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Oct 2023 17:33:38 +0200 Subject: [PATCH 065/690] typo --- openpype/lib/transcoding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/transcoding.py b/openpype/lib/transcoding.py index 7cd3671dd1..07acc309d2 100644 --- a/openpype/lib/transcoding.py +++ b/openpype/lib/transcoding.py @@ -1189,7 +1189,7 @@ def convert_colorspace( "--colorconfig", config_path ] - # prepand any additional args if available + # prepend any additional args if available if additional_input_args: args = additional_input_args + args From 9e61d7e371d54a500cc1c67dd3c560d8cfcf98c1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Oct 2023 17:39:10 +0200 Subject: [PATCH 066/690] removing debug printing --- openpype/hosts/resolve/api/lib.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index ca79dd6e87..dfe4608a46 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -292,10 +292,6 @@ def create_timeline_item( "recordFrame": timeline_in, } - print("clip_data", "_" * 50) - print(media_pool_item.GetName()) - print(clip_data) - # add to timeline media_pool.AppendToTimeline([clip_data]) @@ -511,7 +507,7 @@ def imprint(timeline_item, data=None): Arguments: timeline_item (hiero.core.TrackItem): hiero track item object - data (dict): Any data which needst to be imprinted + data (dict): Any data which needs to be imprinted Examples: data = { From 3bbc3d0489db4ea0d785416e6459c79fee34701e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Tue, 17 Oct 2023 17:42:46 +0200 Subject: [PATCH 067/690] Update openpype/hosts/resolve/api/lib.py Co-authored-by: Roy Nieterau --- openpype/hosts/resolve/api/lib.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index dfe4608a46..20636f299b 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -251,10 +251,10 @@ def get_media_pool_item(filepath, root: object = None) -> object: def create_timeline_item( media_pool_item: object, - source_start: int, - source_end: int, - timeline_in: int, - timeline: object = None + timeline: object = None, + timeline_in: int = None, + source_start: int = None, + source_end: int = None, ) -> object: """ Add media pool item to current or defined timeline. From 435408dc142cb934424333257f8092db37974b01 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 17 Oct 2023 17:47:23 +0200 Subject: [PATCH 068/690] create_timeline_item with backward comapatibility --- openpype/hosts/resolve/api/lib.py | 30 ++++++++++++++++++---------- openpype/hosts/resolve/api/plugin.py | 4 ++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 20636f299b..6f84d921e0 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -261,10 +261,10 @@ def create_timeline_item( Args: media_pool_item (resolve.MediaPoolItem): resolve's object - source_start (int): media source input frame (sequence frame) - source_end (int): media source output frame (sequence frame) - timeline_in (int): timeline input frame (sequence frame) - timeline (resolve.Timeline)[optional]: resolve's object + timeline (Optional[resolve.Timeline]): resolve's object + timeline_in (Optional[int]): timeline input frame (sequence frame) + source_start (Optional[int]): media source input frame (sequence frame) + source_end (Optional[int]): media source output frame (sequence frame) Returns: object: resolve.TimelineItem @@ -277,21 +277,29 @@ def create_timeline_item( timeline = timeline or get_current_timeline() # timing variables - fps = project.GetSetting("timelineFrameRate") - duration = source_end - source_start - timecode_in = frames_to_timecode(timeline_in, fps) - timecode_out = frames_to_timecode(timeline_in + duration, fps) + if all([timeline_in, source_start, source_end]): + fps = project.GetSetting("timelineFrameRate") + duration = source_end - source_start + timecode_in = frames_to_timecode(timeline_in, fps) + timecode_out = frames_to_timecode(timeline_in + duration, fps) + else: + timecode_in = None + timecode_out = None # if timeline was used then switch it to current timeline with maintain_current_timeline(timeline): # Add input mediaPoolItem to clip data clip_data = { "mediaPoolItem": media_pool_item, - "startFrame": source_start, - "endFrame": source_end, - "recordFrame": timeline_in, } + if source_start: + clip_data["startFrame"] = source_start + if source_end: + clip_data["endFrame"] = source_end + if timecode_in: + clip_data["recordFrame"] = timecode_in + # add to timeline media_pool.AppendToTimeline([clip_data]) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 95f2fb2281..c88ed762ab 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -434,10 +434,10 @@ class ClipLoader: # make track item from source in bin as item timeline_item = lib.create_timeline_item( media_pool_item, + self.active_timeline, + timeline_in, source_in, source_out, - timeline_in, - self.active_timeline, ) print("Loading clips: `{}`".format(self.data["clip_name"])) From a810dfe78a97eb1467d3745ee786f2743f6faac2 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Oct 2023 12:30:57 +0200 Subject: [PATCH 069/690] fixing assert message --- openpype/hosts/resolve/api/lib.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 6f84d921e0..798c40a864 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -308,9 +308,9 @@ def create_timeline_item( assert output_timeline_item, AssertionError(( "Clip name '{}' was't created on the timeline: '{}' \n\n" - "Please check if the clip is in the media pool or if the timeline \n" - "is having activated correct track name, or if it is not already \n" - "having any clip add place on the timeline in: '{}' out: '{}'. \n\n" + "Please check if correct track position is activated, \n" + "or if a clip is not already at the timeline in \n" + "position: '{}' out: '{}'. \n\n" "Clip data: {}" ).format( clip_name, timeline.GetName(), timecode_in, timecode_out, clip_data From a11467883b5d1cec302f43361e7d939ff502ac07 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Oct 2023 12:34:12 +0200 Subject: [PATCH 070/690] getting fps from timeline instead of project --- openpype/hosts/resolve/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index 798c40a864..aef9caca78 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -278,7 +278,7 @@ def create_timeline_item( # timing variables if all([timeline_in, source_start, source_end]): - fps = project.GetSetting("timelineFrameRate") + fps = timeline.GetSetting("timelineFrameRate") duration = source_end - source_start timecode_in = frames_to_timecode(timeline_in, fps) timecode_out = frames_to_timecode(timeline_in + duration, fps) From fbc24f565415cc6cbb88547c9b333bf41a52a3e0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Oct 2023 12:48:50 +0200 Subject: [PATCH 071/690] make sure handles on timeline are included only if available or demanded --- openpype/hosts/resolve/api/plugin.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index c88ed762ab..9a09685bee 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -410,6 +410,18 @@ class ClipLoader: if handle_end is None: handle_end = int(self.data["assetData"]["handleEnd"]) + # check frame duration from versionData or assetData + frame_start = self.data["versionData"].get("frameStart") + if frame_start is None: + frame_start = self.data["assetData"]["frameStart"] + + # check frame duration from versionData or assetData + frame_end = self.data["versionData"].get("frameEnd") + if frame_end is None: + frame_end = self.data["assetData"]["frameEnd"] + + db_frame_duration = int(frame_end) - int(frame_start) + 1 + # get timeline in timeline_start = self.active_timeline.GetStartFrame() if self.sequential_load: @@ -423,10 +435,17 @@ class ClipLoader: source_in = int(_clip_property("Start")) source_out = int(_clip_property("End")) - # include handles + # check if source duration is shorter than db frame duration + source_with_handles = True + source_duration = source_out - source_in + 1 + if source_duration < db_frame_duration: + source_with_handles = False + + # only exclude handles if source has no handles or + # if user wants to load without handles if ( not self.with_handles - or _clip_property("Type") == "Video" + or not source_with_handles ): source_in += handle_start source_out -= handle_end From ed2756aa52372b296b5e0307e763339dd5890250 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Oct 2023 13:05:23 +0200 Subject: [PATCH 072/690] improving code readability --- openpype/hosts/resolve/api/plugin.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 9a09685bee..63da14b1c2 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -306,14 +306,18 @@ class ClipLoader: self.active_project = lib.get_current_project() # try to get value from options or evaluate key value for `handles` - self.with_handles = options.get("handles") or bool( - options.get("handles") is True) + self.with_handles = options.get("handles") is True + # try to get value from options or evaluate key value for `load_to` - self.new_timeline = options.get("newTimeline") or bool( - "New timeline" in options.get("load_to", "")) + self.new_timeline = ( + options.get("newTimeline") or + options.get("load_to") == "New timeline" + ) # try to get value from options or evaluate key value for `load_how` - self.sequential_load = options.get("sequentially") or bool( - "Sequentially in order" in options.get("load_how", "")) + self.sequential_load = ( + options.get("sequentially") or + options.get("load_how") == "Sequentially in order" + ) assert self._populate_data(), str( "Cannot Load selected data, look into database " From aa74d48836c990a66413e821bd09628e5480a00f Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 18 Oct 2023 14:00:57 +0200 Subject: [PATCH 073/690] clip duration from Frames clip attributes --- openpype/hosts/resolve/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 63da14b1c2..5c4a92df89 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -438,10 +438,10 @@ class ClipLoader: source_in = int(_clip_property("Start")) source_out = int(_clip_property("End")) + source_duration = int(_clip_property("Frames")) # check if source duration is shorter than db frame duration source_with_handles = True - source_duration = source_out - source_in + 1 if source_duration < db_frame_duration: source_with_handles = False From 9868b09c9bbd546d98148c7a80c087b87f84a766 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 10 Oct 2023 15:58:34 +0200 Subject: [PATCH 074/690] prepared context dialog using AYON calls --- openpype/tools/context_dialog/_ayon_window.py | 783 ++++++++++++++++++ .../tools/context_dialog/_openpype_window.py | 396 +++++++++ openpype/tools/context_dialog/window.py | 402 +-------- 3 files changed, 1188 insertions(+), 393 deletions(-) create mode 100644 openpype/tools/context_dialog/_ayon_window.py create mode 100644 openpype/tools/context_dialog/_openpype_window.py diff --git a/openpype/tools/context_dialog/_ayon_window.py b/openpype/tools/context_dialog/_ayon_window.py new file mode 100644 index 0000000000..6514780236 --- /dev/null +++ b/openpype/tools/context_dialog/_ayon_window.py @@ -0,0 +1,783 @@ +import os +import json + +import ayon_api +from qtpy import QtWidgets, QtCore, QtGui + +from openpype import style +from openpype.lib.events import QueuedEventSystem +from openpype.tools.ayon_utils.models import ( + ProjectsModel, + HierarchyModel, +) +from openpype.tools.ayon_utils.widgets import ( + ProjectsCombobox, + FoldersWidget, + TasksWidget, +) +from openpype.tools.utils.lib import ( + center_window, + get_openpype_qt_app, +) + + +class SelectionModel(object): + """Model handling selection changes. + + Triggering events: + - "selection.project.changed" + - "selection.folder.changed" + - "selection.task.changed" + """ + + event_source = "selection.model" + + def __init__(self, controller): + self._controller = controller + + self._project_name = None + self._folder_id = None + self._task_id = None + self._task_name = None + + def get_selected_project_name(self): + return self._project_name + + def set_selected_project(self, project_name): + self._project_name = project_name + self._controller.emit_event( + "selection.project.changed", + {"project_name": project_name}, + self.event_source + ) + + def get_selected_folder_id(self): + return self._folder_id + + def set_selected_folder(self, folder_id): + if folder_id == self._folder_id: + return + self._folder_id = folder_id + self._controller.emit_event( + "selection.folder.changed", + { + "project_name": self._project_name, + "folder_id": folder_id, + }, + self.event_source + ) + + def get_selected_task_name(self): + return self._task_name + + def get_selected_task_id(self): + return self._task_id + + def set_selected_task(self, task_id, task_name): + if task_id == self._task_id: + return + + self._task_name = task_name + self._task_id = task_id + self._controller.emit_event( + "selection.task.changed", + { + "project_name": self._project_name, + "folder_id": self._folder_id, + "task_name": task_name, + "task_id": task_id, + }, + self.event_source + ) + + +class ExpectedSelection: + def __init__(self, controller): + self._project_name = None + self._folder_id = None + + self._project_selected = True + self._folder_selected = True + + self._controller = controller + + def _emit_change(self): + self._controller.emit_event( + "expected_selection_changed", + self.get_expected_selection_data(), + ) + + def set_expected_selection(self, project_name, folder_id): + self._project_name = project_name + self._folder_id = folder_id + + self._project_selected = False + self._folder_selected = False + self._emit_change() + + def get_expected_selection_data(self): + project_current = False + folder_current = False + if not self._project_selected: + project_current = True + elif not self._folder_selected: + folder_current = True + return { + "project": { + "name": self._project_name, + "current": project_current, + "selected": self._project_selected, + }, + "folder": { + "id": self._folder_id, + "current": folder_current, + "selected": self._folder_selected, + }, + } + + def is_expected_project_selected(self, project_name): + return project_name == self._project_name and self._project_selected + + def is_expected_folder_selected(self, folder_id): + return folder_id == self._folder_id and self._folder_selected + + def expected_project_selected(self, project_name): + if project_name != self._project_name: + return False + self._project_selected = True + self._emit_change() + return True + + def expected_folder_selected(self, folder_id): + if folder_id != self._folder_id: + return False + self._folder_selected = True + self._emit_change() + return True + + +class ContextDialogController: + def __init__(self): + self._event_system = None + + self._projects_model = ProjectsModel(self) + self._hierarchy_model = HierarchyModel(self) + self._selection_model = SelectionModel(self) + self._expected_selection = ExpectedSelection(self) + + self._confirmed = False + self._is_strict = False + self._output_path = None + + self._initial_project_name = None + self._initial_folder_id = None + self._initial_folder_label = None + self._initial_project_found = True + self._initial_folder_found = True + self._initial_tasks_found = True + + def reset(self): + self._emit_event("controller.reset.started") + + self._confirmed = False + self._output_path = None + + self._initial_project_name = None + self._initial_folder_id = None + self._initial_folder_label = None + self._initial_project_found = True + self._initial_folder_found = True + self._initial_tasks_found = True + + self._projects_model.reset() + self._hierarchy_model.reset() + + self._emit_event("controller.reset.finished") + + def refresh(self): + self._emit_event("controller.refresh.started") + + self._projects_model.reset() + self._hierarchy_model.reset() + + self._emit_event("controller.refresh.finished") + + # Event handling + def emit_event(self, topic, data=None, source=None): + """Use implemented event system to trigger event.""" + + if data is None: + data = {} + self._get_event_system().emit(topic, data, source) + + def register_event_callback(self, topic, callback): + self._get_event_system().add_callback(topic, callback) + + def set_output_json_path(self, output_path): + self._output_path = output_path + + def is_strict(self): + return self._is_strict + + def set_strict(self, enabled): + if self._is_strict is enabled: + return + self._is_strict = enabled + self._emit_event("strict.changed", {"strict": enabled}) + + # Data model functions + def get_project_items(self, sender=None): + return self._projects_model.get_project_items(sender) + + def get_folder_items(self, project_name, sender=None): + return self._hierarchy_model.get_folder_items(project_name, sender) + + def get_task_items(self, project_name, folder_id, sender=None): + return self._hierarchy_model.get_task_items( + project_name, folder_id, sender + ) + + # Expected selection helpers + def set_expected_selection(self, project_name, folder_id): + return self._expected_selection.set_expected_selection( + project_name, folder_id + ) + + def get_expected_selection_data(self): + return self._expected_selection.get_expected_selection_data() + + def expected_project_selected(self, project_name): + self._expected_selection.expected_project_selected(project_name) + + def expected_folder_selected(self, folder_id): + self._expected_selection.expected_folder_selected(folder_id) + + # Selection handling + def get_selected_project_name(self): + return self._selection_model.get_selected_project_name() + + def set_selected_project(self, project_name): + self._selection_model.set_selected_project(project_name) + + def get_selected_folder_id(self): + return self._selection_model.get_selected_folder_id() + + def set_selected_folder(self, folder_id): + self._selection_model.set_selected_folder(folder_id) + + def get_selected_task_name(self): + return self._selection_model.get_selected_task_name() + + def get_selected_task_id(self): + return self._selection_model.get_selected_task_id() + + def set_selected_task(self, task_id, task_name): + self._selection_model.set_selected_task(task_id, task_name) + + def is_initial_context_valid(self): + return self._initial_folder_found and self._initial_project_found + + def set_initial_context( + self, project_name=None, asset_name=None, folder_path=None + ): + if project_name is None: + project_found = True + asset_name = None + folder_path = None + + else: + project = ayon_api.get_project(project_name) + project_found = project is not None + + folder_id = None + folder_found = True + folder_label = None + if folder_path: + folder_label = folder_path + folder = ayon_api.get_folder_by_path(project_name, folder_path) + if folder: + folder_id = folder["id"] + else: + folder_found = False + elif asset_name: + folder_label = asset_name + for folder in ayon_api.get_folders( + project_name, folder_names=[asset_name] + ): + folder_id = folder["id"] + break + if not folder_id: + folder_found = False + + tasks_found = True + if folder_found and (folder_path or asset_name): + tasks = list(ayon_api.get_tasks( + project_name, folder_ids=[folder_id], fields=["id"] + )) + if not tasks: + tasks_found = False + + self._initial_project_name = project_name + self._initial_folder_id = folder_id + self._initial_folder_label = folder_label + self._initial_folder_found = project_found + self._initial_folder_found = folder_found + self._initial_tasks_found = tasks_found + self._emit_event( + "initial.context.changed", + self.get_initial_context() + ) + + def get_initial_context(self): + return { + "project_name": self._initial_project_name, + "folder_id": self._initial_folder_id, + "folder_label": self._initial_folder_label, + "project_found": self._initial_project_found, + "folder_found": self._initial_folder_found, + "tasks_found": self._initial_tasks_found, + "valid": ( + self._initial_project_found + and self._initial_folder_found + and self._initial_tasks_found + ) + } + + # Result of this tool + def get_selected_context(self): + return { + "project": None, + "project_name": None, + "asset": None, + "folder_id": None, + "folder_path": None, + "task": None, + "task_id": None, + "task_name": None, + } + + def window_closed(self): + if not self._confirmed and not self._is_strict: + return + + self._store_output() + + def confirm_selection(self): + self._confirmed = True + self._emit_event( + "selection.confirmed", + {"confirmed": True} + ) + + def _store_output(self): + if not self._output_path: + return + + dirpath = os.path.dirname(self._output_path) + os.makedirs(dirpath, exist_ok=True) + with open(self._output_path, "w") as stream: + json.dump(self.get_selected_context(), stream) + + def _get_event_system(self): + """Inner event system for workfiles tool controller. + + Is used for communication with UI. Event system is created on demand. + + Returns: + QueuedEventSystem: Event system which can trigger callbacks + for topics. + """ + + if self._event_system is None: + self._event_system = QueuedEventSystem() + return self._event_system + + def _emit_event(self, topic, data=None): + self.emit_event(topic, data, "controller") + + +class InvalidContextOverlay(QtWidgets.QFrame): + confirmed = QtCore.Signal() + + def __init__(self, parent): + super(InvalidContextOverlay, self).__init__(parent) + self.setObjectName("OverlayFrame") + + mid_widget = QtWidgets.QWidget(self) + label_widget = QtWidgets.QLabel( + "Requested context was not found...", + mid_widget + ) + + confirm_btn = QtWidgets.QPushButton("Close", mid_widget) + + mid_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + label_widget.setAttribute(QtCore.Qt.WA_TranslucentBackground) + + mid_layout = QtWidgets.QVBoxLayout(mid_widget) + mid_layout.setContentsMargins(0, 0, 0, 0) + mid_layout.addWidget(label_widget, 0) + mid_layout.addSpacing(30) + mid_layout.addWidget(confirm_btn, 0) + + main_layout = QtWidgets.QGridLayout(self) + main_layout.setContentsMargins(0, 0, 0, 0) + main_layout.addWidget(mid_widget, 1, 1) + main_layout.setRowStretch(0, 1) + main_layout.setRowStretch(1, 0) + main_layout.setRowStretch(2, 1) + main_layout.setColumnStretch(0, 1) + main_layout.setColumnStretch(1, 0) + main_layout.setColumnStretch(2, 1) + + confirm_btn.clicked.connect(self.confirmed) + + self._label_widget = label_widget + self._confirm_btn = confirm_btn + + def set_context( + self, + project_name, + folder_label, + project_found, + folder_found, + tasks_found, + ): + lines = [] + if not project_found: + lines.extend([ + "Requested project {} was not found...".format(project_name), + ]) + + elif not folder_found: + lines.extend([ + "Requested folder was not found...", + "", + "Project: {}".format(project_name), + "Folder: {}".format(folder_label), + ]) + elif not tasks_found: + lines.extend([ + "Requested folder does not have any tasks...", + "", + "Project: {}".format(project_name), + "Folder: {}".format(folder_label), + ]) + else: + lines.append("Requested context was not found...") + self._label_widget.setText("
".join(lines)) + + +class ContextDialog(QtWidgets.QDialog): + """Dialog to select a context. + + Context has 3 parts: + - Project + - Asset + - Task + + It is possible to predefine project and asset. In that case their widgets + will have passed preselected values and will be disabled. + """ + def __init__(self, controller=None, parent=None): + super(ContextDialog, self).__init__(parent) + + self.setWindowTitle("Select Context") + self.setWindowIcon(QtGui.QIcon(style.app_icon_path())) + + if controller is None: + controller = ContextDialogController() + + # Enable minimize and maximize for app + window_flags = QtCore.Qt.Window + if not parent: + window_flags |= QtCore.Qt.WindowStaysOnTopHint + self.setWindowFlags(window_flags) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + # UI initialization + main_splitter = QtWidgets.QSplitter(self) + + # Left side widget contains project combobox and asset widget + left_side_widget = QtWidgets.QWidget(main_splitter) + + project_combobox = ProjectsCombobox( + controller, + parent=left_side_widget, + handle_expected_selection=True + ) + + # Assets widget + folders_widget = FoldersWidget( + controller, + parent=left_side_widget, + handle_expected_selection=True + ) + + left_side_layout = QtWidgets.QVBoxLayout(left_side_widget) + left_side_layout.setContentsMargins(0, 0, 0, 0) + left_side_layout.addWidget(project_combobox, 0) + left_side_layout.addWidget(folders_widget, 1) + + # Right side of window contains only tasks + tasks_widget = TasksWidget(controller, parent=main_splitter) + + # Add widgets to main splitter + main_splitter.addWidget(left_side_widget) + main_splitter.addWidget(tasks_widget) + + # Set stretch of both sides + main_splitter.setStretchFactor(0, 7) + main_splitter.setStretchFactor(1, 3) + + # Add confimation button to bottom right + ok_btn = QtWidgets.QPushButton("OK", self) + + buttons_layout = QtWidgets.QHBoxLayout() + buttons_layout.setContentsMargins(0, 0, 0, 0) + buttons_layout.addStretch(1) + buttons_layout.addWidget(ok_btn, 0) + + main_layout = QtWidgets.QVBoxLayout(self) + main_layout.addWidget(main_splitter, 1) + main_layout.addLayout(buttons_layout, 0) + + overlay_widget = InvalidContextOverlay(self) + overlay_widget.setVisible(False) + + ok_btn.clicked.connect(self._on_ok_click) + project_combobox.refreshed.connect(self._on_projects_refresh) + overlay_widget.confirmed.connect(self._on_overlay_confirm) + + controller.register_event_callback( + "selection.project.changed", + self._on_project_selection_change + ) + controller.register_event_callback( + "selection.folder.changed", + self._on_folder_selection_change + ) + controller.register_event_callback( + "selection.task.changed", + self._on_task_selection_change + ) + controller.register_event_callback( + "initial.context.changed", + self._on_init_context_change + ) + controller.register_event_callback( + "strict.changed", + self._on_strict_changed + ) + controller.register_event_callback( + "controller.reset.finished", + self._on_controller_reset + ) + controller.register_event_callback( + "controller.refresh.finished", + self._on_controller_refresh + ) + + # Set stylehseet and resize window on first show + self._first_show = True + self._visible = False + + self._controller = controller + + self._project_combobox = project_combobox + self._folders_widget = folders_widget + self._tasks_widget = tasks_widget + + self._ok_btn = ok_btn + + self._overlay_widget = overlay_widget + + self._apply_strict_changes(self.is_strict()) + + def is_strict(self): + return self._controller.is_strict() + + def showEvent(self, event): + """Override show event to do some callbacks.""" + super(ContextDialog, self).showEvent(event) + self._visible = True + + if self._first_show: + self._first_show = False + # Set stylesheet and resize + self.setStyleSheet(style.load_stylesheet()) + self.resize(600, 700) + center_window(self) + self._controller.refresh() + + initial_context = self._controller.get_initial_context() + self._set_init_context(initial_context) + self._overlay_widget.resize(self.size()) + + def resizeEvent(self, event): + super(ContextDialog, self).resizeEvent(event) + self._overlay_widget.resize(self.size()) + + def closeEvent(self, event): + """Ignore close event if is in strict state and context is not done.""" + if self.is_strict() and not self._ok_btn.isEnabled(): + # Allow to close window when initial context is not valid + if self._controller.is_initial_context_valid(): + event.ignore() + return + + if self.is_strict(): + self._controller.confirm_selection() + self._visible = False + super(ContextDialog, self).closeEvent(event) + + def set_strict(self, enabled): + """Change strictness of dialog.""" + + self._controller.set_strict(enabled) + + def refresh(self): + """Refresh all widget one by one. + + When asset refresh is triggered we have to wait when is done so + this method continues with `_on_asset_widget_refresh_finished`. + """ + + self._controller.reset() + + def get_context(self): + """Result of dialog.""" + return self._controller.get_selected_context() + + def set_context(self, project_name=None, asset_name=None): + """Set context which will be used and locked in dialog.""" + + self._controller.set_initial_context(project_name, asset_name) + + def _on_projects_refresh(self): + initial_context = self._controller.get_initial_context() + self._controller.set_expected_selection( + initial_context["project_name"], + initial_context["folder_id"] + ) + + def _on_overlay_confirm(self): + self.close() + + def _on_ok_click(self): + # Store values to output + self._controller.confirm_selection() + # Close dialog + self.accept() + + def _on_project_selection_change(self, event): + self._on_selection_change( + event["project_name"], + ) + + def _on_folder_selection_change(self, event): + self._on_selection_change( + event["project_name"], + event["folder_id"], + ) + + def _on_task_selection_change(self, event): + self._on_selection_change( + event["project_name"], + event["folder_id"], + event["task_name"], + ) + + def _on_selection_change( + self, project_name, folder_id=None, task_name=None + ): + self._validate_strict(project_name, folder_id, task_name) + + def _on_init_context_change(self, event): + self._set_init_context(event.data) + if self._visible: + self._controller.set_expected_selection( + event["project_name"], event["folder_id"] + ) + + def _set_init_context(self, init_context): + project_name = init_context["project_name"] + if not init_context["valid"]: + self._overlay_widget.setVisible(True) + self._overlay_widget.set_context( + project_name, + init_context["folder_label"], + init_context["project_found"], + init_context["folder_found"], + init_context["tasks_found"] + ) + return + + self._overlay_widget.setVisible(False) + if project_name: + self._project_combobox.setEnabled(False) + if init_context["folder_id"]: + self._folders_widget.setEnabled(False) + else: + self._project_combobox.setEnabled(True) + self._folders_widget.setEnabled(True) + + def _on_strict_changed(self, event): + self._apply_strict_changes(event["strict"]) + + def _on_controller_reset(self): + self._apply_strict_changes(self.is_strict()) + self._project_combobox.refresh() + + def _on_controller_refresh(self): + self._project_combobox.refresh() + + def _apply_strict_changes(self, is_strict): + if not is_strict: + if not self._ok_btn.isEnabled(): + self._ok_btn.setEnabled(True) + return + context = self._controller.get_selected_context() + self._validate_strict( + context["project_name"], + context["folder_id"], + context["task_name"] + ) + + def _validate_strict(self, project_name, folder_id, task_name): + if not self.is_strict(): + return + + enabled = True + if not project_name or not folder_id or not task_name: + enabled = False + self._ok_btn.setEnabled(enabled) + + +def main( + path_to_store, + project_name=None, + asset_name=None, + strict=True +): + # Run Qt application + app = get_openpype_qt_app() + controller = ContextDialogController() + controller.set_strict(strict) + controller.set_initial_context(project_name, asset_name) + controller.set_output_json_path(path_to_store) + window = ContextDialog(controller=controller) + window.show() + app.exec_() + + # Get result from window + data = window.get_context() + + # Make sure json filepath directory exists + file_dir = os.path.dirname(path_to_store) + if not os.path.exists(file_dir): + os.makedirs(file_dir) + + # Store result into json file + with open(path_to_store, "w") as stream: + json.dump(data, stream) diff --git a/openpype/tools/context_dialog/_openpype_window.py b/openpype/tools/context_dialog/_openpype_window.py new file mode 100644 index 0000000000..d370772a7f --- /dev/null +++ b/openpype/tools/context_dialog/_openpype_window.py @@ -0,0 +1,396 @@ +import os +import json + +from qtpy import QtWidgets, QtCore, QtGui + +from openpype import style +from openpype.pipeline import AvalonMongoDB +from openpype.tools.utils.lib import center_window, get_openpype_qt_app +from openpype.tools.utils.assets_widget import SingleSelectAssetsWidget +from openpype.tools.utils.constants import ( + PROJECT_NAME_ROLE +) +from openpype.tools.utils.tasks_widget import TasksWidget +from openpype.tools.utils.models import ( + ProjectModel, + ProjectSortFilterProxy +) + + +class ContextDialog(QtWidgets.QDialog): + """Dialog to select a context. + + Context has 3 parts: + - Project + - Asset + - Task + + It is possible to predefine project and asset. In that case their widgets + will have passed preselected values and will be disabled. + """ + def __init__(self, parent=None): + super(ContextDialog, self).__init__(parent) + + self.setWindowTitle("Select Context") + self.setWindowIcon(QtGui.QIcon(style.app_icon_path())) + + # Enable minimize and maximize for app + window_flags = QtCore.Qt.Window + if not parent: + window_flags |= QtCore.Qt.WindowStaysOnTopHint + self.setWindowFlags(window_flags) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + + dbcon = AvalonMongoDB() + + # UI initialization + main_splitter = QtWidgets.QSplitter(self) + + # Left side widget contains project combobox and asset widget + left_side_widget = QtWidgets.QWidget(main_splitter) + + project_combobox = QtWidgets.QComboBox(left_side_widget) + # Styled delegate to propagate stylessheet + project_delegate = QtWidgets.QStyledItemDelegate(project_combobox) + project_combobox.setItemDelegate(project_delegate) + # Project model with only active projects without default item + project_model = ProjectModel( + dbcon, + only_active=True, + add_default_project=False + ) + # Sorting proxy model + project_proxy = ProjectSortFilterProxy() + project_proxy.setSourceModel(project_model) + project_combobox.setModel(project_proxy) + + # Assets widget + assets_widget = SingleSelectAssetsWidget( + dbcon, parent=left_side_widget + ) + + left_side_layout = QtWidgets.QVBoxLayout(left_side_widget) + left_side_layout.setContentsMargins(0, 0, 0, 0) + left_side_layout.addWidget(project_combobox) + left_side_layout.addWidget(assets_widget) + + # Right side of window contains only tasks + tasks_widget = TasksWidget(dbcon, main_splitter) + + # Add widgets to main splitter + main_splitter.addWidget(left_side_widget) + main_splitter.addWidget(tasks_widget) + + # Set stretch of both sides + main_splitter.setStretchFactor(0, 7) + main_splitter.setStretchFactor(1, 3) + + # Add confimation button to bottom right + ok_btn = QtWidgets.QPushButton("OK", self) + + buttons_layout = QtWidgets.QHBoxLayout() + buttons_layout.setContentsMargins(0, 0, 0, 0) + buttons_layout.addStretch(1) + buttons_layout.addWidget(ok_btn, 0) + + main_layout = QtWidgets.QVBoxLayout(self) + main_layout.addWidget(main_splitter, 1) + main_layout.addLayout(buttons_layout, 0) + + # Timer which will trigger asset refresh + # - this is needed because asset widget triggers + # finished refresh before hides spin box so we need to trigger + # refreshing in small offset if we want re-refresh asset widget + assets_timer = QtCore.QTimer() + assets_timer.setInterval(50) + assets_timer.setSingleShot(True) + + assets_timer.timeout.connect(self._on_asset_refresh_timer) + + project_combobox.currentIndexChanged.connect( + self._on_project_combo_change + ) + assets_widget.selection_changed.connect(self._on_asset_change) + assets_widget.refresh_triggered.connect(self._on_asset_refresh_trigger) + assets_widget.refreshed.connect(self._on_asset_widget_refresh_finished) + tasks_widget.task_changed.connect(self._on_task_change) + ok_btn.clicked.connect(self._on_ok_click) + + self._dbcon = dbcon + + self._project_combobox = project_combobox + self._project_model = project_model + self._project_proxy = project_proxy + self._project_delegate = project_delegate + + self._assets_widget = assets_widget + + self._tasks_widget = tasks_widget + + self._ok_btn = ok_btn + + self._strict = False + + # Values set by `set_context` method + self._set_context_project = None + self._set_context_asset = None + + # Requirements for asset widget refresh + self._assets_timer = assets_timer + self._rerefresh_assets = True + self._assets_refreshing = False + + # Set stylehseet and resize window on first show + self._first_show = True + + # Helper attributes for handling of refresh + self._ignore_value_changes = False + self._refresh_on_next_show = True + + # Output of dialog + self._context_to_store = { + "project": None, + "asset": None, + "task": None + } + + def closeEvent(self, event): + """Ignore close event if is in strict state and context is not done.""" + if self._strict and not self._ok_btn.isEnabled(): + event.ignore() + return + + if self._strict: + self._confirm_values() + super(ContextDialog, self).closeEvent(event) + + def set_strict(self, strict): + """Change strictness of dialog.""" + self._strict = strict + self._validate_strict() + + def _set_refresh_on_next_show(self): + """Refresh will be called on next showEvent. + + If window is already visible then just execute refresh. + """ + self._refresh_on_next_show = True + if self.isVisible(): + self.refresh() + + def _refresh_assets(self): + """Trigger refreshing of asset widget. + + This will set mart to rerefresh asset when current refreshing is done + or do it immidietely if asset widget is not refreshing at the time. + """ + if self._assets_refreshing: + self._rerefresh_assets = True + else: + self._on_asset_refresh_timer() + + def showEvent(self, event): + """Override show event to do some callbacks.""" + super(ContextDialog, self).showEvent(event) + if self._first_show: + self._first_show = False + # Set stylesheet and resize + self.setStyleSheet(style.load_stylesheet()) + self.resize(600, 700) + center_window(self) + + if self._refresh_on_next_show: + self.refresh() + + def refresh(self): + """Refresh all widget one by one. + + When asset refresh is triggered we have to wait when is done so + this method continues with `_on_asset_widget_refresh_finished`. + """ + # Change state of refreshing (no matter how refresh was called) + self._refresh_on_next_show = False + + # Ignore changes of combobox and asset widget + self._ignore_value_changes = True + + # Get current project name to be able set it afterwards + select_project_name = self._dbcon.Session.get("AVALON_PROJECT") + # Trigger project refresh + self._project_model.refresh() + # Sort projects + self._project_proxy.sort(0) + + # Disable combobox if project was passed to `set_context` + if self._set_context_project: + select_project_name = self._set_context_project + self._project_combobox.setEnabled(False) + else: + # Find new project to select + self._project_combobox.setEnabled(True) + if ( + select_project_name is None + and self._project_proxy.rowCount() > 0 + ): + index = self._project_proxy.index(0, 0) + select_project_name = index.data(PROJECT_NAME_ROLE) + + self._ignore_value_changes = False + + idx = self._project_combobox.findText(select_project_name) + if idx >= 0: + self._project_combobox.setCurrentIndex(idx) + self._dbcon.Session["AVALON_PROJECT"] = ( + self._project_combobox.currentText() + ) + + # Trigger asset refresh + self._refresh_assets() + + def _on_asset_refresh_timer(self): + """This is only way how to trigger refresh asset widget. + + Use `_refresh_assets` method to refresh asset widget. + """ + self._assets_widget.refresh() + + def _on_asset_widget_refresh_finished(self): + """Catch when asset widget finished refreshing.""" + # If should refresh again then skip all other callbacks and trigger + # assets timer directly. + self._assets_refreshing = False + if self._rerefresh_assets: + self._rerefresh_assets = False + self._assets_timer.start() + return + + self._ignore_value_changes = True + if self._set_context_asset: + self._dbcon.Session["AVALON_ASSET"] = self._set_context_asset + self._assets_widget.setEnabled(False) + self._assets_widget.select_asset_by_name(self._set_context_asset) + self._set_asset_to_tasks_widget() + else: + self._assets_widget.setEnabled(True) + self._assets_widget.set_current_asset_btn_visibility(False) + + # Refresh tasks + self._tasks_widget.refresh() + + self._ignore_value_changes = False + + self._validate_strict() + + def _on_project_combo_change(self): + if self._ignore_value_changes: + return + project_name = self._project_combobox.currentText() + + if self._dbcon.Session.get("AVALON_PROJECT") == project_name: + return + + self._dbcon.Session["AVALON_PROJECT"] = project_name + + self._refresh_assets() + self._validate_strict() + + def _on_asset_refresh_trigger(self): + self._assets_refreshing = True + self._on_asset_change() + + def _on_asset_change(self): + """Selected assets have changed""" + if self._ignore_value_changes: + return + self._set_asset_to_tasks_widget() + + def _on_task_change(self): + self._validate_strict() + + def _set_asset_to_tasks_widget(self): + asset_id = self._assets_widget.get_selected_asset_id() + + self._tasks_widget.set_asset_id(asset_id) + + def _confirm_values(self): + """Store values to output.""" + self._context_to_store["project"] = self.get_selected_project() + self._context_to_store["asset"] = self.get_selected_asset() + self._context_to_store["task"] = self.get_selected_task() + + def _on_ok_click(self): + # Store values to output + self._confirm_values() + # Close dialog + self.accept() + + def get_selected_project(self): + """Get selected project.""" + return self._project_combobox.currentText() + + def get_selected_asset(self): + """Currently selected asset in asset widget.""" + return self._assets_widget.get_selected_asset_name() + + def get_selected_task(self): + """Currently selected task.""" + return self._tasks_widget.get_selected_task_name() + + def _validate_strict(self): + if not self._strict: + if not self._ok_btn.isEnabled(): + self._ok_btn.setEnabled(True) + return + + enabled = True + if not self._set_context_project and not self.get_selected_project(): + enabled = False + elif not self._set_context_asset and not self.get_selected_asset(): + enabled = False + elif not self.get_selected_task(): + enabled = False + self._ok_btn.setEnabled(enabled) + + def set_context(self, project_name=None, asset_name=None): + """Set context which will be used and locked in dialog.""" + if project_name is None: + asset_name = None + + self._set_context_project = project_name + self._set_context_asset = asset_name + + self._context_to_store["project"] = project_name + self._context_to_store["asset"] = asset_name + + self._set_refresh_on_next_show() + + def get_context(self): + """Result of dialog.""" + return self._context_to_store + + +def main( + path_to_store, + project_name=None, + asset_name=None, + strict=True +): + # Run Qt application + app = get_openpype_qt_app() + window = ContextDialog() + window.set_strict(strict) + window.set_context(project_name, asset_name) + window.show() + app.exec_() + + # Get result from window + data = window.get_context() + + # Make sure json filepath directory exists + file_dir = os.path.dirname(path_to_store) + if not os.path.exists(file_dir): + os.makedirs(file_dir) + + # Store result into json file + with open(path_to_store, "w") as stream: + json.dump(data, stream) diff --git a/openpype/tools/context_dialog/window.py b/openpype/tools/context_dialog/window.py index 4fe41c9949..15b90463da 100644 --- a/openpype/tools/context_dialog/window.py +++ b/openpype/tools/context_dialog/window.py @@ -1,396 +1,12 @@ -import os -import json +from openpype import AYON_SERVER_ENABLED -from qtpy import QtWidgets, QtCore, QtGui +if AYON_SERVER_ENABLED: + from ._ayon_window import ContextDialog, main +else: + from ._openpype_window import ContextDialog, main -from openpype import style -from openpype.pipeline import AvalonMongoDB -from openpype.tools.utils.lib import center_window, get_openpype_qt_app -from openpype.tools.utils.assets_widget import SingleSelectAssetsWidget -from openpype.tools.utils.constants import ( - PROJECT_NAME_ROLE + +__all__ = ( + "ContextDialog", + "main", ) -from openpype.tools.utils.tasks_widget import TasksWidget -from openpype.tools.utils.models import ( - ProjectModel, - ProjectSortFilterProxy -) - - -class ContextDialog(QtWidgets.QDialog): - """Dialog to select a context. - - Context has 3 parts: - - Project - - Aseet - - Task - - It is possible to predefine project and asset. In that case their widgets - will have passed preselected values and will be disabled. - """ - def __init__(self, parent=None): - super(ContextDialog, self).__init__(parent) - - self.setWindowTitle("Select Context") - self.setWindowIcon(QtGui.QIcon(style.app_icon_path())) - - # Enable minimize and maximize for app - window_flags = QtCore.Qt.Window - if not parent: - window_flags |= QtCore.Qt.WindowStaysOnTopHint - self.setWindowFlags(window_flags) - self.setFocusPolicy(QtCore.Qt.StrongFocus) - - dbcon = AvalonMongoDB() - - # UI initialization - main_splitter = QtWidgets.QSplitter(self) - - # Left side widget contains project combobox and asset widget - left_side_widget = QtWidgets.QWidget(main_splitter) - - project_combobox = QtWidgets.QComboBox(left_side_widget) - # Styled delegate to propagate stylessheet - project_delegate = QtWidgets.QStyledItemDelegate(project_combobox) - project_combobox.setItemDelegate(project_delegate) - # Project model with only active projects without default item - project_model = ProjectModel( - dbcon, - only_active=True, - add_default_project=False - ) - # Sorting proxy model - project_proxy = ProjectSortFilterProxy() - project_proxy.setSourceModel(project_model) - project_combobox.setModel(project_proxy) - - # Assets widget - assets_widget = SingleSelectAssetsWidget( - dbcon, parent=left_side_widget - ) - - left_side_layout = QtWidgets.QVBoxLayout(left_side_widget) - left_side_layout.setContentsMargins(0, 0, 0, 0) - left_side_layout.addWidget(project_combobox) - left_side_layout.addWidget(assets_widget) - - # Right side of window contains only tasks - tasks_widget = TasksWidget(dbcon, main_splitter) - - # Add widgets to main splitter - main_splitter.addWidget(left_side_widget) - main_splitter.addWidget(tasks_widget) - - # Set stretch of both sides - main_splitter.setStretchFactor(0, 7) - main_splitter.setStretchFactor(1, 3) - - # Add confimation button to bottom right - ok_btn = QtWidgets.QPushButton("OK", self) - - buttons_layout = QtWidgets.QHBoxLayout() - buttons_layout.setContentsMargins(0, 0, 0, 0) - buttons_layout.addStretch(1) - buttons_layout.addWidget(ok_btn, 0) - - main_layout = QtWidgets.QVBoxLayout(self) - main_layout.addWidget(main_splitter, 1) - main_layout.addLayout(buttons_layout, 0) - - # Timer which will trigger asset refresh - # - this is needed because asset widget triggers - # finished refresh before hides spin box so we need to trigger - # refreshing in small offset if we want re-refresh asset widget - assets_timer = QtCore.QTimer() - assets_timer.setInterval(50) - assets_timer.setSingleShot(True) - - assets_timer.timeout.connect(self._on_asset_refresh_timer) - - project_combobox.currentIndexChanged.connect( - self._on_project_combo_change - ) - assets_widget.selection_changed.connect(self._on_asset_change) - assets_widget.refresh_triggered.connect(self._on_asset_refresh_trigger) - assets_widget.refreshed.connect(self._on_asset_widget_refresh_finished) - tasks_widget.task_changed.connect(self._on_task_change) - ok_btn.clicked.connect(self._on_ok_click) - - self._dbcon = dbcon - - self._project_combobox = project_combobox - self._project_model = project_model - self._project_proxy = project_proxy - self._project_delegate = project_delegate - - self._assets_widget = assets_widget - - self._tasks_widget = tasks_widget - - self._ok_btn = ok_btn - - self._strict = False - - # Values set by `set_context` method - self._set_context_project = None - self._set_context_asset = None - - # Requirements for asset widget refresh - self._assets_timer = assets_timer - self._rerefresh_assets = True - self._assets_refreshing = False - - # Set stylehseet and resize window on first show - self._first_show = True - - # Helper attributes for handling of refresh - self._ignore_value_changes = False - self._refresh_on_next_show = True - - # Output of dialog - self._context_to_store = { - "project": None, - "asset": None, - "task": None - } - - def closeEvent(self, event): - """Ignore close event if is in strict state and context is not done.""" - if self._strict and not self._ok_btn.isEnabled(): - event.ignore() - return - - if self._strict: - self._confirm_values() - super(ContextDialog, self).closeEvent(event) - - def set_strict(self, strict): - """Change strictness of dialog.""" - self._strict = strict - self._validate_strict() - - def _set_refresh_on_next_show(self): - """Refresh will be called on next showEvent. - - If window is already visible then just execute refresh. - """ - self._refresh_on_next_show = True - if self.isVisible(): - self.refresh() - - def _refresh_assets(self): - """Trigger refreshing of asset widget. - - This will set mart to rerefresh asset when current refreshing is done - or do it immidietely if asset widget is not refreshing at the time. - """ - if self._assets_refreshing: - self._rerefresh_assets = True - else: - self._on_asset_refresh_timer() - - def showEvent(self, event): - """Override show event to do some callbacks.""" - super(ContextDialog, self).showEvent(event) - if self._first_show: - self._first_show = False - # Set stylesheet and resize - self.setStyleSheet(style.load_stylesheet()) - self.resize(600, 700) - center_window(self) - - if self._refresh_on_next_show: - self.refresh() - - def refresh(self): - """Refresh all widget one by one. - - When asset refresh is triggered we have to wait when is done so - this method continues with `_on_asset_widget_refresh_finished`. - """ - # Change state of refreshing (no matter how refresh was called) - self._refresh_on_next_show = False - - # Ignore changes of combobox and asset widget - self._ignore_value_changes = True - - # Get current project name to be able set it afterwards - select_project_name = self._dbcon.Session.get("AVALON_PROJECT") - # Trigger project refresh - self._project_model.refresh() - # Sort projects - self._project_proxy.sort(0) - - # Disable combobox if project was passed to `set_context` - if self._set_context_project: - select_project_name = self._set_context_project - self._project_combobox.setEnabled(False) - else: - # Find new project to select - self._project_combobox.setEnabled(True) - if ( - select_project_name is None - and self._project_proxy.rowCount() > 0 - ): - index = self._project_proxy.index(0, 0) - select_project_name = index.data(PROJECT_NAME_ROLE) - - self._ignore_value_changes = False - - idx = self._project_combobox.findText(select_project_name) - if idx >= 0: - self._project_combobox.setCurrentIndex(idx) - self._dbcon.Session["AVALON_PROJECT"] = ( - self._project_combobox.currentText() - ) - - # Trigger asset refresh - self._refresh_assets() - - def _on_asset_refresh_timer(self): - """This is only way how to trigger refresh asset widget. - - Use `_refresh_assets` method to refresh asset widget. - """ - self._assets_widget.refresh() - - def _on_asset_widget_refresh_finished(self): - """Catch when asset widget finished refreshing.""" - # If should refresh again then skip all other callbacks and trigger - # assets timer directly. - self._assets_refreshing = False - if self._rerefresh_assets: - self._rerefresh_assets = False - self._assets_timer.start() - return - - self._ignore_value_changes = True - if self._set_context_asset: - self._dbcon.Session["AVALON_ASSET"] = self._set_context_asset - self._assets_widget.setEnabled(False) - self._assets_widget.select_assets(self._set_context_asset) - self._set_asset_to_tasks_widget() - else: - self._assets_widget.setEnabled(True) - self._assets_widget.set_current_asset_btn_visibility(False) - - # Refresh tasks - self._tasks_widget.refresh() - - self._ignore_value_changes = False - - self._validate_strict() - - def _on_project_combo_change(self): - if self._ignore_value_changes: - return - project_name = self._project_combobox.currentText() - - if self._dbcon.Session.get("AVALON_PROJECT") == project_name: - return - - self._dbcon.Session["AVALON_PROJECT"] = project_name - - self._refresh_assets() - self._validate_strict() - - def _on_asset_refresh_trigger(self): - self._assets_refreshing = True - self._on_asset_change() - - def _on_asset_change(self): - """Selected assets have changed""" - if self._ignore_value_changes: - return - self._set_asset_to_tasks_widget() - - def _on_task_change(self): - self._validate_strict() - - def _set_asset_to_tasks_widget(self): - asset_id = self._assets_widget.get_selected_asset_id() - - self._tasks_widget.set_asset_id(asset_id) - - def _confirm_values(self): - """Store values to output.""" - self._context_to_store["project"] = self.get_selected_project() - self._context_to_store["asset"] = self.get_selected_asset() - self._context_to_store["task"] = self.get_selected_task() - - def _on_ok_click(self): - # Store values to output - self._confirm_values() - # Close dialog - self.accept() - - def get_selected_project(self): - """Get selected project.""" - return self._project_combobox.currentText() - - def get_selected_asset(self): - """Currently selected asset in asset widget.""" - return self._assets_widget.get_selected_asset_name() - - def get_selected_task(self): - """Currently selected task.""" - return self._tasks_widget.get_selected_task_name() - - def _validate_strict(self): - if not self._strict: - if not self._ok_btn.isEnabled(): - self._ok_btn.setEnabled(True) - return - - enabled = True - if not self._set_context_project and not self.get_selected_project(): - enabled = False - elif not self._set_context_asset and not self.get_selected_asset(): - enabled = False - elif not self.get_selected_task(): - enabled = False - self._ok_btn.setEnabled(enabled) - - def set_context(self, project_name=None, asset_name=None): - """Set context which will be used and locked in dialog.""" - if project_name is None: - asset_name = None - - self._set_context_project = project_name - self._set_context_asset = asset_name - - self._context_to_store["project"] = project_name - self._context_to_store["asset"] = asset_name - - self._set_refresh_on_next_show() - - def get_context(self): - """Result of dialog.""" - return self._context_to_store - - -def main( - path_to_store, - project_name=None, - asset_name=None, - strict=True -): - # Run Qt application - app = get_openpype_qt_app() - window = ContextDialog() - window.set_strict(strict) - window.set_context(project_name, asset_name) - window.show() - app.exec_() - - # Get result from window - data = window.get_context() - - # Make sure json filepath directory exists - file_dir = os.path.dirname(path_to_store) - if not os.path.exists(file_dir): - os.makedirs(file_dir) - - # Store result into json file - with open(path_to_store, "w") as stream: - json.dump(data, stream) From b374bf7eaebcb151a38447593ab54864e4cc65ba Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 13 Oct 2023 14:47:21 +0200 Subject: [PATCH 075/690] fix storing of data --- openpype/tools/context_dialog/_ayon_window.py | 34 +++++-------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/openpype/tools/context_dialog/_ayon_window.py b/openpype/tools/context_dialog/_ayon_window.py index 6514780236..04fd3495e1 100644 --- a/openpype/tools/context_dialog/_ayon_window.py +++ b/openpype/tools/context_dialog/_ayon_window.py @@ -356,27 +356,17 @@ class ContextDialogController: "task_name": None, } - def window_closed(self): - if not self._confirmed and not self._is_strict: - return - - self._store_output() - def confirm_selection(self): self._confirmed = True - self._emit_event( - "selection.confirmed", - {"confirmed": True} - ) - def _store_output(self): + def store_output(self): if not self._output_path: return dirpath = os.path.dirname(self._output_path) os.makedirs(dirpath, exist_ok=True) with open(self._output_path, "w") as stream: - json.dump(self.get_selected_context(), stream) + json.dump(self.get_selected_context(), stream, indent=4) def _get_event_system(self): """Inner event system for workfiles tool controller. @@ -627,7 +617,7 @@ class ContextDialog(QtWidgets.QDialog): return if self.is_strict(): - self._controller.confirm_selection() + self._confirm_selection() self._visible = False super(ContextDialog, self).closeEvent(event) @@ -666,10 +656,13 @@ class ContextDialog(QtWidgets.QDialog): def _on_ok_click(self): # Store values to output - self._controller.confirm_selection() + self._confirm_selection() # Close dialog self.accept() + def _confirm_selection(self): + self._controller.confirm_selection() + def _on_project_selection_change(self, event): self._on_selection_change( event["project_name"], @@ -769,15 +762,4 @@ def main( window = ContextDialog(controller=controller) window.show() app.exec_() - - # Get result from window - data = window.get_context() - - # Make sure json filepath directory exists - file_dir = os.path.dirname(path_to_store) - if not os.path.exists(file_dir): - os.makedirs(file_dir) - - # Store result into json file - with open(path_to_store, "w") as stream: - json.dump(data, stream) + controller.store_output() From f86874df3de22841587697cc8246eda14ddb4978 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 13 Oct 2023 14:47:46 +0200 Subject: [PATCH 076/690] add select item to projects combobox --- openpype/tools/context_dialog/_ayon_window.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/tools/context_dialog/_ayon_window.py b/openpype/tools/context_dialog/_ayon_window.py index 04fd3495e1..07495b7674 100644 --- a/openpype/tools/context_dialog/_ayon_window.py +++ b/openpype/tools/context_dialog/_ayon_window.py @@ -496,6 +496,7 @@ class ContextDialog(QtWidgets.QDialog): parent=left_side_widget, handle_expected_selection=True ) + project_combobox.set_select_item_visible(True) # Assets widget folders_widget = FoldersWidget( From 28bcbc8053133a1a257078052e9c2115167fea0d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 13 Oct 2023 14:48:07 +0200 Subject: [PATCH 077/690] implemented helper function to prepare initial context data --- openpype/tools/context_dialog/_ayon_window.py | 136 +++++++++++------- 1 file changed, 84 insertions(+), 52 deletions(-) diff --git a/openpype/tools/context_dialog/_ayon_window.py b/openpype/tools/context_dialog/_ayon_window.py index 07495b7674..73f9ed139c 100644 --- a/openpype/tools/context_dialog/_ayon_window.py +++ b/openpype/tools/context_dialog/_ayon_window.py @@ -277,52 +277,15 @@ class ContextDialogController: def is_initial_context_valid(self): return self._initial_folder_found and self._initial_project_found - def set_initial_context( - self, project_name=None, asset_name=None, folder_path=None - ): - if project_name is None: - project_found = True - asset_name = None - folder_path = None - - else: - project = ayon_api.get_project(project_name) - project_found = project is not None - - folder_id = None - folder_found = True - folder_label = None - if folder_path: - folder_label = folder_path - folder = ayon_api.get_folder_by_path(project_name, folder_path) - if folder: - folder_id = folder["id"] - else: - folder_found = False - elif asset_name: - folder_label = asset_name - for folder in ayon_api.get_folders( - project_name, folder_names=[asset_name] - ): - folder_id = folder["id"] - break - if not folder_id: - folder_found = False - - tasks_found = True - if folder_found and (folder_path or asset_name): - tasks = list(ayon_api.get_tasks( - project_name, folder_ids=[folder_id], fields=["id"] - )) - if not tasks: - tasks_found = False + def set_initial_context(self, project_name=None, asset_name=None): + result = self._prepare_initial_context(project_name, asset_name) self._initial_project_name = project_name - self._initial_folder_id = folder_id - self._initial_folder_label = folder_label - self._initial_folder_found = project_found - self._initial_folder_found = folder_found - self._initial_tasks_found = tasks_found + self._initial_folder_id = result["folder_id"] + self._initial_folder_label = result["folder_label"] + self._initial_project_found = result["project_found"] + self._initial_folder_found = result["folder_found"] + self._initial_tasks_found = result["tasks_found"] self._emit_event( "initial.context.changed", self.get_initial_context() @@ -345,15 +308,36 @@ class ContextDialogController: # Result of this tool def get_selected_context(self): + project_name = None + folder_id = None + task_id = None + task_name = None + folder_path = None + folder_name = None + if self._confirmed: + project_name = self.get_selected_project_name() + folder_id = self.get_selected_folder_id() + task_id = self.get_selected_task_id() + task_name = self.get_selected_task_name() + + folder_item = None + if folder_id: + folder_item = self._hierarchy_model.get_folder_item( + project_name, folder_id) + + if folder_item: + folder_path = folder_item.path + folder_name = folder_item.name return { - "project": None, - "project_name": None, - "asset": None, - "folder_id": None, - "folder_path": None, - "task": None, - "task_id": None, - "task_name": None, + "project": project_name, + "project_name": project_name, + "asset": folder_name, + "folder_id": folder_id, + "folder_path": folder_path, + "task": task_name, + "task_name": task_name, + "task_id": task_id, + "initial_context_valid": self.is_initial_context_valid(), } def confirm_selection(self): @@ -368,6 +352,54 @@ class ContextDialogController: with open(self._output_path, "w") as stream: json.dump(self.get_selected_context(), stream, indent=4) + def _prepare_initial_context(self, project_name, asset_name): + project_found = True + output = { + "project_found": project_found, + "folder_id": None, + "folder_label": None, + "folder_found": True, + "tasks_found": True, + } + if project_name is None: + asset_name = None + else: + project = ayon_api.get_project(project_name) + project_found = project is not None + output["project_found"] = project_found + if not project_found or not asset_name: + return output + + output["folder_label"] = asset_name + + folder_id = None + folder_found = False + # First try to find by path + folder = ayon_api.get_folder_by_path(project_name, asset_name) + # Try to find by name if folder was not found by path + # - prevent to query by name if 'asset_name' contains '/' + if not folder and "/" not in asset_name: + folder = next( + ayon_api.get_folders( + project_name, folder_names=[asset_name], fields=["id"]), + None + ) + + if folder: + folder_id = folder["id"] + folder_found = True + + output["folder_id"] = folder_id + output["folder_found"] = folder_found + if not folder_found: + return output + + tasks = list(ayon_api.get_tasks( + project_name, folder_ids=[folder_id], fields=["id"] + )) + output["tasks_found"] = bool(tasks) + return output + def _get_event_system(self): """Inner event system for workfiles tool controller. From a62718dc72b62a1823513795695a55b0601bb5a4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 13 Oct 2023 14:48:24 +0200 Subject: [PATCH 078/690] project name is in quotes --- openpype/tools/context_dialog/_ayon_window.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/tools/context_dialog/_ayon_window.py b/openpype/tools/context_dialog/_ayon_window.py index 73f9ed139c..f347978392 100644 --- a/openpype/tools/context_dialog/_ayon_window.py +++ b/openpype/tools/context_dialog/_ayon_window.py @@ -468,7 +468,8 @@ class InvalidContextOverlay(QtWidgets.QFrame): lines = [] if not project_found: lines.extend([ - "Requested project {} was not found...".format(project_name), + "Requested project '{}' was not found...".format( + project_name), ]) elif not folder_found: From 2f15dca3f50bbf687efd86bfb8339c284fd6aa7a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 13 Oct 2023 14:51:59 +0200 Subject: [PATCH 079/690] removed 'window.py' --- openpype/tools/context_dialog/__init__.py | 12 +++++++----- openpype/tools/context_dialog/window.py | 12 ------------ 2 files changed, 7 insertions(+), 17 deletions(-) delete mode 100644 openpype/tools/context_dialog/window.py diff --git a/openpype/tools/context_dialog/__init__.py b/openpype/tools/context_dialog/__init__.py index 9b10baf903..15b90463da 100644 --- a/openpype/tools/context_dialog/__init__.py +++ b/openpype/tools/context_dialog/__init__.py @@ -1,10 +1,12 @@ -from .window import ( - ContextDialog, - main -) +from openpype import AYON_SERVER_ENABLED + +if AYON_SERVER_ENABLED: + from ._ayon_window import ContextDialog, main +else: + from ._openpype_window import ContextDialog, main __all__ = ( "ContextDialog", - "main" + "main", ) diff --git a/openpype/tools/context_dialog/window.py b/openpype/tools/context_dialog/window.py deleted file mode 100644 index 15b90463da..0000000000 --- a/openpype/tools/context_dialog/window.py +++ /dev/null @@ -1,12 +0,0 @@ -from openpype import AYON_SERVER_ENABLED - -if AYON_SERVER_ENABLED: - from ._ayon_window import ContextDialog, main -else: - from ._openpype_window import ContextDialog, main - - -__all__ = ( - "ContextDialog", - "main", -) From 507adfa9368f24d9eaff47e5d386cad08671ab9e Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Mon, 5 Jun 2023 18:39:32 +0200 Subject: [PATCH 080/690] Refactor: Blender new publisher --- openpype/hosts/blender/api/ops.py | 6 ++++- openpype/hosts/blender/api/plugin.py | 25 ++++++++++++++++--- .../blender/plugins/create/create_action.py | 2 +- .../plugins/create/create_animation.py | 2 +- .../blender/plugins/create/create_camera.py | 2 +- .../blender/plugins/create/create_layout.py | 2 +- .../blender/plugins/create/create_model.py | 2 +- .../plugins/create/create_pointcache.py | 2 +- .../blender/plugins/create/create_review.py | 2 +- .../blender/plugins/create/create_rig.py | 2 +- .../blender/plugins/publish/extract_blend.py | 5 +++- 11 files changed, 39 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/blender/api/ops.py b/openpype/hosts/blender/api/ops.py index 208c11cfe8..22c590d4bd 100644 --- a/openpype/hosts/blender/api/ops.py +++ b/openpype/hosts/blender/api/ops.py @@ -275,6 +275,10 @@ class LaunchCreator(LaunchQtApp): def before_window_show(self): self._window.refresh() + def execute(self, context): + host_tools.show_publisher(tab="create") + return {"FINISHED"} + class LaunchLoader(LaunchQtApp): """Launch Avalon Loader.""" @@ -299,7 +303,7 @@ class LaunchPublisher(LaunchQtApp): bl_label = "Publish..." def execute(self, context): - host_tools.show_publish() + host_tools.show_publisher(tab="publish") return {"FINISHED"} diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index fb87d08cce..221c8d8936 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -6,7 +6,8 @@ from typing import Dict, List, Optional import bpy from openpype.pipeline import ( - LegacyCreator, + Creator, + CreatedInstance, LoaderPlugin, ) from .pipeline import AVALON_CONTAINERS @@ -134,10 +135,11 @@ def deselect_all(): bpy.context.view_layer.objects.active = active -class Creator(LegacyCreator): - """Base class for Creator plug-ins.""" +class BlenderCreator(Creator): + """Base class for Blender Creator plug-ins.""" defaults = ['Main'] + # Deprecated? def process(self): collection = bpy.data.collections.new(name=self.data["subset"]) bpy.context.scene.collection.children.link(collection) @@ -150,6 +152,23 @@ class Creator(LegacyCreator): return collection + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + """Override abstract method from Creator. + Create new instance and store it. + + Args: + subset_name(str): Subset name of created instance. + instance_data(dict): Base data for instance. + pre_create_data(dict): Data based on pre creation attributes. + Those may affect how creator works. + """ + instance = CreatedInstance( + self.family, subset_name, instance_data + ) + + class Loader(LoaderPlugin): """Base class for Loader plug-ins.""" diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 0203ba74c0..effbccd430 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -7,7 +7,7 @@ import openpype.hosts.blender.api.plugin from openpype.hosts.blender.api import lib -class CreateAction(openpype.hosts.blender.api.plugin.Creator): +class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): """Action output for character rigs""" name = "actionMain" diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index bc2840952b..1b9bbcacd9 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateAnimation(plugin.Creator): +class CreateAnimation(plugin.BlenderCreator): """Animation output for character rigs""" name = "animationMain" diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 7a770a3e77..c72f2b92ff 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateCamera(plugin.Creator): +class CreateCamera(plugin.BlenderCreator): """Polygonal static geometry""" name = "cameraMain" diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index 73ed683256..ba75df6735 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateLayout(plugin.Creator): +class CreateLayout(plugin.BlenderCreator): """Layout output for character rigs""" name = "layoutMain" diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 51fc6683f6..a7e71622ea 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateModel(plugin.Creator): +class CreateModel(plugin.BlenderCreator): """Polygonal static geometry""" name = "modelMain" diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 65cf18472d..0555d956de 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreatePointcache(plugin.Creator): +class CreatePointcache(plugin.BlenderCreator): """Polygonal static geometry""" name = "pointcacheMain" diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 914f249891..58c26e0324 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateReview(plugin.Creator): +class CreateReview(plugin.BlenderCreator): """Single baked camera""" name = "reviewDefault" diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 08cc46ee3e..7a0393f0ba 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES -class CreateRig(plugin.Creator): +class CreateRig(plugin.BlenderCreator): """Artist-friendly rig with controls to direct motion""" name = "rigMain" diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index d4f26b4f3c..fba9a861a0 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -5,7 +5,7 @@ import bpy from openpype.pipeline import publish -class ExtractBlend(publish.Extractor): +class ExtractBlend(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract a blend file.""" label = "Extract Blend" @@ -16,6 +16,9 @@ class ExtractBlend(publish.Extractor): def process(self, instance): # Define extract output file path + if not self.is_active(instance.data): + return + stagingdir = self.staging_dir(instance) filename = f"{instance.name}.blend" filepath = os.path.join(stagingdir, filename) From e06dfbb8e8dbf1a92f2164a0b929968384d1aaff Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 6 Jun 2023 16:09:09 +0200 Subject: [PATCH 081/690] draft implementation for blender creator refactor --- openpype/hosts/blender/api/plugin.py | 75 ++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 221c8d8936..39d0f5e662 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -152,6 +152,29 @@ class BlenderCreator(Creator): return collection + @staticmethod + def cache_subsets(shared_data): + """Cache instances for Creators shared data. + + Create `blender_cached_subsets` key when needed in shared data and + fill it with all collected instances from the scene under its + respective creator identifiers. + + If legacy instances are detected in the scene, create + `blender_cached_legacy_subsets` key and fill it with + all legacy subsets from this family as a value. # key or value? + + Args: + shared_data(Dict[str, Any]): Shared data. + + Return: + Dict[str, Any]: Shared data with cached subsets. + """ + if not shared_data.get('blender_cached_subsets'): + cache = {} + cache_legacy = {} + + def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): @@ -168,6 +191,58 @@ class BlenderCreator(Creator): self.family, subset_name, instance_data ) + collection = bpy.data.collections.new(name=self.data['subset']) + bpy.context.scene.collection.children.link(collection) + + if (self.options or {}).get("useSelection"): + for obj in get_selection(): + collection.objects.link(obj) + + + def collect_instances(self): + """Override abstract method from BaseCreator. + Collect existing instances related to this creator plugin.""" + for ( + instance_data in self.cache_subsets( + self.collection_shared_data + ).get('blender_cached_subsets') + ): + # Process only instances that were created by this creator + creator_id = instance_data.get('creator_identifier') + + if creator_id == self.identifier: + # Create instance object from existing data + instance = CreatedInstance.from_existing( + instance_data, self + ) + + # Add instance to create context + self.add_instance_to_context(instance) + + + def update_instances(self, update_list): + """Override abstract method from BaseCreator. + Store changes of existing instances so they can be recollected. + + Args: + update_list(List[UpdateData]): Changed instances + and their changes, as a list of tuples.""" + for created_instance, _changes in update_list: + data = created_instance.data_to_store() + + # TODO + + + def remove_instances(self, instances: List[CreatedInstance]): + """Override abstract method from BaseCreator. + Method called when instances are removed. + + Args: + instance(List[CreatedInstance]): Instance objects to remove. + """ + for instance in instances: + self._remove_instance_from_context(instance) + class Loader(LoaderPlugin): """Base class for Loader plug-ins.""" From 3c198694a9be7dace95e5e027b604f23e3f2bdfe Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 6 Jun 2023 18:03:02 +0200 Subject: [PATCH 082/690] blender creator cache subsets --- openpype/hosts/blender/api/plugin.py | 59 +++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 39d0f5e662..9a982c45e7 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -10,7 +10,11 @@ from openpype.pipeline import ( CreatedInstance, LoaderPlugin, ) -from .pipeline import AVALON_CONTAINERS +from .pipeline import ( + AVALON_CONTAINERS, + AVALON_INSTANCES, + AVALON_PROPERTY, +) from .ops import ( MainThreadItem, execute_in_main_thread @@ -174,6 +178,44 @@ class BlenderCreator(Creator): cache = {} cache_legacy = {} + avalon_instances = bpy.data.collections.get(AVALON_INSTANCES) + if avalon_instances: + for obj in bpy.data.collections.get(AVALON_INSTANCES).objects: + avalon_prop = obj.get(AVALON_PROPERTY, {}) + if avalon_prop.get('id') == 'pyblish.avalon.instance': + creator_id = avalon_prop.get('creator_identifier') + + if creator_id: + # Creator instance + cache.setdefault(creator_id, []).append( + avalon_prop + ) + else: + family = avalon_prop.get('family') + if family: + # Legacy creator instance + cache_legacy.setdefault(family, []).append( + avalon_prop + ) + + for col in bpy.data.collections: + avalon_prop = col.get(AVALON_PROPERTY, {}) + if avalon_prop.get('id') == 'pyblish.avalon.instance': + creaor_id = avalon_prop.get('creator_identifier') + + if creator_id: + # Creator instance + cache.setdefault(creator_id, []).append(avalon_prop) + else: + family = avalon_prop.get('family') + if family: + cache_legacy.setdefault(family, []) + if family: + # Legacy creator instance + cache_legacy.setdefault(family, []).append( + avalon_prop + ) + def create( self, subset_name: str, instance_data: dict, pre_create_data: dict @@ -202,11 +244,16 @@ class BlenderCreator(Creator): def collect_instances(self): """Override abstract method from BaseCreator. Collect existing instances related to this creator plugin.""" - for ( - instance_data in self.cache_subsets( - self.collection_shared_data - ).get('blender_cached_subsets') - ): + + # Cache subsets in shared data + self.cache_subsets(self.collection_shared_data) + + # Get cached subsets + cached_subsets = self.collection_shared_data.get('blender_cached_subsets') + if not cached_subsets: + return + + for instance_data in cached_subsets: # Process only instances that were created by this creator creator_id = instance_data.get('creator_identifier') From d4c030e77d38b7db3fc50c98d0d43ca6d6beae8e Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Fri, 16 Jun 2023 11:16:42 +0200 Subject: [PATCH 083/690] Add identifiers to blender creators. Fix wrong method name --- openpype/hosts/blender/api/plugin.py | 2 +- openpype/hosts/blender/plugins/create/create_action.py | 1 + openpype/hosts/blender/plugins/create/create_animation.py | 1 + openpype/hosts/blender/plugins/create/create_camera.py | 1 + openpype/hosts/blender/plugins/create/create_layout.py | 1 + openpype/hosts/blender/plugins/create/create_model.py | 1 + openpype/hosts/blender/plugins/create/create_pointcache.py | 1 + openpype/hosts/blender/plugins/create/create_review.py | 1 + openpype/hosts/blender/plugins/create/create_rig.py | 1 + 9 files changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 9a982c45e7..c13af363c5 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -264,7 +264,7 @@ class BlenderCreator(Creator): ) # Add instance to create context - self.add_instance_to_context(instance) + self._add_instance_to_context(instance) def update_instances(self, update_list): diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index effbccd430..5f4ded3688 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api import lib class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): """Action output for character rigs""" + identifier = "io.openpype.creators.blender.action" name = "actionMain" label = "Action" family = "action" diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 1b9bbcacd9..277c588610 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateAnimation(plugin.BlenderCreator): """Animation output for character rigs""" + identifier = "io.openpype.creators.blender.animation" name = "animationMain" label = "Animation" family = "animation" diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index c72f2b92ff..9086c44c5f 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateCamera(plugin.BlenderCreator): """Polygonal static geometry""" + identifier = "io.openpype.creators.blender.camera" name = "cameraMain" label = "Camera" family = "camera" diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index ba75df6735..ae567e6495 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateLayout(plugin.BlenderCreator): """Layout output for character rigs""" + identifier = "io.openpype.creators.blender.layout" name = "layoutMain" label = "Layout" family = "layout" diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index a7e71622ea..46196ab383 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateModel(plugin.BlenderCreator): """Polygonal static geometry""" + identifier = "io.openpype.creators.blender.model" name = "modelMain" label = "Model" family = "model" diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 0555d956de..4c434202c7 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreatePointcache(plugin.BlenderCreator): """Polygonal static geometry""" + identifier = "io.openpype.creators.blender.pointcache" name = "pointcacheMain" label = "Point Cache" family = "pointcache" diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 58c26e0324..87774aed7a 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateReview(plugin.BlenderCreator): """Single baked camera""" + identifier = "io.openpype.creators.blender.review" name = "reviewDefault" label = "Review" family = "review" diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 7a0393f0ba..84924a659b 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -10,6 +10,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES class CreateRig(plugin.BlenderCreator): """Artist-friendly rig with controls to direct motion""" + identifier = "io.openpype.creators.blender.rig" name = "rigMain" label = "Rig" family = "rig" From efa294defcc625acdd36e7948bde3f75b15beb88 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Fri, 16 Jun 2023 17:54:28 +0200 Subject: [PATCH 084/690] fixed wrong variable name --- openpype/hosts/blender/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index c13af363c5..02436e3583 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -201,7 +201,7 @@ class BlenderCreator(Creator): for col in bpy.data.collections: avalon_prop = col.get(AVALON_PROPERTY, {}) if avalon_prop.get('id') == 'pyblish.avalon.instance': - creaor_id = avalon_prop.get('creator_identifier') + creator_id = avalon_prop.get('creator_identifier') if creator_id: # Creator instance From b681173dc5b2ee34862ffa41dbc3fc452c682a56 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Mon, 3 Jul 2023 17:44:36 +0200 Subject: [PATCH 085/690] draft blenderhost class implementation --- openpype/hosts/blender/api/__init__.py | 2 + openpype/hosts/blender/api/pipeline.py | 41 ++++++++++++++++++- .../blender/blender_addon/startup/init.py | 4 +- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/api/__init__.py b/openpype/hosts/blender/api/__init__.py index e15f1193a5..ce2b444997 100644 --- a/openpype/hosts/blender/api/__init__.py +++ b/openpype/hosts/blender/api/__init__.py @@ -10,6 +10,7 @@ from .pipeline import ( ls, publish, containerise, + BlenderHost, ) from .plugin import ( @@ -47,6 +48,7 @@ __all__ = [ "ls", "publish", "containerise", + "BlenderHost", "Creator", "Loader", diff --git a/openpype/hosts/blender/api/pipeline.py b/openpype/hosts/blender/api/pipeline.py index 84af0904f0..935981da86 100644 --- a/openpype/hosts/blender/api/pipeline.py +++ b/openpype/hosts/blender/api/pipeline.py @@ -6,10 +6,14 @@ from typing import Callable, Dict, Iterator, List, Optional import bpy from . import lib -from . import ops +from . import ops, properties import pyblish.api +from openpype.host import( + HostBase, + IPublishHost, +) from openpype.client import get_asset_by_name from openpype.pipeline import ( schema, @@ -47,6 +51,39 @@ IS_HEADLESS = bpy.app.background log = Logger.get_logger(__name__) +class BlenderHost(HostBase, IPublishHost): + name = "blender" + + def install(self): + """Override install method from HostBase. + Install Blender host functionality.""" + install() + + def ls(self) -> Iterator: + """List containers from active Blender scene.""" + return ls() + + def get_context_data(self): + """Override abstract method from IPublishHost. + Get global data related to creation-publishing from workfile. + + Returns: + dict: Context data stored using 'update_context_data'. + """ + return bpy.context.scene.openpype_context + + def update_context_data(self, data, changes): + """Override abstract method from IPublishHost. + Store global context data to workfile. + + Args: + data (dict): New data as are. + changes (dict): Only data that has been changed. Each value has + tuple with '(, )' value. + """ + bpy.context.scene.openpype_context.update(data) + + def pype_excepthook_handler(*args): traceback.print_exception(*args) @@ -72,6 +109,7 @@ def install(): if not IS_HEADLESS: ops.register() + properties.register() def uninstall(): @@ -86,6 +124,7 @@ def uninstall(): if not IS_HEADLESS: ops.unregister() + properties.unregister() def show_message(title, message): diff --git a/openpype/hosts/blender/blender_addon/startup/init.py b/openpype/hosts/blender/blender_addon/startup/init.py index 8dbff8a91d..603691675d 100644 --- a/openpype/hosts/blender/blender_addon/startup/init.py +++ b/openpype/hosts/blender/blender_addon/startup/init.py @@ -1,9 +1,9 @@ from openpype.pipeline import install_host -from openpype.hosts.blender import api +from openpype.hosts.blender.api import BlenderHost def register(): - install_host(api) + install_host(BlenderHost()) def unregister(): From 3b7ed1d71f86f6bd04029cc6ec0e369aff94c365 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 4 Jul 2023 10:55:04 +0200 Subject: [PATCH 086/690] Fix update_container_data error --- openpype/hosts/blender/api/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/pipeline.py b/openpype/hosts/blender/api/pipeline.py index 935981da86..968c70089b 100644 --- a/openpype/hosts/blender/api/pipeline.py +++ b/openpype/hosts/blender/api/pipeline.py @@ -81,7 +81,7 @@ class BlenderHost(HostBase, IPublishHost): changes (dict): Only data that has been changed. Each value has tuple with '(, )' value. """ - bpy.context.scene.openpype_context.update(data) + bpy.context.scene.openpype_context |= data def pype_excepthook_handler(*args): From 7bdbf0252211167c065aa8f3e622d48e725c0bf8 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 4 Jul 2023 16:07:44 +0200 Subject: [PATCH 087/690] Added properties to blender host --- openpype/hosts/blender/api/properties.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 openpype/hosts/blender/api/properties.py diff --git a/openpype/hosts/blender/api/properties.py b/openpype/hosts/blender/api/properties.py new file mode 100644 index 0000000000..ffc1dea733 --- /dev/null +++ b/openpype/hosts/blender/api/properties.py @@ -0,0 +1,23 @@ +import bpy +from bpy.utils import register_classes_factory + +class OpenpypeContext(bpy.types.PropertyGroup): + pass + +classes = [OpenpypeContext] + +factory_register, factory_unregister = register_classes_factory(classes) + +def register(): + """Register the properties.""" + factory_register() + + bpy.types.Scene.openpype_context = bpy.props.CollectionProperty( + name="OpenPype Context", type=OpenpypeContext, options={"HIDDEN"} + ) + +def unregister(): + """Unregister the properties.""" + factory_unregister() + + del bpy.types.Scene.openpype_context From d9960e84d44dab94ac5fec6bf45315ce79ab5d37 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 4 Jul 2023 17:54:40 +0200 Subject: [PATCH 088/690] Fixed errors during create --- openpype/hosts/blender/api/pipeline.py | 2 +- openpype/hosts/blender/api/plugin.py | 6 +++--- openpype/hosts/blender/api/properties.py | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/blender/api/pipeline.py b/openpype/hosts/blender/api/pipeline.py index 968c70089b..935981da86 100644 --- a/openpype/hosts/blender/api/pipeline.py +++ b/openpype/hosts/blender/api/pipeline.py @@ -81,7 +81,7 @@ class BlenderHost(HostBase, IPublishHost): changes (dict): Only data that has been changed. Each value has tuple with '(, )' value. """ - bpy.context.scene.openpype_context |= data + bpy.context.scene.openpype_context.update(data) def pype_excepthook_handler(*args): diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 02436e3583..91068244c5 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -230,13 +230,13 @@ class BlenderCreator(Creator): Those may affect how creator works. """ instance = CreatedInstance( - self.family, subset_name, instance_data + self.family, subset_name, instance_data, self ) - collection = bpy.data.collections.new(name=self.data['subset']) + collection = bpy.data.collections.new(name=subset_name) bpy.context.scene.collection.children.link(collection) - if (self.options or {}).get("useSelection"): + if pre_create_data.get("useSelection"): for obj in get_selection(): collection.objects.link(obj) diff --git a/openpype/hosts/blender/api/properties.py b/openpype/hosts/blender/api/properties.py index ffc1dea733..c6b5ffe011 100644 --- a/openpype/hosts/blender/api/properties.py +++ b/openpype/hosts/blender/api/properties.py @@ -4,7 +4,7 @@ from bpy.utils import register_classes_factory class OpenpypeContext(bpy.types.PropertyGroup): pass -classes = [OpenpypeContext] +classes = [] # [OpenpypeContext] factory_register, factory_unregister = register_classes_factory(classes) @@ -12,9 +12,10 @@ def register(): """Register the properties.""" factory_register() - bpy.types.Scene.openpype_context = bpy.props.CollectionProperty( - name="OpenPype Context", type=OpenpypeContext, options={"HIDDEN"} - ) + bpy.types.Scene.openpype_context = {} + # bpy.types.Scene.openpype_context = bpy.props.CollectionProperty( + # name="OpenPype Context", type=OpenpypeContext, options={"HIDDEN"} + # ) def unregister(): """Unregister the properties.""" From cf66d12ef20feb2e1dcf326d4888434a3c506bdb Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 5 Jul 2023 17:36:42 +0200 Subject: [PATCH 089/690] Fixes to base creator, creators compatibility --- openpype/hosts/blender/api/plugin.py | 3 + .../blender/plugins/create/create_action.py | 27 +++++++++ .../plugins/create/create_animation.py | 47 +++++++++++++++- .../blender/plugins/create/create_camera.py | 56 ++++++++++++++++++- .../blender/plugins/create/create_layout.py | 45 ++++++++++++++- .../blender/plugins/create/create_model.py | 45 ++++++++++++++- .../plugins/create/create_pointcache.py | 22 ++++++++ .../blender/plugins/create/create_review.py | 43 +++++++++++++- .../blender/plugins/create/create_rig.py | 45 ++++++++++++++- 9 files changed, 315 insertions(+), 18 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 91068244c5..153897cb9a 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -216,6 +216,8 @@ class BlenderCreator(Creator): avalon_prop ) + return shared_data + def create( self, subset_name: str, instance_data: dict, pre_create_data: dict @@ -232,6 +234,7 @@ class BlenderCreator(Creator): instance = CreatedInstance( self.family, subset_name, instance_data, self ) + self._add_instance_to_context(instance) collection = bpy.data.collections.new(name=subset_name) bpy.context.scene.collection.children.link(collection) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 5f4ded3688..32e924d758 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -16,6 +16,33 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): family = "action" icon = "male" + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + + name = openpype.hosts.blender.api.plugin.asset_name( + instance_data["asset"], subset_name + ) + collection = bpy.data.collections.new(name=name) + bpy.context.scene.collection.children.link(collection) + instance_data['task'] = get_current_task_name() + lib.imprint(collection, instance_data) + + if pre_create_data.get("useSelection"): + for obj in lib.get_selection(): + if (obj.animation_data is not None + and obj.animation_data.action is not None): + + empty_obj = bpy.data.objects.new(name=name, + object_data=None) + empty_obj.animation_data_create() + empty_obj.animation_data.action = obj.animation_data.action + empty_obj.animation_data.action.name = name + collection.objects.link(empty_obj) + + return collection + + # Deprecated def process(self): asset = self.data["asset"] diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 277c588610..12478fd7e5 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -16,12 +16,53 @@ class CreateAnimation(plugin.BlenderCreator): family = "animation" icon = "male" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + # name = self.name + # if not name: + name = plugin.asset_name(instance_data["asset"], subset_name) + # asset_group = bpy.data.objects.new(name=name, object_data=None) + # asset_group.empty_display_type = 'SINGLE_ARROW' + asset_group = bpy.data.collections.new(name=name) + instances.children.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + if pre_create_data.get("useSelection"): + selected = lib.get_selection() + for obj in selected: + asset_group.objects.link(obj) + elif pre_create_data.get("asset_group"): + obj = (self.options or {}).get("asset_group") + asset_group.objects.link(obj) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 9086c44c5f..6b9d1b7f73 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -16,12 +16,62 @@ class CreateCamera(plugin.BlenderCreator): family = "camera" icon = "video-camera" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + name = plugin.asset_name(instance_data["asset"], subset_name) + + asset_group = bpy.data.objects.new(name=name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' + instances.objects.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + if pre_create_data.get("useSelection"): + bpy.context.view_layer.objects.active = asset_group + selected = lib.get_selection() + for obj in selected: + obj.select_set(True) + selected.append(asset_group) + bpy.ops.object.parent_set(keep_transform=True) + else: + plugin.deselect_all() + camera = bpy.data.cameras.new(subset_name) + camera_obj = bpy.data.objects.new(subset_name, camera) + + instances.objects.link(camera_obj) + + camera_obj.select_set(True) + asset_group.select_set(True) + bpy.context.view_layer.objects.active = asset_group + bpy.ops.object.parent_set(keep_transform=True) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index ae567e6495..24aa277349 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -16,12 +16,51 @@ class CreateLayout(plugin.BlenderCreator): family = "layout" icon = "cubes" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + name = plugin.asset_name(instance_data["asset"], subset_name) + asset_group = bpy.data.objects.new(name=name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' + instances.objects.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + # Add selected objects to instance + if pre_create_data.get("useSelection"): + bpy.context.view_layer.objects.active = asset_group + selected = lib.get_selection() + for obj in selected: + obj.select_set(True) + selected.append(asset_group) + bpy.ops.object.parent_set(keep_transform=True) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 46196ab383..2e713dd661 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -16,12 +16,51 @@ class CreateModel(plugin.BlenderCreator): family = "model" icon = "cube" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + name = plugin.asset_name(instance_data["asset"], subset_name) + asset_group = bpy.data.objects.new(name=name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' + instances.objects.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + # Add selected objects to instance + if pre_create_data.get("useSelection"): + bpy.context.view_layer.objects.active = asset_group + selected = lib.get_selection() + for obj in selected: + obj.select_set(True) + selected.append(asset_group) + bpy.ops.object.parent_set(keep_transform=True) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 4c434202c7..5932315bc8 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -16,6 +16,28 @@ class CreatePointcache(plugin.BlenderCreator): family = "pointcache" icon = "gears" + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + + name = openpype.hosts.blender.api.plugin.asset_name( + instance_data["asset"], subset_name + ) + collection = bpy.data.collections.new(name=name) + bpy.context.scene.collection.children.link(collection) + instance_data['task'] = get_current_task_name() + lib.imprint(collection, instance_data) + + if pre_create_data.get("useSelection"): + objects = lib.get_selection() + for obj in objects: + collection.objects.link(obj) + if obj.type == 'EMPTY': + objects.extend(obj.children) + + return collection + + # Deprecated def process(self): """ Run the creator on Blender main thread""" mti = ops.MainThreadItem(self._process) diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 87774aed7a..4b5cfb4c35 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -16,12 +16,49 @@ class CreateReview(plugin.BlenderCreator): family = "review" icon = "video-camera" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + name = plugin.asset_name(instance_data["asset"], subset_name) + asset_group = bpy.data.collections.new(name=name) + instances.children.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + if pre_create_data.get("useSelection"): + selected = lib.get_selection() + for obj in selected: + asset_group.objects.link(obj) + elif pre_create_data.get("asset_group"): + obj = (self.options or {}).get("asset_group") + asset_group.objects.link(obj) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 84924a659b..5ebf952d4a 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -16,12 +16,51 @@ class CreateRig(plugin.BlenderCreator): family = "rig" icon = "wheelchair" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance object + name = plugin.asset_name(instance_data["asset"], subset_name) + asset_group = bpy.data.objects.new(name=name, object_data=None) + asset_group.empty_display_type = 'SINGLE_ARROW' + instances.objects.link(asset_group) + instance_data['task'] = get_current_task_name() + lib.imprint(asset_group, instance_data) + + # Add selected objects to instance + if pre_create_data.get("useSelection"): + bpy.context.view_layer.objects.active = asset_group + selected = lib.get_selection() + for obj in selected: + obj.select_set(True) + selected.append(asset_group) + bpy.ops.object.parent_set(keep_transform=True) + + return asset_group + + # Deprecated + def process(self): + """ Run the creator on Blender main thread""" + mti = ops.MainThreadItem(self._process_legacy) + ops.execute_in_main_thread(mti) + + # Deprecated + def _process_legacy(self): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: From e0e7c965856795776e86cfab83a582b2fd4c134d Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Mon, 10 Jul 2023 14:59:31 +0200 Subject: [PATCH 090/690] blender creator instances added to context --- openpype/hosts/blender/plugins/create/create_action.py | 5 ++++- openpype/hosts/blender/plugins/create/create_animation.py | 6 +++++- openpype/hosts/blender/plugins/create/create_camera.py | 6 +++++- openpype/hosts/blender/plugins/create/create_layout.py | 6 +++++- openpype/hosts/blender/plugins/create/create_model.py | 6 +++++- openpype/hosts/blender/plugins/create/create_pointcache.py | 7 +++++-- openpype/hosts/blender/plugins/create/create_review.py | 6 +++++- openpype/hosts/blender/plugins/create/create_rig.py | 6 +++++- 8 files changed, 39 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 32e924d758..6c2c6d98ce 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance import openpype.hosts.blender.api.plugin from openpype.hosts.blender.api import lib @@ -19,6 +19,9 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) name = openpype.hosts.blender.api.plugin.asset_name( instance_data["asset"], subset_name diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 12478fd7e5..ec77569889 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateAnimation(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 6b9d1b7f73..55ea07d90f 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateCamera(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index 24aa277349..60812d7fc9 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateLayout(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 2e713dd661..59bbae5bc4 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateModel(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 5932315bc8..bb843c5a22 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -19,8 +19,11 @@ class CreatePointcache(plugin.BlenderCreator): def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) - name = openpype.hosts.blender.api.plugin.asset_name( + name = plugin.asset_name( instance_data["asset"], subset_name ) collection = bpy.data.collections.new(name=name) diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 4b5cfb4c35..1191fb95f1 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateReview(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 5ebf952d4a..752f3f7b18 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -2,7 +2,7 @@ import bpy -from openpype.pipeline import get_current_task_name +from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES @@ -20,6 +20,10 @@ class CreateRig(plugin.BlenderCreator): self, subset_name: str, instance_data: dict, pre_create_data: dict ): """ Run the creator on Blender main thread""" + self._add_instance_to_context( + CreatedInstance(self.family, subset_name, instance_data, self) + ) + mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) From 6eae2c264d57b4ed5395de03950e09bc54ae7acb Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 12 Jul 2023 15:54:41 +0200 Subject: [PATCH 091/690] Add dict to imprint, type hints in blenderhost, imprint in create --- openpype/hosts/blender/api/lib.py | 2 +- openpype/hosts/blender/api/pipeline.py | 4 ++-- openpype/hosts/blender/api/plugin.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index 9bb560c364..76bef09ceb 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -188,7 +188,7 @@ def imprint(node: bpy.types.bpy_struct_meta_idprop, data: Dict): # Support values evaluated at imprint value = value() - if not isinstance(value, (int, float, bool, str, list)): + if not isinstance(value, (int, float, bool, str, list, dict)): raise TypeError(f"Unsupported type: {type(value)}") imprint_data[key] = value diff --git a/openpype/hosts/blender/api/pipeline.py b/openpype/hosts/blender/api/pipeline.py index 935981da86..4c06b1959e 100644 --- a/openpype/hosts/blender/api/pipeline.py +++ b/openpype/hosts/blender/api/pipeline.py @@ -63,7 +63,7 @@ class BlenderHost(HostBase, IPublishHost): """List containers from active Blender scene.""" return ls() - def get_context_data(self): + def get_context_data(self) -> dict: """Override abstract method from IPublishHost. Get global data related to creation-publishing from workfile. @@ -72,7 +72,7 @@ class BlenderHost(HostBase, IPublishHost): """ return bpy.context.scene.openpype_context - def update_context_data(self, data, changes): + def update_context_data(self, data: dict, changes: dict): """Override abstract method from IPublishHost. Store global context data to workfile. diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 153897cb9a..fe1e4ce81c 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -238,6 +238,7 @@ class BlenderCreator(Creator): collection = bpy.data.collections.new(name=subset_name) bpy.context.scene.collection.children.link(collection) + imprint(collection, instance_data) if pre_create_data.get("useSelection"): for obj in get_selection(): From 7617d1e0ad63042d39a3c626f6e614100d2bd879 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 19 Jul 2023 20:28:45 +0200 Subject: [PATCH 092/690] Set shared data, edit loop in cached_subsets --- openpype/hosts/blender/api/plugin.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index fe1e4ce81c..97a3dfa6a6 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -216,6 +216,9 @@ class BlenderCreator(Creator): avalon_prop ) + shared_data["blender_cached_subsets"] = cache + shared_data["blender_cached_legacy_subsets"] = cache_legacy + return shared_data @@ -257,14 +260,17 @@ class BlenderCreator(Creator): if not cached_subsets: return - for instance_data in cached_subsets: + for instance_data in cached_subsets.get(self.identifier, []): # Process only instances that were created by this creator + data = dict() + for key, value in instance_data.items(): + data[key] = value creator_id = instance_data.get('creator_identifier') if creator_id == self.identifier: # Create instance object from existing data instance = CreatedInstance.from_existing( - instance_data, self + data, self ) # Add instance to create context From aeebd78cc71fb3edbe51157c60da849f62e727f3 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 20 Jul 2023 15:31:23 +0200 Subject: [PATCH 093/690] Collect instances functional --- openpype/hosts/blender/api/plugin.py | 4 ++-- openpype/hosts/blender/plugins/create/create_action.py | 3 +++ openpype/hosts/blender/plugins/create/create_animation.py | 3 +++ openpype/hosts/blender/plugins/create/create_camera.py | 3 +++ openpype/hosts/blender/plugins/create/create_layout.py | 3 +++ openpype/hosts/blender/plugins/create/create_model.py | 3 +++ openpype/hosts/blender/plugins/create/create_pointcache.py | 3 +++ openpype/hosts/blender/plugins/create/create_review.py | 3 +++ openpype/hosts/blender/plugins/create/create_rig.py | 3 +++ 9 files changed, 26 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 97a3dfa6a6..5dd352ff6c 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -262,10 +262,10 @@ class BlenderCreator(Creator): for instance_data in cached_subsets.get(self.identifier, []): # Process only instances that were created by this creator - data = dict() + data = {} for key, value in instance_data.items(): data[key] = value - creator_id = instance_data.get('creator_identifier') + creator_id = data.get('creator_identifier') if creator_id == self.identifier: # Create instance object from existing data diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 6c2c6d98ce..2c0d248994 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -29,6 +29,9 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index ec77569889..538c0455ac 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -47,6 +47,9 @@ class CreateAnimation(plugin.BlenderCreator): asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 55ea07d90f..ae85273353 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -45,6 +45,9 @@ class CreateCamera(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index 60812d7fc9..cce422b229 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -44,6 +44,9 @@ class CreateLayout(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) # Add selected objects to instance diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 59bbae5bc4..57f9e79aa1 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -44,6 +44,9 @@ class CreateModel(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) # Add selected objects to instance diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index bb843c5a22..f95f79ae78 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -29,6 +29,9 @@ class CreatePointcache(plugin.BlenderCreator): collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 1191fb95f1..8472600c2f 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -43,6 +43,9 @@ class CreateReview(plugin.BlenderCreator): asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 752f3f7b18..a60f2a72ee 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -44,6 +44,9 @@ class CreateRig(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) instance_data['task'] = get_current_task_name() + instance_data['id'] = 'pyblish.avalon.instance' + instance_data['creator_identifier'] = self.identifier + instance_data['label'] = self.label lib.imprint(asset_group, instance_data) # Add selected objects to instance From 4d03c1c0e60b8e32248a4bb96a326c7c3a3762fb Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 20 Jul 2023 18:26:59 +0200 Subject: [PATCH 094/690] Set subset in inst data, use update to set it --- .../hosts/blender/plugins/create/create_action.py | 13 +++++++++---- .../blender/plugins/create/create_animation.py | 13 +++++++++---- .../hosts/blender/plugins/create/create_camera.py | 13 +++++++++---- .../hosts/blender/plugins/create/create_layout.py | 13 +++++++++---- .../hosts/blender/plugins/create/create_model.py | 13 +++++++++---- .../blender/plugins/create/create_pointcache.py | 13 +++++++++---- .../hosts/blender/plugins/create/create_review.py | 13 +++++++++---- openpype/hosts/blender/plugins/create/create_rig.py | 13 +++++++++---- 8 files changed, 72 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 2c0d248994..6951e86c46 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -28,10 +28,15 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): ) collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 538c0455ac..9e7dfbaf84 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -46,10 +46,15 @@ class CreateAnimation(plugin.BlenderCreator): # asset_group.empty_display_type = 'SINGLE_ARROW' asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index ae85273353..c5987779c0 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -44,10 +44,15 @@ class CreateCamera(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index cce422b229..cb61799f4a 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -43,10 +43,15 @@ class CreateLayout(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) # Add selected objects to instance diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 57f9e79aa1..ccf3668d98 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -43,10 +43,15 @@ class CreateModel(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) # Add selected objects to instance diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index f95f79ae78..e27cb22389 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -28,10 +28,15 @@ class CreatePointcache(plugin.BlenderCreator): ) collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 8472600c2f..afeaea951b 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -42,10 +42,15 @@ class CreateReview(plugin.BlenderCreator): name = plugin.asset_name(instance_data["asset"], subset_name) asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index a60f2a72ee..2db766f7ed 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -43,10 +43,15 @@ class CreateRig(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_data['task'] = get_current_task_name() - instance_data['id'] = 'pyblish.avalon.instance' - instance_data['creator_identifier'] = self.identifier - instance_data['label'] = self.label + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": self.label, + "task": get_current_task_name(), + "subset": subset_name, + } + ) lib.imprint(asset_group, instance_data) # Add selected objects to instance From 8236e46ca93b562feb66df51a81ec74c6785586f Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Mon, 31 Jul 2023 17:16:40 +0200 Subject: [PATCH 095/690] implement IWorkfileHost for Blender host --- openpype/hosts/blender/api/pipeline.py | 70 +++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/api/pipeline.py b/openpype/hosts/blender/api/pipeline.py index 4c06b1959e..c3f8f06694 100644 --- a/openpype/hosts/blender/api/pipeline.py +++ b/openpype/hosts/blender/api/pipeline.py @@ -12,6 +12,7 @@ import pyblish.api from openpype.host import( HostBase, + IWorkfileHost, IPublishHost, ) from openpype.client import get_asset_by_name @@ -33,6 +34,14 @@ from openpype.lib import ( ) import openpype.hosts.blender from openpype.settings import get_project_settings +from .workio import ( + open_file, + save_file, + current_file, + has_unsaved_changes, + file_extensions, + work_root, +) HOST_DIR = os.path.dirname(os.path.abspath(openpype.hosts.blender.__file__)) @@ -51,7 +60,7 @@ IS_HEADLESS = bpy.app.background log = Logger.get_logger(__name__) -class BlenderHost(HostBase, IPublishHost): +class BlenderHost(HostBase, IWorkfileHost, IPublishHost): name = "blender" def install(self): @@ -63,6 +72,65 @@ class BlenderHost(HostBase, IPublishHost): """List containers from active Blender scene.""" return ls() + def get_workfile_extensions(self) -> List[str]: + """Override get_workfile_extensions method from IWorkfileHost. + Get workfile possible extensions. + + Returns: + List[str]: Workfile extensions. + """ + return file_extensions() + + def save_workfile(self, dst_path: str = None): + """Override save_workfile method from IWorkfileHost. + Save currently opened workfile. + + Args: + dst_path (str): Where the current scene should be saved. Or use + current path if `None` is passed. + """ + save_file(dst_path if dst_path else bpy.data.filepath) + + def open_workfile(self, filepath: str): + """Override open_workfile method from IWorkfileHost. + Open workfile at specified filepath in the host. + + Args: + filepath (str): Path to workfile. + """ + open_file(filepath) + + def get_current_workfile(self) -> str: + """Override get_current_workfile method from IWorkfileHost. + Retrieve currently opened workfile path. + + Returns: + str: Path to currently opened workfile. + """ + return current_file() + + def workfile_has_unsaved_changes(self) -> bool: + """Override wokfile_has_unsaved_changes method from IWorkfileHost. + Returns True if opened workfile has no unsaved changes. + + Returns: + bool: True if scene is saved and False if it has unsaved + modifications. + """ + return has_unsaved_changes() + + def work_root(self, session) -> str: + """Override work_root method from IWorkfileHost. + Modify workdir per host. + + Args: + session (dict): Session context data. + + Returns: + str: Path to new workdir. + """ + return work_root(session) + def get_context_data(self) -> dict: """Override abstract method from IPublishHost. Get global data related to creation-publishing from workfile. From e9d022bab37f67391267788c3de940c1db0f955d Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 2 Aug 2023 16:13:34 +0200 Subject: [PATCH 096/690] Handling optional plugins --- openpype/hosts/blender/plugins/publish/extract_abc.py | 2 +- .../blender/plugins/publish/extract_abc_animation.py | 5 ++++- .../blender/plugins/publish/extract_blend_animation.py | 5 ++++- .../blender/plugins/publish/extract_camera_abc.py | 2 +- .../blender/plugins/publish/extract_camera_fbx.py | 2 +- openpype/hosts/blender/plugins/publish/extract_fbx.py | 2 +- .../blender/plugins/publish/extract_fbx_animation.py | 5 ++++- .../hosts/blender/plugins/publish/extract_layout.py | 2 +- .../hosts/blender/plugins/publish/extract_playblast.py | 2 +- .../plugins/publish/increment_workfile_version.py | 6 +++++- .../blender/plugins/publish/integrate_animation.py | 6 +++++- .../blender/plugins/publish/validate_mesh_has_uv.py | 10 ++++++++-- .../blender/plugins/publish/validate_object_mode.py | 6 +++++- 13 files changed, 41 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index 7b6c4d7ae7..5af8104344 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class ExtractABC(publish.Extractor): +class ExtractABC(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract as ABC.""" label = "Extract ABC" diff --git a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py index 44b2ba3761..0b6b93b7a5 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py @@ -6,7 +6,10 @@ from openpype.pipeline import publish from openpype.hosts.blender.api import plugin -class ExtractAnimationABC(publish.Extractor): +class ExtractAnimationABC( + publish.Extractor, + publish.OptionalPyblishPluginMixin, +): """Extract as ABC.""" label = "Extract Animation ABC" diff --git a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py index 477411b73d..3a5b788c9e 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py @@ -5,7 +5,10 @@ import bpy from openpype.pipeline import publish -class ExtractBlendAnimation(publish.Extractor): +class ExtractBlendAnimation( + publish.Extractor, + publish.OptionalPyblishPluginMixin, +): """Extract a blend file.""" label = "Extract Blend" diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py index 036be7bf3c..2a327f4d65 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class ExtractCameraABC(publish.Extractor): +class ExtractCameraABC(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract camera as ABC.""" label = "Extract Camera (ABC)" diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py index 315994140e..8e5e4d37d4 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py @@ -6,7 +6,7 @@ from openpype.pipeline import publish from openpype.hosts.blender.api import plugin -class ExtractCamera(publish.Extractor): +class ExtractCamera(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract as the camera as FBX.""" label = "Extract Camera (FBX)" diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx.py b/openpype/hosts/blender/plugins/publish/extract_fbx.py index 0ad797c226..8ace6a43a7 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx.py @@ -7,7 +7,7 @@ from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class ExtractFBX(publish.Extractor): +class ExtractFBX(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract as FBX.""" label = "Extract FBX" diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py index 062b42e99d..04f50f8207 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py @@ -10,7 +10,10 @@ from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class ExtractAnimationFBX(publish.Extractor): +class ExtractAnimationFBX( + publish.Extractor, + publish.OptionalPyblishPluginMixin, +): """Extract as animation.""" label = "Extract FBX" diff --git a/openpype/hosts/blender/plugins/publish/extract_layout.py b/openpype/hosts/blender/plugins/publish/extract_layout.py index f2d04f1178..8445560bba 100644 --- a/openpype/hosts/blender/plugins/publish/extract_layout.py +++ b/openpype/hosts/blender/plugins/publish/extract_layout.py @@ -11,7 +11,7 @@ from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class ExtractLayout(publish.Extractor): +class ExtractLayout(publish.Extractor, publish.OptionalPyblishPluginMixin): """Extract a layout.""" label = "Extract Layout" diff --git a/openpype/hosts/blender/plugins/publish/extract_playblast.py b/openpype/hosts/blender/plugins/publish/extract_playblast.py index 196e75b8cc..82ddbc1fc2 100644 --- a/openpype/hosts/blender/plugins/publish/extract_playblast.py +++ b/openpype/hosts/blender/plugins/publish/extract_playblast.py @@ -9,7 +9,7 @@ from openpype.hosts.blender.api import capture from openpype.hosts.blender.api.lib import maintained_time -class ExtractPlayblast(publish.Extractor): +class ExtractPlayblast(publish.Extractor, publish.OptionalPyblishPluginMixin): """ Extract viewport playblast. diff --git a/openpype/hosts/blender/plugins/publish/increment_workfile_version.py b/openpype/hosts/blender/plugins/publish/increment_workfile_version.py index 6ace14d77c..176668f366 100644 --- a/openpype/hosts/blender/plugins/publish/increment_workfile_version.py +++ b/openpype/hosts/blender/plugins/publish/increment_workfile_version.py @@ -1,8 +1,12 @@ import pyblish.api +from openpype.pipeline.publish import OptionalPyblishPluginMixin from openpype.hosts.blender.api.workio import save_file -class IncrementWorkfileVersion(pyblish.api.ContextPlugin): +class IncrementWorkfileVersion( + pyblish.api.ContextPlugin, + OptionalPyblishPluginMixin +): """Increment current workfile version.""" order = pyblish.api.IntegratorOrder + 0.9 diff --git a/openpype/hosts/blender/plugins/publish/integrate_animation.py b/openpype/hosts/blender/plugins/publish/integrate_animation.py index d9a85bc79b..b7e5423fa8 100644 --- a/openpype/hosts/blender/plugins/publish/integrate_animation.py +++ b/openpype/hosts/blender/plugins/publish/integrate_animation.py @@ -1,9 +1,13 @@ import json import pyblish.api +from openpype.pipeline.publish import OptionalPyblishPluginMixin -class IntegrateAnimation(pyblish.api.InstancePlugin): +class IntegrateAnimation( + pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin, +): """Generate a JSON file for animation.""" label = "Integrate Animation" diff --git a/openpype/hosts/blender/plugins/publish/validate_mesh_has_uv.py b/openpype/hosts/blender/plugins/publish/validate_mesh_has_uv.py index edf47193be..687371b362 100644 --- a/openpype/hosts/blender/plugins/publish/validate_mesh_has_uv.py +++ b/openpype/hosts/blender/plugins/publish/validate_mesh_has_uv.py @@ -4,11 +4,17 @@ import bpy import pyblish.api -from openpype.pipeline.publish import ValidateContentsOrder +from openpype.pipeline.publish import ( + ValidateContentsOrder, + OptionalPyblishPluginMixin, +) import openpype.hosts.blender.api.action -class ValidateMeshHasUvs(pyblish.api.InstancePlugin): +class ValidateMeshHasUvs( + pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin, +): """Validate that the current mesh has UV's.""" order = ValidateContentsOrder diff --git a/openpype/hosts/blender/plugins/publish/validate_object_mode.py b/openpype/hosts/blender/plugins/publish/validate_object_mode.py index ac60e00f89..d8d2e3c8bf 100644 --- a/openpype/hosts/blender/plugins/publish/validate_object_mode.py +++ b/openpype/hosts/blender/plugins/publish/validate_object_mode.py @@ -3,10 +3,14 @@ from typing import List import bpy import pyblish.api +from openpype.pipeline.publish import OptionalPyblishPluginMixin import openpype.hosts.blender.api.action -class ValidateObjectIsInObjectMode(pyblish.api.InstancePlugin): +class ValidateObjectIsInObjectMode( + pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin, +): """Validate that the objects in the instance are in Object Mode.""" order = pyblish.api.ValidatorOrder - 0.01 From 656a42dd525317f83b22a232f8dc68756d2c389a Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 9 Aug 2023 11:45:58 +0200 Subject: [PATCH 097/690] Handling instance noce --- openpype/hosts/blender/api/plugin.py | 13 ++++++++++--- .../hosts/blender/plugins/create/create_action.py | 8 ++++++++ .../blender/plugins/create/create_animation.py | 6 ++++++ .../hosts/blender/plugins/create/create_camera.py | 6 ++++++ .../hosts/blender/plugins/create/create_layout.py | 6 ++++++ .../hosts/blender/plugins/create/create_model.py | 6 ++++++ .../blender/plugins/create/create_pointcache.py | 6 ++++++ .../hosts/blender/plugins/create/create_review.py | 6 ++++++ openpype/hosts/blender/plugins/create/create_rig.py | 6 ++++++ 9 files changed, 60 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 5dd352ff6c..fe0d53f84e 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -234,13 +234,20 @@ class BlenderCreator(Creator): pre_create_data(dict): Data based on pre creation attributes. Those may affect how creator works. """ + collection = bpy.data.collections.new(name=subset_name) + bpy.context.scene.collection.children.link(collection) + + instance_node = {} + for key, value in collection.items(): + instance_node[key] = value + + instance_data["instance_node"] = instance_node + instance = CreatedInstance( self.family, subset_name, instance_data, self ) self._add_instance_to_context(instance) - collection = bpy.data.collections.new(name=subset_name) - bpy.context.scene.collection.children.link(collection) imprint(collection, instance_data) if pre_create_data.get("useSelection"): @@ -287,7 +294,7 @@ class BlenderCreator(Creator): for created_instance, _changes in update_list: data = created_instance.data_to_store() - # TODO + imprint(data.get("instance_node", {}), data) def remove_instances(self, instances: List[CreatedInstance]): diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 6951e86c46..a43258082c 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -28,6 +28,11 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): ) collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) + + instance_node = {} + for key, value in collection.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -35,8 +40,11 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) + from pprint import pprint + pprint(instance_data) lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 9e7dfbaf84..842292f0f9 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -46,6 +46,11 @@ class CreateAnimation(plugin.BlenderCreator): # asset_group.empty_display_type = 'SINGLE_ARROW' asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -53,6 +58,7 @@ class CreateAnimation(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index c5987779c0..8360abbc7d 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -44,6 +44,11 @@ class CreateCamera(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -51,6 +56,7 @@ class CreateCamera(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index cb61799f4a..b4b127f32c 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -43,6 +43,11 @@ class CreateLayout(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -50,6 +55,7 @@ class CreateLayout(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index ccf3668d98..5cb2de0fae 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -43,6 +43,11 @@ class CreateModel(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -50,6 +55,7 @@ class CreateModel(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index e27cb22389..a95ae547c8 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -28,6 +28,11 @@ class CreatePointcache(plugin.BlenderCreator): ) collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) + + instance_node = {} + for key, value in collection.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -35,6 +40,7 @@ class CreatePointcache(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(collection, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index afeaea951b..1bcafbc265 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -42,6 +42,11 @@ class CreateReview(plugin.BlenderCreator): name = plugin.asset_name(instance_data["asset"], subset_name) asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -49,6 +54,7 @@ class CreateReview(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 2db766f7ed..e93f4a171f 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -43,6 +43,11 @@ class CreateRig(plugin.BlenderCreator): asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) + + instance_node = {} + for key, value in asset_group.items(): + instance_node[key] = value + instance_data.update( { "id": "pyblish.avalon.instance", @@ -50,6 +55,7 @@ class CreateRig(plugin.BlenderCreator): "label": self.label, "task": get_current_task_name(), "subset": subset_name, + "instance_node": instance_node, } ) lib.imprint(asset_group, instance_data) From 5f7847c6973d378779e3b27a0ef25ed3fa5a9e1c Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 9 Aug 2023 12:04:06 +0200 Subject: [PATCH 098/690] Removed useless pprint --- openpype/hosts/blender/plugins/create/create_action.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index a43258082c..ee7ca092b5 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -43,8 +43,6 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): "instance_node": instance_node, } ) - from pprint import pprint - pprint(instance_data) lib.imprint(collection, instance_data) if pre_create_data.get("useSelection"): From f52c9f0a38de8c9d3f50d6a1a721f20afdfa1b5f Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 10 Aug 2023 10:37:46 +0200 Subject: [PATCH 099/690] Enhance instance_node, wip remove_inst, rm extra empty lines --- openpype/hosts/blender/api/plugin.py | 22 ++++++++++++++----- .../blender/plugins/create/create_action.py | 8 ++++--- .../plugins/create/create_animation.py | 12 ++++++---- .../blender/plugins/create/create_camera.py | 12 ++++++---- .../blender/plugins/create/create_layout.py | 12 ++++++---- .../blender/plugins/create/create_model.py | 12 ++++++---- .../plugins/create/create_pointcache.py | 8 ++++--- .../blender/plugins/create/create_review.py | 12 ++++++---- .../blender/plugins/create/create_rig.py | 12 ++++++---- 9 files changed, 75 insertions(+), 35 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index fe0d53f84e..9967f9479c 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -155,7 +155,6 @@ class BlenderCreator(Creator): return collection - @staticmethod def cache_subsets(shared_data): """Cache instances for Creators shared data. @@ -221,7 +220,6 @@ class BlenderCreator(Creator): return shared_data - def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): @@ -254,7 +252,6 @@ class BlenderCreator(Creator): for obj in get_selection(): collection.objects.link(obj) - def collect_instances(self): """Override abstract method from BaseCreator. Collect existing instances related to this creator plugin.""" @@ -283,7 +280,6 @@ class BlenderCreator(Creator): # Add instance to create context self._add_instance_to_context(instance) - def update_instances(self, update_list): """Override abstract method from BaseCreator. Store changes of existing instances so they can be recollected. @@ -296,7 +292,6 @@ class BlenderCreator(Creator): imprint(data.get("instance_node", {}), data) - def remove_instances(self, instances: List[CreatedInstance]): """Override abstract method from BaseCreator. Method called when instances are removed. @@ -305,6 +300,23 @@ class BlenderCreator(Creator): instance(List[CreatedInstance]): Instance objects to remove. """ for instance in instances: + outliner_entity = instance.data.get("instance_node", {}).get( + "datablock" + ) + if not outliner_entity: + continue + + if isinstance(outliner_entity, bpy.types.Collection): + for children in outliner_entity.children_recursive: + if isinstance(children, bpy.types.Collection): + bpy.data.collections.remove(children) + else: + bpy.data.objects.remove(children) + + bpy.data.collections.remove(outliner_entity) + elif isinstance(outliner_entity, bpy.types.Object): + bpy.data.objects.remove(outliner_entity) + self._remove_instance_from_context(instance) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index ee7ca092b5..7404e7e037 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -5,6 +5,7 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance import openpype.hosts.blender.api.plugin from openpype.hosts.blender.api import lib +from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): @@ -29,9 +30,10 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) - instance_node = {} - for key, value in collection.items(): - instance_node[key] = value + collection[AVALON_PROPERTY] = instance_node = { + "name": collection.name, + "datablock": collection, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 842292f0f9..c2f24250e1 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateAnimation(plugin.BlenderCreator): @@ -47,9 +50,10 @@ class CreateAnimation(plugin.BlenderCreator): asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 8360abbc7d..a83124cbe7 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateCamera(plugin.BlenderCreator): @@ -45,9 +48,10 @@ class CreateCamera(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index b4b127f32c..4fb76ef41e 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateLayout(plugin.BlenderCreator): @@ -44,9 +47,10 @@ class CreateLayout(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 5cb2de0fae..45f1d66ad9 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateModel(plugin.BlenderCreator): @@ -44,9 +47,10 @@ class CreateModel(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index a95ae547c8..7aa3b22466 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -5,6 +5,7 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY class CreatePointcache(plugin.BlenderCreator): @@ -29,9 +30,10 @@ class CreatePointcache(plugin.BlenderCreator): collection = bpy.data.collections.new(name=name) bpy.context.scene.collection.children.link(collection) - instance_node = {} - for key, value in collection.items(): - instance_node[key] = value + collection[AVALON_PROPERTY] = instance_node = { + "name": collection.name, + "datablock": collection, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 1bcafbc265..a6ca5b1b92 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateReview(plugin.BlenderCreator): @@ -43,9 +46,10 @@ class CreateReview(plugin.BlenderCreator): asset_group = bpy.data.collections.new(name=name) instances.children.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index e93f4a171f..f7c99b0b03 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name, CreatedInstance from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateRig(plugin.BlenderCreator): @@ -44,9 +47,10 @@ class CreateRig(plugin.BlenderCreator): asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - instance_node = {} - for key, value in asset_group.items(): - instance_node[key] = value + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name, + "datablock": asset_group, + } instance_data.update( { From 371d7405ec10257fe52c1259c383604862b080f7 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 10 Aug 2023 11:19:05 +0200 Subject: [PATCH 100/690] Apply creator change to bl base creator --- openpype/hosts/blender/api/plugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 9967f9479c..060d229eb5 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -235,9 +235,10 @@ class BlenderCreator(Creator): collection = bpy.data.collections.new(name=subset_name) bpy.context.scene.collection.children.link(collection) - instance_node = {} - for key, value in collection.items(): - instance_node[key] = value + collection["instance_node"] = instance_node = { + "name": collection.name, + "datablock": collection, + } instance_data["instance_node"] = instance_node From e832cf59ccb2bbf6a436184f1143ebf53231c5df Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 12 Sep 2023 15:49:33 +0200 Subject: [PATCH 101/690] Fix Cannot pickle object error --- openpype/hosts/blender/api/plugin.py | 5 +---- openpype/hosts/blender/plugins/create/create_action.py | 1 - openpype/hosts/blender/plugins/create/create_animation.py | 1 - openpype/hosts/blender/plugins/create/create_camera.py | 1 - openpype/hosts/blender/plugins/create/create_layout.py | 1 - openpype/hosts/blender/plugins/create/create_model.py | 1 - openpype/hosts/blender/plugins/create/create_pointcache.py | 1 - openpype/hosts/blender/plugins/create/create_review.py | 1 - openpype/hosts/blender/plugins/create/create_rig.py | 1 - 9 files changed, 1 insertion(+), 12 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 060d229eb5..73d8fc0ed5 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -237,7 +237,6 @@ class BlenderCreator(Creator): collection["instance_node"] = instance_node = { "name": collection.name, - "datablock": collection, } instance_data["instance_node"] = instance_node @@ -267,9 +266,7 @@ class BlenderCreator(Creator): for instance_data in cached_subsets.get(self.identifier, []): # Process only instances that were created by this creator - data = {} - for key, value in instance_data.items(): - data[key] = value + data = instance_data.to_dict() creator_id = data.get('creator_identifier') if creator_id == self.identifier: diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 7404e7e037..d766fce038 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -32,7 +32,6 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): collection[AVALON_PROPERTY] = instance_node = { "name": collection.name, - "datablock": collection, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index c2f24250e1..88ae9e5996 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -52,7 +52,6 @@ class CreateAnimation(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index a83124cbe7..026b5739d6 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -50,7 +50,6 @@ class CreateCamera(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index 4fb76ef41e..f46ae58a43 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -49,7 +49,6 @@ class CreateLayout(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 45f1d66ad9..069b78626b 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -49,7 +49,6 @@ class CreateModel(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 7aa3b22466..3054b81ef5 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -32,7 +32,6 @@ class CreatePointcache(plugin.BlenderCreator): collection[AVALON_PROPERTY] = instance_node = { "name": collection.name, - "datablock": collection, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index a6ca5b1b92..10a96c94fd 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -48,7 +48,6 @@ class CreateReview(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index f7c99b0b03..8daffe638d 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -49,7 +49,6 @@ class CreateRig(plugin.BlenderCreator): asset_group[AVALON_PROPERTY] = instance_node = { "name": asset_group.name, - "datablock": asset_group, } instance_data.update( From 78b33370dc3418083d323d465332ff28aa32fbeb Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Mon, 18 Sep 2023 17:59:33 +0200 Subject: [PATCH 102/690] Fix collectreview --- openpype/hosts/blender/plugins/publish/collect_review.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_review.py b/openpype/hosts/blender/plugins/publish/collect_review.py index 3bf2e39e24..66a3d7b5e8 100644 --- a/openpype/hosts/blender/plugins/publish/collect_review.py +++ b/openpype/hosts/blender/plugins/publish/collect_review.py @@ -16,10 +16,14 @@ class CollectReview(pyblish.api.InstancePlugin): self.log.debug(f"instance: {instance}") + datablock = bpy.data.collections.get( + instance.data.get("instance_node", {}).get("name", "") + ) + # get cameras cameras = [ obj - for obj in instance + for obj in datablock.all_objects if isinstance(obj, bpy.types.Object) and obj.type == "CAMERA" ] From a526260b461a85e951a1fc87697a56df70afa7d3 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 17:57:09 +0200 Subject: [PATCH 103/690] 'get_assets' function can find folders by path and by name --- openpype/client/server/entities.py | 57 ++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index 16223d3d91..c1e27eabb9 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -183,6 +183,20 @@ def get_asset_by_name(project_name, asset_name, fields=None): return None + +def _folders_query(project_name, con, fields, **kwargs): + if fields is None or "tasks" in fields: + folders = get_folders_with_tasks( + con, project_name, fields=fields, **kwargs + ) + + else: + folders = con.get_folders(project_name, fields=fields, **kwargs) + + for folder in folders: + yield folder + + def get_assets( project_name, asset_ids=None, @@ -199,22 +213,51 @@ def get_assets( active = None con = get_server_api_connection() + fields = folder_fields_v3_to_v4(fields, con) kwargs = dict( folder_ids=asset_ids, - folder_names=asset_names, parent_ids=parent_ids, active=active, - fields=fields ) + if not asset_names: + for folder in _folders_query(project_name, con, fields, **kwargs): + yield convert_v4_folder_to_v3(folder, project_name) + return - if fields is None or "tasks" in fields: - folders = get_folders_with_tasks(con, project_name, **kwargs) + new_asset_names = set() + folder_paths = set() + if asset_names: + for name in asset_names: + if "/" in name: + folder_paths.add(name) + else: + new_asset_names.add(name) - else: - folders = con.get_folders(project_name, **kwargs) + if folder_paths: + for folder in _folders_query( + project_name, con, fields, folder_paths=folder_paths, **kwargs + ): + yield convert_v4_folder_to_v3(folder, project_name) - for folder in folders: + if not new_asset_names: + return + + folders_by_name = collections.defaultdict(list) + for folder in _folders_query( + project_name, con, fields, folder_names=new_asset_names, **kwargs + ): + folders_by_name[folder["name"]].append(folder) + + for name, folders in folders_by_name.items(): + folder = next( + ( + folder + for folder in folders + if folder["path"] == name + ), + folders[0] + ) yield convert_v4_folder_to_v3(folder, project_name) From 331c4833ade7acf5ab0db7952e9821b817354d2d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 17:58:34 +0200 Subject: [PATCH 104/690] added helper function 'get_asset_name_identifier' to receive folder path in AYON mode and asset name in openpype --- openpype/client/__init__.py | 4 ++++ openpype/client/entities.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/openpype/client/__init__.py b/openpype/client/__init__.py index 7831afd8ad..a313d6b3cc 100644 --- a/openpype/client/__init__.py +++ b/openpype/client/__init__.py @@ -43,6 +43,8 @@ from .entities import ( get_thumbnail_id_from_source, get_workfile_info, + + get_asset_name_identifier, ) from .entity_links import ( @@ -105,4 +107,6 @@ __all__ = ( "get_linked_representation_id", "create_project", + + "get_asset_name_identifier", ) diff --git a/openpype/client/entities.py b/openpype/client/entities.py index 5d9654c611..d085f90028 100644 --- a/openpype/client/entities.py +++ b/openpype/client/entities.py @@ -4,3 +4,22 @@ if not AYON_SERVER_ENABLED: from .mongo.entities import * else: from .server.entities import * + + +def get_asset_name_identifier(asset_doc): + """Get asset name identifier by asset document. + + This function is added because of AYON implementation where name + identifier is not just a name but full path. + + Asset document must have "name" key, and "data.parents" when in AYON mode. + + Args: + asset_doc (dict[str, Any]): Asset document. + """ + + if not AYON_SERVER_ENABLED: + return asset_doc["name"] + parents = list(asset_doc["data"]["parents"]) + parents.append(asset_doc["name"]) + return "/".join(parents) From 4c6ec4b9bcb245892421b14bee26d7564f33f971 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:00:58 +0200 Subject: [PATCH 105/690] instances in AYON mode have 'folderPath' instead of 'asset' --- openpype/pipeline/create/context.py | 37 ++++++++++++++++--- .../publish/collect_from_create_context.py | 3 ++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/openpype/pipeline/create/context.py b/openpype/pipeline/create/context.py index 25f03ddd3b..333ab25f54 100644 --- a/openpype/pipeline/create/context.py +++ b/openpype/pipeline/create/context.py @@ -11,7 +11,12 @@ from contextlib import contextmanager import pyblish.logic import pyblish.api -from openpype.client import get_assets, get_asset_by_name +from openpype import AYON_SERVER_ENABLED +from openpype.client import ( + get_assets, + get_asset_by_name, + get_asset_name_identifier, +) from openpype.settings import ( get_system_settings, get_project_settings @@ -922,9 +927,19 @@ class CreatedInstance: self._orig_data = copy.deepcopy(data) # Pop family and subset to prevent unexpected changes + # TODO change to 'productType' and 'productName' in AYON data.pop("family", None) data.pop("subset", None) + if AYON_SERVER_ENABLED: + asset_name = data.pop("asset", None) + if "folderPath" not in data: + data["folderPath"] = asset_name + + elif "folderPath" in data: + asset_name = data.pop("folderPath").split("/")[-1] + if "asset" not in data: + data["asset"] = asset_name # QUESTION Does it make sense to have data stored as ordered dict? self._data = collections.OrderedDict() @@ -1268,6 +1283,8 @@ class CreatedInstance: def has_set_asset(self): """Asset name is set in data.""" + if AYON_SERVER_ENABLED: + return "folderPath" in self._data return "asset" in self._data @property @@ -2229,7 +2246,10 @@ class CreateContext: task_names_by_asset_name = {} for instance in instances: task_name = instance.get("task") - asset_name = instance.get("asset") + if AYON_SERVER_ENABLED: + asset_name = instance.get("folderPath") + else: + asset_name = instance.get("asset") if asset_name: task_names_by_asset_name[asset_name] = set() if task_name: @@ -2240,15 +2260,18 @@ class CreateContext: for asset_name in task_names_by_asset_name.keys() if asset_name is not None ] + fields = {"name", "data.tasks"} + if AYON_SERVER_ENABLED: + fields |= {"data.parents"} asset_docs = list(get_assets( self.project_name, asset_names=asset_names, - fields=["name", "data.tasks"] + fields=fields )) task_names_by_asset_name = {} for asset_doc in asset_docs: - asset_name = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) tasks = asset_doc.get("data", {}).get("tasks") or {} task_names_by_asset_name[asset_name] = set(tasks.keys()) @@ -2256,7 +2279,11 @@ class CreateContext: if not instance.has_valid_asset or not instance.has_valid_task: continue - asset_name = instance["asset"] + if AYON_SERVER_ENABLED: + asset_name = instance["folderPath"] + else: + asset_name = instance["asset"] + if asset_name not in task_names_by_asset_name: instance.set_asset_invalid(True) continue diff --git a/openpype/plugins/publish/collect_from_create_context.py b/openpype/plugins/publish/collect_from_create_context.py index 8806a13ca0..84f6141069 100644 --- a/openpype/plugins/publish/collect_from_create_context.py +++ b/openpype/plugins/publish/collect_from_create_context.py @@ -4,6 +4,7 @@ import os import pyblish.api +from openpype import AYON_SERVER_ENABLED from openpype.host import IPublishHost from openpype.pipeline import legacy_io, registered_host from openpype.pipeline.create import CreateContext @@ -38,6 +39,8 @@ class CollectFromCreateContext(pyblish.api.ContextPlugin): for created_instance in create_context.instances: instance_data = created_instance.data_to_store() + if AYON_SERVER_ENABLED: + instance_data["asset"] = instance_data.pop("folderPath") if instance_data["active"]: thumbnail_path = thumbnail_paths_by_instance_id.get( created_instance.id From 0ddd95eacf0fda0b058fccc3388d0816aa9d4145 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:02:41 +0200 Subject: [PATCH 106/690] use 'get_asset_name_identifier' in pipeline logic --- openpype/pipeline/context_tools.py | 5 ++--- openpype/pipeline/create/utils.py | 11 ++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 13630ae7ca..e20099759a 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -17,6 +17,7 @@ from openpype.client import ( get_asset_by_id, get_asset_by_name, version_is_latest, + get_asset_name_identifier, ) from openpype.lib.events import emit_event from openpype.modules import load_modules, ModulesManager @@ -568,14 +569,12 @@ def compute_session_changes( Dict[str, str]: Changes in the Session dictionary. """ - changes = {} - # Get asset document and asset if not asset_doc: task_name = None asset_name = None else: - asset_name = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) # Detect any changes compared session mapping = { diff --git a/openpype/pipeline/create/utils.py b/openpype/pipeline/create/utils.py index 2ef1f02bd6..ce4af8f474 100644 --- a/openpype/pipeline/create/utils.py +++ b/openpype/pipeline/create/utils.py @@ -1,6 +1,11 @@ import collections -from openpype.client import get_assets, get_subsets, get_last_versions +from openpype.client import ( + get_assets, + get_subsets, + get_last_versions, + get_asset_name_identifier, +) def get_last_versions_for_instances( @@ -52,10 +57,10 @@ def get_last_versions_for_instances( asset_docs = get_assets( project_name, asset_names=subset_names_by_asset_name.keys(), - fields=["name", "_id"] + fields=["name", "_id", "data.parents"] ) asset_names_by_id = { - asset_doc["_id"]: asset_doc["name"] + asset_doc["_id"]: get_asset_name_identifier(asset_doc) for asset_doc in asset_docs } if not asset_names_by_id: From 922c481d95b6e377a8d7433819360c45179fcffa Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:03:02 +0200 Subject: [PATCH 107/690] use 'get_asset_name_identifier' for 'AVALON_ASSET' on app start --- openpype/lib/applications.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/lib/applications.py b/openpype/lib/applications.py index ff5e27c122..4d75a01e1d 100644 --- a/openpype/lib/applications.py +++ b/openpype/lib/applications.py @@ -12,6 +12,7 @@ from abc import ABCMeta, abstractmethod import six from openpype import AYON_SERVER_ENABLED, PACKAGE_DIR +from openpype.client import get_asset_name_identifier from openpype.settings import ( get_system_settings, get_project_settings, @@ -1728,7 +1729,9 @@ def prepare_context_environments(data, env_group=None, modules_manager=None): "AVALON_APP_NAME": app.full_name } if asset_doc: - context_env["AVALON_ASSET"] = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) + context_env["AVALON_ASSET"] = asset_name + if task_name: context_env["AVALON_TASK"] = task_name From f38c3f395e68df0a33a3b1ba135dbbcf0cf7f899 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:03:20 +0200 Subject: [PATCH 108/690] use 'get_asset_name_identifier' in global plugins --- .../publish/collect_anatomy_instance_data.py | 20 +++++++++++-------- openpype/plugins/publish/collect_audio.py | 10 ++++++---- .../publish/extract_hierarchy_to_ayon.py | 4 ++-- .../publish/validate_editorial_asset_name.py | 9 ++++++--- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/openpype/plugins/publish/collect_anatomy_instance_data.py b/openpype/plugins/publish/collect_anatomy_instance_data.py index b4f4d6a16a..cc6da9b2c3 100644 --- a/openpype/plugins/publish/collect_anatomy_instance_data.py +++ b/openpype/plugins/publish/collect_anatomy_instance_data.py @@ -30,7 +30,8 @@ import pyblish.api from openpype.client import ( get_assets, get_subsets, - get_last_versions + get_last_versions, + get_asset_name_identifier, ) from openpype.pipeline.version_start import get_versioning_start @@ -60,6 +61,9 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): self.log.debug("Querying asset documents for instances.") context_asset_doc = context.data.get("assetEntity") + context_asset_name = None + if context_asset_doc: + context_asset_name = get_asset_name_identifier(context_asset_doc) instances_with_missing_asset_doc = collections.defaultdict(list) for instance in context: @@ -68,15 +72,15 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): # There is possibility that assetEntity on instance is already set # which can happen in standalone publisher - if ( - instance_asset_doc - and instance_asset_doc["name"] == _asset_name - ): - continue + if instance_asset_doc: + instance_asset_name = get_asset_name_identifier( + instance_asset_doc) + if instance_asset_name == _asset_name: + continue # Check if asset name is the same as what is in context # - they may be different, e.g. in NukeStudio - if context_asset_doc and context_asset_doc["name"] == _asset_name: + if context_asset_name and context_asset_name == _asset_name: instance.data["assetEntity"] = context_asset_doc else: @@ -93,7 +97,7 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): asset_docs = get_assets(project_name, asset_names=asset_names) asset_docs_by_name = { - asset_doc["name"]: asset_doc + get_asset_name_identifier(asset_doc): asset_doc for asset_doc in asset_docs } diff --git a/openpype/plugins/publish/collect_audio.py b/openpype/plugins/publish/collect_audio.py index 6aaadfc568..734a625852 100644 --- a/openpype/plugins/publish/collect_audio.py +++ b/openpype/plugins/publish/collect_audio.py @@ -6,6 +6,7 @@ from openpype.client import ( get_subsets, get_last_versions, get_representations, + get_asset_name_identifier, ) from openpype.pipeline.load import get_representation_path_with_anatomy @@ -121,12 +122,13 @@ class CollectAudio(pyblish.api.ContextPlugin): asset_docs = get_assets( project_name, asset_names=asset_names, - fields=["_id", "name"] + fields=["_id", "name", "data.parents"] ) - asset_id_by_name = {} - for asset_doc in asset_docs: - asset_id_by_name[asset_doc["name"]] = asset_doc["_id"] + asset_id_by_name = { + get_asset_name_identifier(asset_doc): asset_doc["_id"] + for asset_doc in asset_docs + } asset_ids = set(asset_id_by_name.values()) # Query subsets with name define by 'audio_subset_name' attr diff --git a/openpype/plugins/publish/extract_hierarchy_to_ayon.py b/openpype/plugins/publish/extract_hierarchy_to_ayon.py index 0d9131718b..fe8cb40ad2 100644 --- a/openpype/plugins/publish/extract_hierarchy_to_ayon.py +++ b/openpype/plugins/publish/extract_hierarchy_to_ayon.py @@ -8,7 +8,7 @@ from ayon_api import slugify_string from ayon_api.entity_hub import EntityHub from openpype import AYON_SERVER_ENABLED -from openpype.client import get_assets +from openpype.client import get_assets, get_asset_name_identifier from openpype.pipeline.template_data import ( get_asset_template_data, get_task_template_data, @@ -58,7 +58,7 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): project_name, asset_names=instances_by_asset_name.keys() ) asset_docs_by_name = { - asset_doc["name"]: asset_doc + get_asset_name_identifier(asset_doc): asset_doc for asset_doc in asset_docs } for asset_name, instances in instances_by_asset_name.items(): diff --git a/openpype/plugins/publish/validate_editorial_asset_name.py b/openpype/plugins/publish/validate_editorial_asset_name.py index fca0d8e7f5..b5afc49f2e 100644 --- a/openpype/plugins/publish/validate_editorial_asset_name.py +++ b/openpype/plugins/publish/validate_editorial_asset_name.py @@ -2,7 +2,7 @@ from pprint import pformat import pyblish.api -from openpype.client import get_assets +from openpype.client import get_assets, get_asset_name_identifier class ValidateEditorialAssetName(pyblish.api.ContextPlugin): @@ -34,8 +34,11 @@ class ValidateEditorialAssetName(pyblish.api.ContextPlugin): self.log.debug("__ db_assets: {}".format(db_assets)) asset_db_docs = { - str(e["name"]): [str(p) for p in e["data"]["parents"]] - for e in db_assets} + get_asset_name_identifier(asset_doc): list( + asset_doc["data"]["parents"] + ) + for asset_doc in db_assets + } self.log.debug("__ project_entities: {}".format( pformat(asset_db_docs))) From c505513b056e092ac8dd8c3652776a238046980c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:04:31 +0200 Subject: [PATCH 109/690] use folder path in ayon tools to define current context --- openpype/tools/ayon_launcher/models/actions.py | 6 +++--- openpype/tools/ayon_loader/control.py | 2 +- openpype/tools/ayon_sceneinventory/control.py | 11 ++--------- openpype/tools/ayon_workfiles/control.py | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/openpype/tools/ayon_launcher/models/actions.py b/openpype/tools/ayon_launcher/models/actions.py index 93ec115734..d7c4219dc2 100644 --- a/openpype/tools/ayon_launcher/models/actions.py +++ b/openpype/tools/ayon_launcher/models/actions.py @@ -402,12 +402,12 @@ class ActionsModel: ) def _prepare_session(self, project_name, folder_id, task_id): - folder_name = None + folder_path = None if folder_id: folder = self._controller.get_folder_entity( project_name, folder_id) if folder: - folder_name = folder["name"] + folder_path = folder["path"] task_name = None if task_id: @@ -417,7 +417,7 @@ class ActionsModel: return { "AVALON_PROJECT": project_name, - "AVALON_ASSET": folder_name, + "AVALON_ASSET": folder_path, "AVALON_TASK": task_name, } diff --git a/openpype/tools/ayon_loader/control.py b/openpype/tools/ayon_loader/control.py index 2b779f5c2e..d2fae35f32 100644 --- a/openpype/tools/ayon_loader/control.py +++ b/openpype/tools/ayon_loader/control.py @@ -289,7 +289,7 @@ class LoaderController(BackendLoaderController, FrontendLoaderController): project_name = context.get("project_name") asset_name = context.get("asset_name") if project_name and asset_name: - folder = ayon_api.get_folder_by_name( + folder = ayon_api.get_folder_by_path( project_name, asset_name, fields=["id"] ) if folder: diff --git a/openpype/tools/ayon_sceneinventory/control.py b/openpype/tools/ayon_sceneinventory/control.py index e98b0e307b..6111d7e43b 100644 --- a/openpype/tools/ayon_sceneinventory/control.py +++ b/openpype/tools/ayon_sceneinventory/control.py @@ -70,19 +70,12 @@ class SceneInventoryController: context = self.get_current_context() project_name = context["project_name"] - folder_path = context.get("folder_path") folder_name = context.get("asset_name") folder_id = None - if folder_path: - folder = ayon_api.get_folder_by_path(project_name, folder_path) + if folder_name: + folder = ayon_api.get_folder_by_path(project_name, folder_name) if folder: folder_id = folder["id"] - elif folder_name: - for folder in ayon_api.get_folders( - project_name, folder_names=[folder_name] - ): - folder_id = folder["id"] - break self._current_folder_id = folder_id self._current_folder_set = True diff --git a/openpype/tools/ayon_workfiles/control.py b/openpype/tools/ayon_workfiles/control.py index 3784959caf..d86b04badb 100644 --- a/openpype/tools/ayon_workfiles/control.py +++ b/openpype/tools/ayon_workfiles/control.py @@ -427,7 +427,7 @@ class BaseWorkfileController( task_name = context["task_name"] folder_id = None if folder_name: - folder = ayon_api.get_folder_by_name(project_name, folder_name) + folder = ayon_api.get_folder_by_path(project_name, folder_name) if folder: folder_id = folder["id"] From 1ac66764d49af599915a592de0917a4b67977358 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:05:16 +0200 Subject: [PATCH 110/690] use folder path in publisher --- openpype/tools/publisher/control.py | 6 ++- .../tools/publisher/widgets/assets_widget.py | 42 ++++++++++++++++--- openpype/tools/publisher/widgets/widgets.py | 17 ++++++-- openpype/tools/utils/assets_widget.py | 1 + 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/openpype/tools/publisher/control.py b/openpype/tools/publisher/control.py index a6264303d5..ad87bdf607 100644 --- a/openpype/tools/publisher/control.py +++ b/openpype/tools/publisher/control.py @@ -12,10 +12,12 @@ from abc import ABCMeta, abstractmethod import six import pyblish.api +from openpype import AYON_SERVER_ENABLED from openpype.client import ( get_assets, get_asset_by_id, get_subsets, + get_asset_name_identifier, ) from openpype.lib.events import EventSystem from openpype.lib.attribute_definitions import ( @@ -73,6 +75,8 @@ class AssetDocsCache: "data.visualParent": True, "data.tasks": True } + if AYON_SERVER_ENABLED: + projection["data.parents"] = True def __init__(self, controller): self._controller = controller @@ -105,7 +109,7 @@ class AssetDocsCache: elif "tasks" not in asset_doc["data"]: asset_doc["data"]["tasks"] = {} - asset_name = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) asset_tasks = asset_doc["data"]["tasks"] task_names_by_asset_name[asset_name] = list(asset_tasks.keys()) asset_docs_by_name[asset_name] = asset_doc diff --git a/openpype/tools/publisher/widgets/assets_widget.py b/openpype/tools/publisher/widgets/assets_widget.py index c536f93c9b..5f74b79c99 100644 --- a/openpype/tools/publisher/widgets/assets_widget.py +++ b/openpype/tools/publisher/widgets/assets_widget.py @@ -11,7 +11,8 @@ from openpype.tools.utils import ( from openpype.tools.utils.assets_widget import ( SingleSelectAssetsWidget, ASSET_ID_ROLE, - ASSET_NAME_ROLE + ASSET_NAME_ROLE, + ASSET_PATH_ROLE, ) @@ -31,6 +32,15 @@ class CreateWidgetAssetsWidget(SingleSelectAssetsWidget): self._last_filter_height = None + def get_selected_asset_name(self): + if AYON_SERVER_ENABLED: + selection_model = self._view.selectionModel() + indexes = selection_model.selectedRows() + for index in indexes: + return index.data(ASSET_PATH_ROLE) + return None + return super(CreateWidgetAssetsWidget, self).get_selected_asset_name() + def _check_header_height(self): """Catch header height changes. @@ -100,21 +110,24 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel): self._controller = controller self._items_by_name = {} + self._items_by_path = {} self._items_by_asset_id = {} def reset(self): self.clear() self._items_by_name = {} + self._items_by_path = {} self._items_by_asset_id = {} assets_by_parent_id = self._controller.get_asset_hierarchy() items_by_name = {} + items_by_path = {} items_by_asset_id = {} _queue = collections.deque() - _queue.append((self.invisibleRootItem(), None)) + _queue.append((self.invisibleRootItem(), None, None)) while _queue: - parent_item, parent_id = _queue.popleft() + parent_item, parent_id, parent_path = _queue.popleft() children = assets_by_parent_id.get(parent_id) if not children: continue @@ -127,6 +140,9 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel): for name in sorted(children_by_name.keys()): child = children_by_name[name] child_id = child["_id"] + child_path = name + if parent_path: + child_path = "{}/{}".format(parent_path, child_path) has_children = bool(assets_by_parent_id.get(child_id)) icon = get_asset_icon(child, has_children) @@ -138,15 +154,18 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel): item.setData(icon, QtCore.Qt.DecorationRole) item.setData(child_id, ASSET_ID_ROLE) item.setData(name, ASSET_NAME_ROLE) + item.setData(child_path, ASSET_PATH_ROLE) items_by_name[name] = item + items_by_path[child_path] = item items_by_asset_id[child_id] = item items.append(item) - _queue.append((item, child_id)) + _queue.append((item, child_id, child_path)) parent_item.appendRows(items) self._items_by_name = items_by_name + self._items_by_path = items_by_path self._items_by_asset_id = items_by_asset_id def get_index_by_asset_id(self, asset_id): @@ -156,12 +175,20 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel): return QtCore.QModelIndex() def get_index_by_asset_name(self, asset_name): - item = self._items_by_name.get(asset_name) + item = None + if AYON_SERVER_ENABLED: + item = self._items_by_path.get(asset_name) + + if item is None: + item = self._items_by_name.get(asset_name) + if item is None: return QtCore.QModelIndex() return item.index() def name_is_valid(self, item_name): + if AYON_SERVER_ENABLED and item_name in self._items_by_path: + return True return item_name in self._items_by_name @@ -296,7 +323,10 @@ class AssetsDialog(QtWidgets.QDialog): index = self._asset_view.currentIndex() asset_name = None if index.isValid(): - asset_name = index.data(ASSET_NAME_ROLE) + if AYON_SERVER_ENABLED: + asset_name = index.data(ASSET_PATH_ROLE) + else: + asset_name = index.data(ASSET_NAME_ROLE) self._selected_asset = asset_name self.done(1) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 1bbe73381f..cc0f7a9f97 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -538,6 +538,7 @@ class AssetsField(BaseClickableFrame): Does not change selected items (assets). """ self._name_input.setText(text) + self._name_input.end(False) def set_selected_items(self, asset_names=None): """Set asset names for selection of instances. @@ -1162,7 +1163,10 @@ class GlobalAttrsWidget(QtWidgets.QWidget): invalid_tasks = False for instance in self._current_instances: new_variant_value = instance.get("variant") - new_asset_name = instance.get("asset") + if AYON_SERVER_ENABLED: + new_asset_name = instance.get("folderPath") + else: + new_asset_name = instance.get("asset") new_task_name = instance.get("task") if variant_value is not None: new_variant_value = variant_value @@ -1193,7 +1197,11 @@ class GlobalAttrsWidget(QtWidgets.QWidget): instance["variant"] = variant_value if asset_name is not None: - instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + instance["folderPath"] = asset_name + else: + instance["asset"] = asset_name + instance.set_asset_invalid(False) if task_name is not None: @@ -1282,7 +1290,10 @@ class GlobalAttrsWidget(QtWidgets.QWidget): variants.add(instance.get("variant") or self.unknown_value) families.add(instance.get("family") or self.unknown_value) - asset_name = instance.get("asset") or self.unknown_value + if AYON_SERVER_ENABLED: + asset_name = instance.get("folderPath") or self.unknown_value + else: + asset_name = instance.get("asset") or self.unknown_value task_name = instance.get("task") or "" asset_names.add(asset_name) asset_task_combinations.append((asset_name, task_name)) diff --git a/openpype/tools/utils/assets_widget.py b/openpype/tools/utils/assets_widget.py index a45d762c73..b83f4dfcaf 100644 --- a/openpype/tools/utils/assets_widget.py +++ b/openpype/tools/utils/assets_widget.py @@ -36,6 +36,7 @@ ASSET_ID_ROLE = QtCore.Qt.UserRole + 1 ASSET_NAME_ROLE = QtCore.Qt.UserRole + 2 ASSET_LABEL_ROLE = QtCore.Qt.UserRole + 3 ASSET_UNDERLINE_COLORS_ROLE = QtCore.Qt.UserRole + 4 +ASSET_PATH_ROLE = QtCore.Qt.UserRole + 5 class AssetsView(TreeViewSpinner, DeselectableTreeView): From 69792a5c64446bf4c5b17333f2da14a2b9368e3a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:07:06 +0200 Subject: [PATCH 111/690] use 'get_asset_name_identifier' in aftereffecs --- .../plugins/create/workfile_creator.py | 22 ++++++++++++++++--- .../plugins/publish/collect_workfile.py | 6 ++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/aftereffects/plugins/create/workfile_creator.py b/openpype/hosts/aftereffects/plugins/create/workfile_creator.py index 2e7b9d4a7e..5dc3d6592d 100644 --- a/openpype/hosts/aftereffects/plugins/create/workfile_creator.py +++ b/openpype/hosts/aftereffects/plugins/create/workfile_creator.py @@ -1,3 +1,4 @@ +from openpype import AYON_SERVER_ENABLED import openpype.hosts.aftereffects.api as api from openpype.client import get_asset_by_name from openpype.pipeline import ( @@ -43,6 +44,14 @@ class AEWorkfileCreator(AutoCreator): task_name = context.get_current_task_name() host_name = context.host_name + existing_asset_name = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_asset_name = existing_instance.get("folderPath") + + if existing_asset_name is None: + existing_asset_name = existing_instance["asset"] + if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -50,10 +59,13 @@ class AEWorkfileCreator(AutoCreator): project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name data.update(self.get_dynamic_data( self.default_variant, task_name, asset_doc, project_name, host_name, None @@ -68,7 +80,7 @@ class AEWorkfileCreator(AutoCreator): new_instance.data_to_store()) elif ( - existing_instance["asset"] != asset_name + existing_asset_name != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -76,6 +88,10 @@ class AEWorkfileCreator(AutoCreator): self.default_variant, task_name, asset_doc, project_name, host_name ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name + existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/aftereffects/plugins/publish/collect_workfile.py b/openpype/hosts/aftereffects/plugins/publish/collect_workfile.py index dc557f67fc..58d2757840 100644 --- a/openpype/hosts/aftereffects/plugins/publish/collect_workfile.py +++ b/openpype/hosts/aftereffects/plugins/publish/collect_workfile.py @@ -1,6 +1,8 @@ import os import pyblish.api + +from openpype.client import get_asset_name_identifier from openpype.pipeline.create import get_subset_name @@ -48,9 +50,11 @@ class CollectWorkfile(pyblish.api.ContextPlugin): asset_entity = context.data["assetEntity"] project_entity = context.data["projectEntity"] + asset_name = get_asset_name_identifier(asset_entity) + instance_data = { "active": True, - "asset": asset_entity["name"], + "asset": asset_name, "task": task, "frameStart": context.data['frameStart'], "frameEnd": context.data['frameEnd'], From 18fcfa4a4133ac71873ed5ac67e498891b514f96 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:07:17 +0200 Subject: [PATCH 112/690] use 'get_asset_name_identifier' in fusion --- .../fusion/plugins/create/create_workfile.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_workfile.py b/openpype/hosts/fusion/plugins/create/create_workfile.py index 8acaaa172f..8063e56413 100644 --- a/openpype/hosts/fusion/plugins/create/create_workfile.py +++ b/openpype/hosts/fusion/plugins/create/create_workfile.py @@ -1,6 +1,7 @@ from openpype.hosts.fusion.api import ( get_current_comp ) +from openpype import AYON_SERVER_ENABLED from openpype.client import get_asset_by_name from openpype.pipeline import ( AutoCreator, @@ -68,6 +69,15 @@ class FusionWorkfileCreator(AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name + existing_instance_asset = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance.data.get( + "folderPath") + + if not existing_instance_asset: + existing_instance_asset = existing_instance.data.get("asset") + if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -75,10 +85,13 @@ class FusionWorkfileCreator(AutoCreator): project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name data.update(self.get_dynamic_data( self.default_variant, task_name, asset_doc, project_name, host_name, None @@ -91,7 +104,7 @@ class FusionWorkfileCreator(AutoCreator): self._add_instance_to_context(new_instance) elif ( - existing_instance["asset"] != asset_name + existing_instance_asset != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -99,6 +112,9 @@ class FusionWorkfileCreator(AutoCreator): self.default_variant, task_name, asset_doc, project_name, host_name ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name From 279ab08dfacf6f0916d0162f35c11e72567565e1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:07:27 +0200 Subject: [PATCH 113/690] use 'get_asset_name_identifier' in celaction --- .../plugins/publish/collect_celaction_instances.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py index c815c1edd4..875f15fcc5 100644 --- a/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py +++ b/openpype/hosts/celaction/plugins/publish/collect_celaction_instances.py @@ -1,6 +1,8 @@ import os import pyblish.api +from openpype.client import get_asset_name_identifier + class CollectCelactionInstances(pyblish.api.ContextPlugin): """ Adds the celaction render instances """ @@ -17,8 +19,10 @@ class CollectCelactionInstances(pyblish.api.ContextPlugin): asset_entity = context.data["assetEntity"] project_entity = context.data["projectEntity"] + asset_name = get_asset_name_identifier(asset_entity) + shared_instance_data = { - "asset": asset_entity["name"], + "asset": asset_name, "frameStart": asset_entity["data"]["frameStart"], "frameEnd": asset_entity["data"]["frameEnd"], "handleStart": asset_entity["data"]["handleStart"], From a5056ea3fbca99c74f63ccafe409bbc650ec612b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:09:43 +0200 Subject: [PATCH 114/690] modified maya to follow new usage of 'asset' value --- openpype/hosts/maya/api/plugin.py | 11 ++++++---- .../maya/plugins/create/create_review.py | 7 +++++- .../maya/plugins/create/create_workfile.py | 22 +++++++++++++++---- .../validate_unreal_staticmesh_naming.py | 3 ++- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/maya/api/plugin.py b/openpype/hosts/maya/api/plugin.py index 3b54954c8a..6c8b5b6b78 100644 --- a/openpype/hosts/maya/api/plugin.py +++ b/openpype/hosts/maya/api/plugin.py @@ -7,6 +7,7 @@ import six from maya import cmds from maya.app.renderSetup.model import renderSetup +from openpype import AYON_SERVER_ENABLED from openpype.lib import BoolDef, Logger from openpype.settings import get_project_settings from openpype.pipeline import ( @@ -463,14 +464,16 @@ class RenderlayerCreator(NewCreator, MayaCreatorBase): # this instance will not have the `instance_node` data yet # until it's been saved/persisted at least once. project_name = self.create_context.get_current_project_name() - + asset_name = self.create_context.get_current_asset_name() instance_data = { - "asset": self.create_context.get_current_asset_name(), "task": self.create_context.get_current_task_name(), "variant": layer.name(), } - asset_doc = get_asset_by_name(project_name, - instance_data["asset"]) + if AYON_SERVER_ENABLED: + instance_data["folderPath"] = asset_name + else: + instance_data["asset"] = asset_name + asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( layer.name(), instance_data["task"], diff --git a/openpype/hosts/maya/plugins/create/create_review.py b/openpype/hosts/maya/plugins/create/create_review.py index f60e2406bc..18d661b186 100644 --- a/openpype/hosts/maya/plugins/create/create_review.py +++ b/openpype/hosts/maya/plugins/create/create_review.py @@ -2,6 +2,7 @@ import json from maya import cmds +from openpype import AYON_SERVER_ENABLED from openpype.hosts.maya.api import ( lib, plugin @@ -43,7 +44,11 @@ class CreateReview(plugin.MayaCreator): members = cmds.ls(selection=True) project_name = self.project_name - asset_doc = get_asset_by_name(project_name, instance_data["asset"]) + if AYON_SERVER_ENABLED: + asset_name = instance_data["folderPath"] + else: + asset_name = instance_data["asset"] + asset_doc = get_asset_by_name(project_name, asset_name) task_name = instance_data["task"] preset = lib.get_capture_preset( task_name, diff --git a/openpype/hosts/maya/plugins/create/create_workfile.py b/openpype/hosts/maya/plugins/create/create_workfile.py index d84753cd7f..74629776af 100644 --- a/openpype/hosts/maya/plugins/create/create_workfile.py +++ b/openpype/hosts/maya/plugins/create/create_workfile.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- """Creator plugin for creating workfiles.""" +from openpype import AYON_SERVER_ENABLED from openpype.pipeline import CreatedInstance, AutoCreator -from openpype.client import get_asset_by_name +from openpype.client import get_asset_by_name, get_asset_name_identifier from openpype.hosts.maya.api import plugin from maya import cmds @@ -29,16 +30,27 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name + current_instance_asset = None + if current_instance is not None: + if AYON_SERVER_ENABLED: + current_instance_asset = current_instance.get("folderPath") + if not current_instance_asset: + current_instance_asset = current_instance.get("asset") + if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( variant, task_name, asset_doc, project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name + data.update( self.get_dynamic_data( variant, task_name, asset_doc, @@ -50,14 +62,16 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): ) self._add_instance_to_context(current_instance) elif ( - current_instance["asset"] != asset_name - or current_instance["task"] != task_name + current_instance_asset != asset_name + or current_instance["task"] != task_name ): # Update instance context if is not the same asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( variant, task_name, asset_doc, project_name, host_name ) + asset_name = get_asset_name_identifier(asset_doc) + current_instance["asset"] = asset_name current_instance["task"] = task_name current_instance["subset"] = subset_name diff --git a/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py b/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py index 58fa9d02bd..42d3dc3ac8 100644 --- a/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py +++ b/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py @@ -102,7 +102,8 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin, cl_r = re.compile(regex_collision) - mesh_name = "{}{}".format(instance.data["asset"], + asset_name = instance.data["assetEntity"]["name"] + mesh_name = "{}{}".format(asset_name, instance.data.get("variant", [])) for obj in collision_set: From 82b1e0b205428dd0496be71bb269bd7d179b67c1 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:12:08 +0200 Subject: [PATCH 115/690] modified houdini to follow new asset naming --- .../houdini/plugins/create/create_workfile.py | 23 +++++++++--- .../plugins/publish/collect_usd_bootstrap.py | 35 ++++++++++++------- .../plugins/publish/validate_subset_name.py | 10 +++--- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/openpype/hosts/houdini/plugins/create/create_workfile.py b/openpype/hosts/houdini/plugins/create/create_workfile.py index cc45a6c2a8..04a844bdf5 100644 --- a/openpype/hosts/houdini/plugins/create/create_workfile.py +++ b/openpype/hosts/houdini/plugins/create/create_workfile.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- """Creator plugin for creating workfiles.""" +from openpype import AYON_SERVER_ENABLED from openpype.hosts.houdini.api import plugin from openpype.hosts.houdini.api.lib import read, imprint from openpype.hosts.houdini.api.pipeline import CONTEXT_CONTAINER @@ -30,16 +31,27 @@ class CreateWorkfile(plugin.HoudiniCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.host_name + current_instance_asset = None + if current_instance is not None: + if AYON_SERVER_ENABLED: + current_instance_asset = current_instance.get("folderPath") + if not current_instance_asset: + current_instance_asset = current_instance.get("asset") + if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( variant, task_name, asset_doc, project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": variant } + if AYON_SERVER_ENABLED: + data["folderpath"] = asset_name + else: + data["asset"] = asset_name + data.update( self.get_dynamic_data( variant, task_name, asset_doc, @@ -51,15 +63,18 @@ class CreateWorkfile(plugin.HoudiniCreatorBase, AutoCreator): ) self._add_instance_to_context(current_instance) elif ( - current_instance["asset"] != asset_name - or current_instance["task"] != task_name + current_instance_asset != asset_name + or current_instance["task"] != task_name ): # Update instance context if is not the same asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( variant, task_name, asset_doc, project_name, host_name ) - current_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + current_instance["folderPath"] = asset_name + else: + current_instance["asset"] = asset_name current_instance["task"] = task_name current_instance["subset"] = subset_name diff --git a/openpype/hosts/houdini/plugins/publish/collect_usd_bootstrap.py b/openpype/hosts/houdini/plugins/publish/collect_usd_bootstrap.py index 14a8e3c056..462cf99b9c 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_usd_bootstrap.py +++ b/openpype/hosts/houdini/plugins/publish/collect_usd_bootstrap.py @@ -1,6 +1,10 @@ import pyblish.api -from openpype.client import get_subset_by_name, get_asset_by_name +from openpype.client import ( + get_subset_by_name, + get_asset_by_name, + get_asset_name_identifier, +) import openpype.lib.usdlib as usdlib @@ -51,8 +55,9 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): self.log.debug("Add bootstrap for: %s" % bootstrap) project_name = instance.context.data["projectName"] - asset = get_asset_by_name(project_name, instance.data["asset"]) - assert asset, "Asset must exist: %s" % asset + asset_name = instance.data["asset"] + asset_doc = get_asset_by_name(project_name, asset_name) + assert asset_doc, "Asset must exist: %s" % asset_name # Check which are not about to be created and don't exist yet required = {"shot": ["usdShot"], "asset": ["usdAsset"]}.get(bootstrap) @@ -67,19 +72,21 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): required += list(layers) self.log.debug("Checking required bootstrap: %s" % required) - for subset in required: - if self._subset_exists(project_name, instance, subset, asset): + for subset_name in required: + if self._subset_exists( + project_name, instance, subset_name, asset_doc + ): continue self.log.debug( "Creating {0} USD bootstrap: {1} {2}".format( - bootstrap, asset["name"], subset + bootstrap, asset_name, subset_name ) ) - new = instance.context.create_instance(subset) - new.data["subset"] = subset - new.data["label"] = "{0} ({1})".format(subset, asset["name"]) + new = instance.context.create_instance(subset_name) + new.data["subset"] = subset_name + new.data["label"] = "{0} ({1})".format(subset_name, asset_name) new.data["family"] = "usd.bootstrap" new.data["comment"] = "Automated bootstrap USD file." new.data["publishFamilies"] = ["usd"] @@ -91,21 +98,23 @@ class CollectUsdBootstrap(pyblish.api.InstancePlugin): for key in ["asset"]: new.data[key] = instance.data[key] - def _subset_exists(self, project_name, instance, subset, asset): + def _subset_exists(self, project_name, instance, subset_name, asset_doc): """Return whether subset exists in current context or in database.""" # Allow it to be created during this publish session context = instance.context + + asset_doc_name = get_asset_name_identifier(asset_doc) for inst in context: if ( - inst.data["subset"] == subset - and inst.data["asset"] == asset["name"] + inst.data["subset"] == subset_name + and inst.data["asset"] == asset_doc_name ): return True # Or, if they already exist in the database we can # skip them too. if get_subset_by_name( - project_name, subset, asset["_id"], fields=["_id"] + project_name, subset_name, asset_doc["_id"], fields=["_id"] ): return True return False diff --git a/openpype/hosts/houdini/plugins/publish/validate_subset_name.py b/openpype/hosts/houdini/plugins/publish/validate_subset_name.py index bb3648f361..7bed74ebb1 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_subset_name.py +++ b/openpype/hosts/houdini/plugins/publish/validate_subset_name.py @@ -54,12 +54,13 @@ class ValidateSubsetName(pyblish.api.InstancePlugin, rop_node = hou.node(instance.data["instance_node"]) # Check subset name + asset_doc = instance.data["assetEntity"] subset_name = get_subset_name( family=instance.data["family"], variant=instance.data["variant"], task_name=instance.data["task"], - asset_doc=instance.data["assetEntity"], - dynamic_data={"asset": instance.data["asset"]} + asset_doc=asset_doc, + dynamic_data={"asset": asset_doc["name"]} ) if instance.data.get("subset") != subset_name: @@ -76,12 +77,13 @@ class ValidateSubsetName(pyblish.api.InstancePlugin, rop_node = hou.node(instance.data["instance_node"]) # Check subset name + asset_doc = instance.data["assetEntity"] subset_name = get_subset_name( family=instance.data["family"], variant=instance.data["variant"], task_name=instance.data["task"], - asset_doc=instance.data["assetEntity"], - dynamic_data={"asset": instance.data["asset"]} + asset_doc=asset_doc, + dynamic_data={"asset": asset_doc["name"]} ) instance.data["subset"] = subset_name From 23c41fe12aedeedd567cd9d290e243a5871c07bf Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:13:00 +0200 Subject: [PATCH 116/690] modified photoshop to follow new 'asset' name usage --- openpype/hosts/photoshop/lib.py | 22 ++++++++++++++++--- .../plugins/create/create_flatten_image.py | 22 +++++++++++++++---- .../plugins/publish/collect_auto_image.py | 3 ++- .../plugins/publish/collect_auto_review.py | 4 +++- .../plugins/publish/collect_auto_workfile.py | 3 ++- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/photoshop/lib.py b/openpype/hosts/photoshop/lib.py index 9f603a70d2..654528410a 100644 --- a/openpype/hosts/photoshop/lib.py +++ b/openpype/hosts/photoshop/lib.py @@ -1,5 +1,6 @@ import re +from openpype import AYON_SERVER_ENABLED import openpype.hosts.photoshop.api as api from openpype.client import get_asset_by_name from openpype.lib import prepare_template_data @@ -43,6 +44,15 @@ class PSAutoCreator(AutoCreator): asset_name = context.get_current_asset_name() task_name = context.get_current_task_name() host_name = context.host_name + + existing_instance_asset = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance.get("folderPath") + + if not existing_instance_asset: + existing_instance_asset = existing_instance.get("asset") + if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -50,10 +60,13 @@ class PSAutoCreator(AutoCreator): project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name data.update(self.get_dynamic_data( self.default_variant, task_name, asset_doc, project_name, host_name, None @@ -70,7 +83,7 @@ class PSAutoCreator(AutoCreator): new_instance.data_to_store()) elif ( - existing_instance["asset"] != asset_name + existing_instance_asset != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -78,7 +91,10 @@ class PSAutoCreator(AutoCreator): self.default_variant, task_name, asset_doc, project_name, host_name ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/photoshop/plugins/create/create_flatten_image.py b/openpype/hosts/photoshop/plugins/create/create_flatten_image.py index afde77fdb4..942f8f4989 100644 --- a/openpype/hosts/photoshop/plugins/create/create_flatten_image.py +++ b/openpype/hosts/photoshop/plugins/create/create_flatten_image.py @@ -1,5 +1,6 @@ from openpype.pipeline import CreatedInstance +from openpype import AYON_SERVER_ENABLED from openpype.lib import BoolDef import openpype.hosts.photoshop.api as api from openpype.hosts.photoshop.lib import PSAutoCreator, clean_subset_name @@ -37,6 +38,14 @@ class AutoImageCreator(PSAutoCreator): host_name = context.host_name asset_doc = get_asset_by_name(project_name, asset_name) + existing_instance_asset = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance.get("folderPath") + + if not existing_instance_asset: + existing_instance_asset = existing_instance.get("asset") + if existing_instance is None: subset_name = self.get_subset_name( self.default_variant, task_name, asset_doc, @@ -44,9 +53,12 @@ class AutoImageCreator(PSAutoCreator): ) data = { - "asset": asset_name, "task": task_name, } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name if not self.active_on_create: data["active"] = False @@ -62,15 +74,17 @@ class AutoImageCreator(PSAutoCreator): new_instance.data_to_store()) elif ( # existing instance from different context - existing_instance["asset"] != asset_name + existing_instance_asset != asset_name or existing_instance["task"] != task_name ): subset_name = self.get_subset_name( self.default_variant, task_name, asset_doc, project_name, host_name ) - - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/photoshop/plugins/publish/collect_auto_image.py b/openpype/hosts/photoshop/plugins/publish/collect_auto_image.py index 77f1a3e91f..038ae9ff6c 100644 --- a/openpype/hosts/photoshop/plugins/publish/collect_auto_image.py +++ b/openpype/hosts/photoshop/plugins/publish/collect_auto_image.py @@ -1,5 +1,6 @@ import pyblish.api +from openpype.client import get_asset_name_identifier from openpype.hosts.photoshop import api as photoshop from openpype.pipeline.create import get_subset_name @@ -27,7 +28,7 @@ class CollectAutoImage(pyblish.api.ContextPlugin): task_name = context.data["anatomyData"]["task"]["name"] host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) auto_creator = proj_settings.get( "photoshop", {}).get( diff --git a/openpype/hosts/photoshop/plugins/publish/collect_auto_review.py b/openpype/hosts/photoshop/plugins/publish/collect_auto_review.py index 82ba0ac09c..37e9e8bae8 100644 --- a/openpype/hosts/photoshop/plugins/publish/collect_auto_review.py +++ b/openpype/hosts/photoshop/plugins/publish/collect_auto_review.py @@ -7,6 +7,7 @@ Provides: """ import pyblish.api +from openpype.client import get_asset_name_identifier from openpype.hosts.photoshop import api as photoshop from openpype.pipeline.create import get_subset_name @@ -65,7 +66,8 @@ class CollectAutoReview(pyblish.api.ContextPlugin): task_name = context.data["anatomyData"]["task"]["name"] host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = asset_doc["name"] + + asset_name = get_asset_name_identifier(asset_doc) subset_name = get_subset_name( family, diff --git a/openpype/hosts/photoshop/plugins/publish/collect_auto_workfile.py b/openpype/hosts/photoshop/plugins/publish/collect_auto_workfile.py index 01dc50af40..be5a641d51 100644 --- a/openpype/hosts/photoshop/plugins/publish/collect_auto_workfile.py +++ b/openpype/hosts/photoshop/plugins/publish/collect_auto_workfile.py @@ -1,6 +1,7 @@ import os import pyblish.api +from openpype.client import get_asset_name_identifier from openpype.hosts.photoshop import api as photoshop from openpype.pipeline.create import get_subset_name @@ -69,8 +70,8 @@ class CollectAutoWorkfile(pyblish.api.ContextPlugin): task_name = context.data["anatomyData"]["task"]["name"] host_name = context.data["hostName"] asset_doc = context.data["assetEntity"] - asset_name = asset_doc["name"] + asset_name = get_asset_name_identifier(asset_doc) subset_name = get_subset_name( family, variant, From 7c7f9f175c041292e8a11306763a0863cc6bae95 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:13:23 +0200 Subject: [PATCH 117/690] modified substance to follow new 'asset' usage --- .../plugins/create/create_workfile.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/substancepainter/plugins/create/create_workfile.py b/openpype/hosts/substancepainter/plugins/create/create_workfile.py index d7f31f9dcf..8aa696f11d 100644 --- a/openpype/hosts/substancepainter/plugins/create/create_workfile.py +++ b/openpype/hosts/substancepainter/plugins/create/create_workfile.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin for creating workfiles.""" +from openpype import AYON_SERVER_ENABLED from openpype.pipeline import CreatedInstance, AutoCreator from openpype.client import get_asset_by_name @@ -41,6 +42,13 @@ class CreateWorkfile(AutoCreator): if instance.creator_identifier == self.identifier ), None) + current_instance_asset = None + if current_instance is not None: + if AYON_SERVER_ENABLED: + current_instance_asset = current_instance.get("folderPath") + if not current_instance_asset: + current_instance_asset = current_instance.get("asset") + if current_instance is None: self.log.info("Auto-creating workfile instance...") asset_doc = get_asset_by_name(project_name, asset_name) @@ -48,22 +56,28 @@ class CreateWorkfile(AutoCreator): variant, task_name, asset_doc, project_name, host_name ) data = { - "asset": asset_name, "task": task_name, "variant": variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name current_instance = self.create_instance_in_context(subset_name, data) elif ( - current_instance["asset"] != asset_name - or current_instance["task"] != task_name + current_instance_asset != asset_name + or current_instance["task"] != task_name ): # Update instance context if is not the same asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( variant, task_name, asset_doc, project_name, host_name ) - current_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + current_instance["folderPath"] = asset_name + else: + current_instance["asset"] = asset_name current_instance["task"] = task_name current_instance["subset"] = subset_name From 7d366371a5eec266083721b1ac651813103978fb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:17:35 +0200 Subject: [PATCH 118/690] modified most of code in traypublisher to follow new asset usage --- openpype/hosts/traypublisher/api/plugin.py | 11 ++++++++--- .../plugins/create/create_colorspace_look.py | 7 ++++++- .../traypublisher/plugins/create/create_editorial.py | 6 +++++- .../plugins/create/create_movie_batch.py | 9 ++++++++- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/traypublisher/api/plugin.py b/openpype/hosts/traypublisher/api/plugin.py index 36e041a32c..14c66fa08f 100644 --- a/openpype/hosts/traypublisher/api/plugin.py +++ b/openpype/hosts/traypublisher/api/plugin.py @@ -1,7 +1,9 @@ +from openpype import AYON_SERVER_ENABLED from openpype.client import ( get_assets, get_subsets, get_last_versions, + get_asset_name_identifier, ) from openpype.lib.attribute_definitions import ( FileDef, @@ -114,7 +116,10 @@ class SettingsCreator(TrayPublishCreator): # Fill 'version_to_use' if version control is enabled if self.allow_version_control: - asset_name = data["asset"] + if AYON_SERVER_ENABLED: + asset_name = data["folderPath"] + else: + asset_name = data["asset"] subset_docs_by_asset_id = self._prepare_next_versions( [asset_name], [subset_name]) version = subset_docs_by_asset_id[asset_name].get(subset_name) @@ -162,10 +167,10 @@ class SettingsCreator(TrayPublishCreator): asset_docs = get_assets( self.project_name, asset_names=asset_names, - fields=["_id", "name"] + fields=["_id", "name", "data.parents"] ) asset_names_by_id = { - asset_doc["_id"]: asset_doc["name"] + asset_doc["_id"]: get_asset_name_identifier(asset_doc) for asset_doc in asset_docs } subset_docs = list(get_subsets( diff --git a/openpype/hosts/traypublisher/plugins/create/create_colorspace_look.py b/openpype/hosts/traypublisher/plugins/create/create_colorspace_look.py index 5628d0973f..ac4c72a0ce 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_colorspace_look.py +++ b/openpype/hosts/traypublisher/plugins/create/create_colorspace_look.py @@ -6,6 +6,7 @@ production type `ociolook`. All files are published as representation. """ from pathlib import Path +from openpype import AYON_SERVER_ENABLED from openpype.client import get_asset_by_name from openpype.lib.attribute_definitions import ( FileDef, EnumDef, TextDef, UISeparatorDef @@ -54,8 +55,12 @@ This creator publishes color space look file (LUT). # this should never happen raise CreatorError("Missing files from representation") + if AYON_SERVER_ENABLED: + asset_name = instance_data["folderPath"] + else: + asset_name = instance_data["asset"] asset_doc = get_asset_by_name( - self.project_name, instance_data["asset"]) + self.project_name, asset_name) subset_name = self.get_subset_name( variant=instance_data["variant"], diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 8640500b18..23cf066362 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -1,6 +1,7 @@ import os from copy import deepcopy import opentimelineio as otio +from openpype import AYON_SERVER_ENABLED from openpype.client import ( get_asset_by_name, get_project @@ -215,7 +216,10 @@ or updating already created. Publishing will create OTIO file. ] } # Create otio editorial instance - asset_name = instance_data["asset"] + if AYON_SERVER_ENABLED: + asset_name = instance_data["folderPath"] + else: + asset_name = instance_data["asset"] asset_doc = get_asset_by_name(self.project_name, asset_name) if pre_create_data["fps"] == "from_selection": diff --git a/openpype/hosts/traypublisher/plugins/create/create_movie_batch.py b/openpype/hosts/traypublisher/plugins/create/create_movie_batch.py index 3454b6e135..8fa65c7fff 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_movie_batch.py +++ b/openpype/hosts/traypublisher/plugins/create/create_movie_batch.py @@ -2,6 +2,8 @@ import copy import os import re +from openpype import AYON_SERVER_ENABLED +from openpype.client import get_asset_name_identifier from openpype.lib import ( FileDef, BoolDef, @@ -64,8 +66,13 @@ class BatchMovieCreator(TrayPublishCreator): subset_name, task_name = self._get_subset_and_task( asset_doc, data["variant"], self.project_name) + asset_name = get_asset_name_identifier(asset_doc) + instance_data["task"] = task_name - instance_data["asset"] = asset_doc["name"] + if AYON_SERVER_ENABLED: + instance_data["folderPath"] = asset_name + else: + instance_data["asset"] = asset_name # Create new instance new_instance = CreatedInstance(self.family, subset_name, From 8360c321bdf3713df75a7b0225d4cb59ac22b02f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:39:04 +0200 Subject: [PATCH 119/690] modified tvpaint to use new 'asset' handling --- .../tvpaint/plugins/create/create_render.py | 54 +++++++++++++++---- .../tvpaint/plugins/create/create_review.py | 21 ++++++-- .../tvpaint/plugins/create/create_workfile.py | 20 +++++-- .../plugins/publish/validate_asset_name.py | 12 ++++- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/openpype/hosts/tvpaint/plugins/create/create_render.py b/openpype/hosts/tvpaint/plugins/create/create_render.py index b7a7c208d9..667103432e 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_render.py +++ b/openpype/hosts/tvpaint/plugins/create/create_render.py @@ -37,7 +37,8 @@ Todos: import collections from typing import Any, Optional, Union -from openpype.client import get_asset_by_name +from openpype import AYON_SERVER_ENABLED +from openpype.client import get_asset_by_name, get_asset_name_identifier from openpype.lib import ( prepare_template_data, AbstractAttrDef, @@ -784,18 +785,25 @@ class TVPaintAutoDetectRenderCreator(TVPaintCreator): project_name, host_name=self.create_context.host_name, ) + asset_name = get_asset_name_identifier(asset_doc) if existing_instance is not None: - existing_instance["asset"] = asset_doc["name"] + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name return existing_instance instance_data: dict[str, str] = { - "asset": asset_doc["name"], "task": task_name, "family": creator.family, "variant": variant } + if AYON_SERVER_ENABLED: + instance_data["folderPath"] = asset_name + else: + instance_data["asset"] = asset_name pre_create_data: dict[str, str] = { "group_id": group_id, "mark_for_review": mark_for_review @@ -820,6 +828,8 @@ class TVPaintAutoDetectRenderCreator(TVPaintCreator): for layer_name in render_pass["layer_names"]: render_pass_by_layer_name[layer_name] = render_pass + asset_name = get_asset_name_identifier(asset_doc) + for layer in layers: layer_name = layer["name"] variant = layer_name @@ -838,17 +848,25 @@ class TVPaintAutoDetectRenderCreator(TVPaintCreator): ) if render_pass is not None: - render_pass["asset"] = asset_doc["name"] + if AYON_SERVER_ENABLED: + render_pass["folderPath"] = asset_name + else: + render_pass["asset"] = asset_name + render_pass["task"] = task_name render_pass["subset"] = subset_name continue instance_data: dict[str, str] = { - "asset": asset_doc["name"], "task": task_name, "family": creator.family, "variant": variant } + if AYON_SERVER_ENABLED: + instance_data["folderPath"] = asset_name + else: + instance_data["asset"] = asset_name + pre_create_data: dict[str, Any] = { "render_layer_instance_id": render_layer_instance.id, "layer_names": [layer_name], @@ -882,9 +900,13 @@ class TVPaintAutoDetectRenderCreator(TVPaintCreator): def create(self, subset_name, instance_data, pre_create_data): project_name: str = self.create_context.get_current_project_name() - asset_name: str = instance_data["asset"] + if AYON_SERVER_ENABLED: + asset_name: str = instance_data["folderPath"] + else: + asset_name: str = instance_data["asset"] task_name: str = instance_data["task"] - asset_doc: dict[str, Any] = get_asset_by_name(project_name, asset_name) + asset_doc: dict[str, Any] = get_asset_by_name( + project_name, asset_name) render_layers_by_group_id: dict[int, CreatedInstance] = {} render_passes_by_render_layer_id: dict[int, list[CreatedInstance]] = ( @@ -1061,7 +1083,6 @@ class TVPaintSceneRenderCreator(TVPaintAutoCreator): host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant, "creator_attributes": { @@ -1073,6 +1094,10 @@ class TVPaintSceneRenderCreator(TVPaintAutoCreator): self.default_pass_name ) } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name if not self.active_on_create: data["active"] = False @@ -1101,8 +1126,14 @@ class TVPaintSceneRenderCreator(TVPaintAutoCreator): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() + existing_name = None + if AYON_SERVER_ENABLED: + existing_name = existing_instance.get("folderPath") + if existing_name is None: + existing_name = existing_instance["asset"] + if ( - existing_instance["asset"] != asset_name + existing_name != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -1114,7 +1145,10 @@ class TVPaintSceneRenderCreator(TVPaintAutoCreator): host_name, existing_instance ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/tvpaint/plugins/create/create_review.py b/openpype/hosts/tvpaint/plugins/create/create_review.py index 7bb7510a8e..265cef00ef 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_review.py +++ b/openpype/hosts/tvpaint/plugins/create/create_review.py @@ -1,3 +1,4 @@ +from openpype import AYON_SERVER_ENABLED from openpype.client import get_asset_by_name from openpype.pipeline import CreatedInstance from openpype.hosts.tvpaint.api.plugin import TVPaintAutoCreator @@ -33,6 +34,13 @@ class TVPaintReviewCreator(TVPaintAutoCreator): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() + existing_asset_name = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_asset_name = existing_instance.get("folderPath") + if existing_asset_name is None: + existing_asset_name = existing_instance.get("asset") + if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -43,10 +51,14 @@ class TVPaintReviewCreator(TVPaintAutoCreator): host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name + if not self.active_on_create: data["active"] = False @@ -59,7 +71,7 @@ class TVPaintReviewCreator(TVPaintAutoCreator): self._add_instance_to_context(new_instance) elif ( - existing_instance["asset"] != asset_name + existing_asset_name != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -71,6 +83,9 @@ class TVPaintReviewCreator(TVPaintAutoCreator): host_name, existing_instance ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/tvpaint/plugins/create/create_workfile.py b/openpype/hosts/tvpaint/plugins/create/create_workfile.py index c3982c0eca..eec0f8483f 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_workfile.py +++ b/openpype/hosts/tvpaint/plugins/create/create_workfile.py @@ -1,3 +1,4 @@ +from openpype import AYON_SERVER_ENABLED from openpype.client import get_asset_by_name from openpype.pipeline import CreatedInstance from openpype.hosts.tvpaint.api.plugin import TVPaintAutoCreator @@ -29,6 +30,13 @@ class TVPaintWorkfileCreator(TVPaintAutoCreator): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() + existing_asset_name = None + if existing_instance is not None: + if AYON_SERVER_ENABLED: + existing_asset_name = existing_instance.get("folderPath") + if existing_asset_name is None: + existing_asset_name = existing_instance.get("asset") + if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) subset_name = self.get_subset_name( @@ -39,10 +47,13 @@ class TVPaintWorkfileCreator(TVPaintAutoCreator): host_name ) data = { - "asset": asset_name, "task": task_name, "variant": self.default_variant } + if AYON_SERVER_ENABLED: + data["folderPath"] = asset_name + else: + data["asset"] = asset_name new_instance = CreatedInstance( self.family, subset_name, data, self @@ -53,7 +64,7 @@ class TVPaintWorkfileCreator(TVPaintAutoCreator): self._add_instance_to_context(new_instance) elif ( - existing_instance["asset"] != asset_name + existing_asset_name != asset_name or existing_instance["task"] != task_name ): asset_doc = get_asset_by_name(project_name, asset_name) @@ -65,6 +76,9 @@ class TVPaintWorkfileCreator(TVPaintAutoCreator): host_name, existing_instance ) - existing_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + existing_instance["folderPath"] = asset_name + else: + existing_instance["asset"] = asset_name existing_instance["task"] = task_name existing_instance["subset"] = subset_name diff --git a/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py b/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py index 9347960d3f..dc29e6c278 100644 --- a/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py +++ b/openpype/hosts/tvpaint/plugins/publish/validate_asset_name.py @@ -1,4 +1,5 @@ import pyblish.api +from openpype import AYON_SERVER_ENABLED from openpype.pipeline import ( PublishXmlValidationError, OptionalPyblishPluginMixin, @@ -24,12 +25,19 @@ class FixAssetNames(pyblish.api.Action): old_instance_items = list_instances() new_instance_items = [] for instance_item in old_instance_items: - instance_asset_name = instance_item.get("asset") + if AYON_SERVER_ENABLED: + instance_asset_name = instance_item.get("folderPath") + else: + instance_asset_name = instance_item.get("asset") + if ( instance_asset_name and instance_asset_name != context_asset_name ): - instance_item["asset"] = context_asset_name + if AYON_SERVER_ENABLED: + instance_item["folderPath"] = context_asset_name + else: + instance_item["asset"] = context_asset_name new_instance_items.append(instance_item) write_instances(new_instance_items) From 5ada46f2a05dc71b621a7cffe077cb9dcff0e997 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:41:37 +0200 Subject: [PATCH 120/690] modified some parts of hiero to follow new 'asset' handling --- openpype/hosts/hiero/api/plugin.py | 6 ++---- .../publish/collect_frame_tag_instances.py | 7 ++++++- .../plugins/publish/precollect_instances.py | 1 - .../plugins/publish/precollect_workfile.py | 17 ++++++++++------- .../collect_assetbuilds.py | 18 ++++++++++-------- 5 files changed, 28 insertions(+), 21 deletions(-) diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index 52f96261b2..0e0632e032 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -11,7 +11,6 @@ import qargparse from openpype.settings import get_current_project_settings from openpype.lib import Logger from openpype.pipeline import LoaderPlugin, LegacyCreator -from openpype.pipeline.context_tools import get_current_project_asset from openpype.pipeline.load import get_representation_path_from_context from . import lib @@ -494,9 +493,8 @@ class ClipLoader: joint `data` key with asset.data dict into the representation """ - asset_name = self.context["representation"]["context"]["asset"] - asset_doc = get_current_project_asset(asset_name) - log.debug("__ asset_doc: {}".format(pformat(asset_doc))) + + asset_doc = self.context["asset"] self.data["assetData"] = asset_doc["data"] def _make_track_item(self, source_bin_item, audio=False): diff --git a/openpype/hosts/hiero/plugins/publish/collect_frame_tag_instances.py b/openpype/hosts/hiero/plugins/publish/collect_frame_tag_instances.py index 982a34efd6..79bf67b336 100644 --- a/openpype/hosts/hiero/plugins/publish/collect_frame_tag_instances.py +++ b/openpype/hosts/hiero/plugins/publish/collect_frame_tag_instances.py @@ -5,6 +5,8 @@ import json import pyblish.api +from openpype.client import get_asset_name_identifier + class CollectFrameTagInstances(pyblish.api.ContextPlugin): """Collect frames from tags. @@ -99,6 +101,9 @@ class CollectFrameTagInstances(pyblish.api.ContextPlugin): # first collect all available subset tag frames subset_data = {} + context_asset_doc = context.data["assetEntity"] + context_asset_name = get_asset_name_identifier(context_asset_doc) + for tag_data in sequence_tags: frame = int(tag_data["start"]) @@ -115,7 +120,7 @@ class CollectFrameTagInstances(pyblish.api.ContextPlugin): subset_data[subset] = { "frames": [frame], "format": tag_data["format"], - "asset": context.data["assetEntity"]["name"] + "asset": context_asset_name } return subset_data diff --git a/openpype/hosts/hiero/plugins/publish/precollect_instances.py b/openpype/hosts/hiero/plugins/publish/precollect_instances.py index 3f9da2cf60..65b8fed49c 100644 --- a/openpype/hosts/hiero/plugins/publish/precollect_instances.py +++ b/openpype/hosts/hiero/plugins/publish/precollect_instances.py @@ -178,7 +178,6 @@ class PrecollectInstances(pyblish.api.ContextPlugin): def create_shot_instance(self, context, **data): master_layer = data.get("heroTrack") hierarchy_data = data.get("hierarchyData") - asset = data.get("asset") item = data.get("item") clip_name = item.name() diff --git a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py index 5a66581531..1d6bdc0257 100644 --- a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py @@ -7,6 +7,7 @@ from qtpy.QtGui import QPixmap import hiero.ui +from openpype import AYON_SERVER_ENABLED from openpype.hosts.hiero.api.otio import hiero_export @@ -17,9 +18,10 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.491 def process(self, context): + asset_name = context.data["asset"] + if AYON_SERVER_ENABLED: + asset_name = asset_name.split("/")[-1] - asset = context.data["asset"] - subset = "workfile" active_timeline = hiero.ui.activeSequence() project = active_timeline.project() fps = active_timeline.framerate().toFloat() @@ -59,13 +61,14 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): 'files': base_name, "stagingDir": staging_dir, } - + family = "workfile" instance_data = { - "name": "{}_{}".format(asset, subset), - "asset": asset, - "subset": "{}{}".format(asset, subset.capitalize()), + "name": "{}_{}".format(asset_name, family), + "asset": context.data["asset"], + # TODO use 'get_subset_name' + "subset": "{}{}".format(asset_name, family.capitalize()), "item": project, - "family": "workfile", + "family": family, "families": [], "representations": [workfile_representation, thumb_representation] } diff --git a/openpype/hosts/hiero/plugins/publish_old_workflow/collect_assetbuilds.py b/openpype/hosts/hiero/plugins/publish_old_workflow/collect_assetbuilds.py index 767f7c30f7..37370497a5 100644 --- a/openpype/hosts/hiero/plugins/publish_old_workflow/collect_assetbuilds.py +++ b/openpype/hosts/hiero/plugins/publish_old_workflow/collect_assetbuilds.py @@ -1,5 +1,6 @@ from pyblish import api -from openpype.client import get_assets + +from openpype.client import get_assets, get_asset_name_identifier class CollectAssetBuilds(api.ContextPlugin): @@ -19,10 +20,13 @@ class CollectAssetBuilds(api.ContextPlugin): def process(self, context): project_name = context.data["projectName"] asset_builds = {} - for asset in get_assets(project_name): - if asset["data"]["entityType"] == "AssetBuild": - self.log.debug("Found \"{}\" in database.".format(asset)) - asset_builds[asset["name"]] = asset + for asset_doc in get_assets(project_name): + if asset_doc["data"].get("entityType") != "AssetBuild": + continue + + asset_name = get_asset_name_identifier(asset_doc) + self.log.debug("Found \"{}\" in database.".format(asset_doc)) + asset_builds[asset_name] = asset_doc for instance in context: if instance.data["family"] != "clip": @@ -50,9 +54,7 @@ class CollectAssetBuilds(api.ContextPlugin): # Collect asset builds. data = {"assetbuilds": []} for name in asset_names: - data["assetbuilds"].append( - asset_builds[name] - ) + data["assetbuilds"].append(asset_builds[name]) self.log.debug( "Found asset builds: {}".format(data["assetbuilds"]) ) From 51bebd0f1e24264e72358d58ef55f77062aaba3b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:42:14 +0200 Subject: [PATCH 121/690] modified part of flame to follow new 'asset' naming --- .../hosts/flame/plugins/publish/collect_timeline_otio.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/flame/plugins/publish/collect_timeline_otio.py b/openpype/hosts/flame/plugins/publish/collect_timeline_otio.py index f8cfa9e963..20ac048986 100644 --- a/openpype/hosts/flame/plugins/publish/collect_timeline_otio.py +++ b/openpype/hosts/flame/plugins/publish/collect_timeline_otio.py @@ -1,5 +1,6 @@ import pyblish.api +from openpype.client import get_asset_name_identifier import openpype.hosts.flame.api as opfapi from openpype.hosts.flame.otio import flame_export from openpype.pipeline.create import get_subset_name @@ -33,13 +34,15 @@ class CollecTimelineOTIO(pyblish.api.ContextPlugin): project_settings=context.data["project_settings"] ) + asset_name = get_asset_name_identifier(asset_doc) + # adding otio timeline to context with opfapi.maintained_segment_selection(sequence) as selected_seg: otio_timeline = flame_export.create_otio_timeline(sequence) instance_data = { "name": subset_name, - "asset": asset_doc["name"], + "asset": asset_name, "subset": subset_name, "family": "workfile", "families": [] From 9d617db64cac3e06ea373e05511bce4fc0728c19 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:46:35 +0200 Subject: [PATCH 122/690] use only folder name to create instance name --- .../hosts/resolve/plugins/publish/precollect_workfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py index a2f3eaed7a..28b2350f01 100644 --- a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py @@ -15,6 +15,8 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): def process(self, context): asset = get_current_asset_name() + # AYON compatibility split name and use last piece + _asset_name = asset.split("/")[-1] subset = "workfile" project = rapi.get_current_project() fps = project.GetSetting("timelineFrameRate") @@ -24,9 +26,9 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): otio_timeline = davinci_export.create_otio_timeline(project) instance_data = { - "name": "{}_{}".format(asset, subset), + "name": "{}_{}".format(_asset_name, subset), "asset": asset, - "subset": "{}{}".format(asset, subset.capitalize()), + "subset": "{}{}".format(_asset_name, subset.capitalize()), "item": project, "family": "workfile", "families": [] From e34c0b9ecd1505657969676bb0d9a062498c6c52 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 24 Oct 2023 18:50:54 +0200 Subject: [PATCH 123/690] avoid unnecessary call to database --- openpype/hosts/resolve/api/plugin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 8381f81acb..a3d533d3d7 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -1,10 +1,11 @@ import re import uuid +import copy + import qargparse from qtpy import QtWidgets, QtCore from openpype.settings import get_current_project_settings -from openpype.pipeline.context_tools import get_current_project_asset from openpype.pipeline import ( LegacyCreator, LoaderPlugin, @@ -379,8 +380,8 @@ class ClipLoader: joint `data` key with asset.data dict into the representation """ - asset_name = self.context["representation"]["context"]["asset"] - self.data["assetData"] = get_current_project_asset(asset_name)["data"] + + self.data["assetData"] = copy.deepcopy(self.context["asset"]["data"]) def load(self, files): """Load clip into timeline From 053cc44891343624d73de6a03ed3c560103ff118 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 25 Oct 2023 11:40:26 +0200 Subject: [PATCH 124/690] removed unnecessary line --- openpype/client/server/entities.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index c1e27eabb9..c735c558d5 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -183,7 +183,6 @@ def get_asset_by_name(project_name, asset_name, fields=None): return None - def _folders_query(project_name, con, fields, **kwargs): if fields is None or "tasks" in fields: folders = get_folders_with_tasks( From 7942e33a117e487d5d86c15e8d919fc5dc947ff6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 25 Oct 2023 12:01:58 +0200 Subject: [PATCH 125/690] be expicit about source of asset and folder path --- .../hosts/fusion/plugins/create/create_workfile.py | 14 ++++++-------- .../houdini/plugins/create/create_workfile.py | 12 ++++++------ .../hosts/maya/plugins/create/create_workfile.py | 12 ++++++------ .../plugins/create/create_flatten_image.py | 13 ++++++------- .../plugins/create/create_workfile.py | 12 ++++++------ 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/openpype/hosts/fusion/plugins/create/create_workfile.py b/openpype/hosts/fusion/plugins/create/create_workfile.py index 8063e56413..4092086ea4 100644 --- a/openpype/hosts/fusion/plugins/create/create_workfile.py +++ b/openpype/hosts/fusion/plugins/create/create_workfile.py @@ -69,14 +69,12 @@ class FusionWorkfileCreator(AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name - existing_instance_asset = None - if existing_instance is not None: - if AYON_SERVER_ENABLED: - existing_instance_asset = existing_instance.data.get( - "folderPath") - - if not existing_instance_asset: - existing_instance_asset = existing_instance.data.get("asset") + if existing_instance is None: + existing_instance_asset = None + elif AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance["folderPath"] + else: + existing_instance_asset = existing_instance["asset"] if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) diff --git a/openpype/hosts/houdini/plugins/create/create_workfile.py b/openpype/hosts/houdini/plugins/create/create_workfile.py index 04a844bdf5..f8ee68ebc9 100644 --- a/openpype/hosts/houdini/plugins/create/create_workfile.py +++ b/openpype/hosts/houdini/plugins/create/create_workfile.py @@ -31,12 +31,12 @@ class CreateWorkfile(plugin.HoudiniCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.host_name - current_instance_asset = None - if current_instance is not None: - if AYON_SERVER_ENABLED: - current_instance_asset = current_instance.get("folderPath") - if not current_instance_asset: - current_instance_asset = current_instance.get("asset") + if current_instance is None: + current_instance_asset = None + elif AYON_SERVER_ENABLED: + current_instance_asset = current_instance["folderPath"] + else: + current_instance_asset = current_instance["asset"] if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) diff --git a/openpype/hosts/maya/plugins/create/create_workfile.py b/openpype/hosts/maya/plugins/create/create_workfile.py index 74629776af..7282fc6b8b 100644 --- a/openpype/hosts/maya/plugins/create/create_workfile.py +++ b/openpype/hosts/maya/plugins/create/create_workfile.py @@ -30,12 +30,12 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): task_name = self.create_context.get_current_task_name() host_name = self.create_context.host_name - current_instance_asset = None - if current_instance is not None: - if AYON_SERVER_ENABLED: - current_instance_asset = current_instance.get("folderPath") - if not current_instance_asset: - current_instance_asset = current_instance.get("asset") + if current_instance is None: + current_instance_asset = None + elif AYON_SERVER_ENABLED: + current_instance_asset = current_instance["folderPath"] + else: + current_instance_asset = current_instance["asset"] if current_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) diff --git a/openpype/hosts/photoshop/plugins/create/create_flatten_image.py b/openpype/hosts/photoshop/plugins/create/create_flatten_image.py index 942f8f4989..24be9df0e0 100644 --- a/openpype/hosts/photoshop/plugins/create/create_flatten_image.py +++ b/openpype/hosts/photoshop/plugins/create/create_flatten_image.py @@ -38,13 +38,12 @@ class AutoImageCreator(PSAutoCreator): host_name = context.host_name asset_doc = get_asset_by_name(project_name, asset_name) - existing_instance_asset = None - if existing_instance is not None: - if AYON_SERVER_ENABLED: - existing_instance_asset = existing_instance.get("folderPath") - - if not existing_instance_asset: - existing_instance_asset = existing_instance.get("asset") + if existing_instance is None: + existing_instance_asset = None + elif AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance["folderPath"] + else: + existing_instance_asset = existing_instance["asset"] if existing_instance is None: subset_name = self.get_subset_name( diff --git a/openpype/hosts/substancepainter/plugins/create/create_workfile.py b/openpype/hosts/substancepainter/plugins/create/create_workfile.py index 8aa696f11d..c73277e405 100644 --- a/openpype/hosts/substancepainter/plugins/create/create_workfile.py +++ b/openpype/hosts/substancepainter/plugins/create/create_workfile.py @@ -42,12 +42,12 @@ class CreateWorkfile(AutoCreator): if instance.creator_identifier == self.identifier ), None) - current_instance_asset = None - if current_instance is not None: - if AYON_SERVER_ENABLED: - current_instance_asset = current_instance.get("folderPath") - if not current_instance_asset: - current_instance_asset = current_instance.get("asset") + if current_instance is None: + current_instance_asset = None + elif AYON_SERVER_ENABLED: + current_instance_asset = current_instance["folderPath"] + else: + current_instance_asset = current_instance["asset"] if current_instance is None: self.log.info("Auto-creating workfile instance...") From a12d599b442540a46b88212fcdc873ad1c85db46 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Wed, 25 Oct 2023 14:04:00 +0200 Subject: [PATCH 126/690] change creator labels --- openpype/hosts/blender/plugins/create/create_action.py | 2 +- openpype/hosts/blender/plugins/create/create_animation.py | 2 +- openpype/hosts/blender/plugins/create/create_camera.py | 2 +- openpype/hosts/blender/plugins/create/create_layout.py | 2 +- openpype/hosts/blender/plugins/create/create_model.py | 2 +- openpype/hosts/blender/plugins/create/create_pointcache.py | 2 +- openpype/hosts/blender/plugins/create/create_review.py | 2 +- openpype/hosts/blender/plugins/create/create_rig.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index d766fce038..e7b689c54e 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -38,7 +38,7 @@ class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 88ae9e5996..8b4214ceda 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -58,7 +58,7 @@ class CreateAnimation(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 026b5739d6..4747e50b2e 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -56,7 +56,7 @@ class CreateCamera(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index f46ae58a43..0c97d57af3 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -55,7 +55,7 @@ class CreateLayout(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 069b78626b..3c8e9c4900 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -55,7 +55,7 @@ class CreateModel(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 3054b81ef5..a40bd5af61 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -38,7 +38,7 @@ class CreatePointcache(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 10a96c94fd..8c9a8d5927 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -54,7 +54,7 @@ class CreateReview(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 8daffe638d..110a9f5c8e 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -55,7 +55,7 @@ class CreateRig(plugin.BlenderCreator): { "id": "pyblish.avalon.instance", "creator_identifier": self.identifier, - "label": self.label, + "label": subset_name, "task": get_current_task_name(), "subset": subset_name, "instance_node": instance_node, From c3ae2a3a09bdd72824f950682faf418931651ff7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 25 Oct 2023 15:20:28 +0200 Subject: [PATCH 127/690] be expicit about source of asset and folder path in photoshop --- openpype/hosts/photoshop/lib.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/photoshop/lib.py b/openpype/hosts/photoshop/lib.py index 654528410a..5c8dff947d 100644 --- a/openpype/hosts/photoshop/lib.py +++ b/openpype/hosts/photoshop/lib.py @@ -45,13 +45,12 @@ class PSAutoCreator(AutoCreator): task_name = context.get_current_task_name() host_name = context.host_name - existing_instance_asset = None - if existing_instance is not None: - if AYON_SERVER_ENABLED: - existing_instance_asset = existing_instance.get("folderPath") - - if not existing_instance_asset: - existing_instance_asset = existing_instance.get("asset") + if existing_instance is None: + existing_instance_asset = None + elif AYON_SERVER_ENABLED: + existing_instance_asset = existing_instance["folderPath"] + else: + existing_instance_asset = existing_instance["asset"] if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) From 803fb616492f5e34feec7a3a3bdd7e7599dcc8d8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 25 Oct 2023 22:31:27 +0800 Subject: [PATCH 128/690] validate loaded plugins tweaks in 3dsmax --- .../plugins/publish/validate_loaded_plugin.py | 69 +++++++++++++++++++ .../plugins/publish/validate_usd_plugin.py | 49 ------------- .../defaults/project_settings/max.json | 5 ++ .../schemas/schema_max_publish.json | 25 +++++++ .../max/server/settings/publishers.py | 18 ++++- server_addon/max/server/version.py | 2 +- 6 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 openpype/hosts/max/plugins/publish/validate_loaded_plugin.py delete mode 100644 openpype/hosts/max/plugins/publish/validate_usd_plugin.py diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py new file mode 100644 index 0000000000..10cbdf22fb --- /dev/null +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +"""Validator for USD plugin.""" +from pyblish.api import InstancePlugin, ValidatorOrder +from pymxs import runtime as rt + +from openpype.pipeline.publish import ( + RepairAction, + OptionalPyblishPluginMixin, + PublishValidationError +) +from openpype.hosts.max.api.lib import get_plugins + + +class ValidateLoadedPlugin(OptionalPyblishPluginMixin, + InstancePlugin): + """Validates if the specific plugin is loaded in 3ds max. + User can add the plugins they want to check through""" + + order = ValidatorOrder + hosts = ["max"] + label = "Validate Loaded Plugin" + optional = True + actions = [RepairAction] + + def get_invalid(self, instance): + """Plugin entry point.""" + invalid = [] + # display all DLL loaded plugins in Max + plugin_info = get_plugins() + project_settings = instance.context.data[ + "project_settings"]["max"]["publish"] + target_plugins = project_settings[ + "ValidateLoadedPlugin"]["plugins_for_check"] + for plugin in target_plugins: + if plugin.lower() not in plugin_info: + invalid.append( + f"Plugin {plugin} not exists in 3dsMax Plugin List.") + for i, _ in enumerate(plugin_info): + if plugin.lower() == rt.pluginManager.pluginDllName(i): + if not rt.pluginManager.isPluginDllLoaded(i): + invalid.append( + f"Plugin {plugin} not loaded.") + return invalid + + def process(self, instance): + invalid_plugins = self.get_invalid(instance) + if invalid_plugins: + bullet_point_invalid_statement = "\n".join( + "- {}".format(invalid) for invalid in invalid_plugins + ) + report = ( + "Required plugins fails to load.\n\n" + f"{bullet_point_invalid_statement}\n\n" + "You can use repair action to load the plugin." + ) + raise PublishValidationError(report, title="Required Plugins unloaded") + + @classmethod + def repair(cls, instance): + plugin_info = get_plugins() + project_settings = instance.context.data[ + "project_settings"]["max"]["publish"] + target_plugins = project_settings[ + "ValidateLoadedPlugin"]["plugins_for_check"] + for plugin in target_plugins: + for i, _ in enumerate(plugin_info): + if plugin == rt.pluginManager.pluginDllName(i): + if not rt.pluginManager.isPluginDllLoaded(i): + rt.pluginManager.loadPluginDll(i) diff --git a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py b/openpype/hosts/max/plugins/publish/validate_usd_plugin.py deleted file mode 100644 index 36c4291925..0000000000 --- a/openpype/hosts/max/plugins/publish/validate_usd_plugin.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -"""Validator for USD plugin.""" -from pyblish.api import InstancePlugin, ValidatorOrder -from pymxs import runtime as rt - -from openpype.pipeline import ( - OptionalPyblishPluginMixin, - PublishValidationError -) - - -def get_plugins() -> list: - """Get plugin list from 3ds max.""" - manager = rt.PluginManager - count = manager.pluginDllCount - plugin_info_list = [] - for p in range(1, count + 1): - plugin_info = manager.pluginDllName(p) - plugin_info_list.append(plugin_info) - - return plugin_info_list - - -class ValidateUSDPlugin(OptionalPyblishPluginMixin, - InstancePlugin): - """Validates if USD plugin is installed or loaded in 3ds max.""" - - order = ValidatorOrder - 0.01 - families = ["model"] - hosts = ["max"] - label = "Validate USD Plugin loaded" - optional = True - - def process(self, instance): - """Plugin entry point.""" - - for sc in ValidateUSDPlugin.__subclasses__(): - self.log.info(sc) - - if not self.is_active(instance.data): - return - - plugin_info = get_plugins() - usd_import = "usdimport.dli" - if usd_import not in plugin_info: - raise PublishValidationError(f"USD Plugin {usd_import} not found") - usd_export = "usdexport.dle" - if usd_export not in plugin_info: - raise PublishValidationError(f"USD Plugin {usd_export} not found") diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index bfb1aa4aeb..45246fdf2b 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -36,6 +36,11 @@ "enabled": true, "optional": true, "active": true + }, + "ValidateLoadedPlugin": { + "enabled": false, + "optional": true, + "plugins_for_check": [] } } } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json index ea08c735a6..4490c5353d 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json @@ -28,6 +28,31 @@ "label": "Active" } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "ValidateLoadedPlugin", + "label": "Validate Loaded Plugin", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "list", + "key": "plugins_for_check", + "label": "Plugins Needed For Check", + "object_type": "text" + } + ] } ] } diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index a695b85e89..8a28224a07 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -3,6 +3,14 @@ from pydantic import Field from ayon_server.settings import BaseSettingsModel +class ValidateLoadedPluginModel(BaseSettingsModel): + enabled: bool = Field(title="ValidateLoadedPlugin") + optional: bool = Field(title="Optional") + plugins_for_check: list[str] = Field( + default_factory=list, title="Plugins Needed For Check" + ) + + class BasicValidateModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") optional: bool = Field(title="Optional") @@ -15,12 +23,20 @@ class PublishersModel(BaseSettingsModel): title="Validate Frame Range", section="Validators" ) - + ValidateLoadedPlugin: ValidateLoadedPluginModel = Field( + default_factory=ValidateLoadedPluginModel, + title="Validate Loaded Plugin" + ) DEFAULT_PUBLISH_SETTINGS = { "ValidateFrameRange": { "enabled": True, "optional": True, "active": True + }, + "ValidateLoadedPlugin": { + "enabled": False, + "optional": True, + "plugins_for_check": [] } } diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py index 3dc1f76bc6..485f44ac21 100644 --- a/server_addon/max/server/version.py +++ b/server_addon/max/server/version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" From 77776d0943ae8750876f98521a9e493dbcdf584e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 25 Oct 2023 22:53:28 +0800 Subject: [PATCH 129/690] hound --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 10cbdf22fb..44343bada2 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -53,7 +53,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, f"{bullet_point_invalid_statement}\n\n" "You can use repair action to load the plugin." ) - raise PublishValidationError(report, title="Required Plugins unloaded") + raise PublishValidationError( + report, title="Required Plugins unloaded") @classmethod def repair(cls, instance): From a43b842097b48924345cb8be98f8ca380a2b73a5 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 15:49:28 +0800 Subject: [PATCH 130/690] add missing codes for switching on/off the loaded plugin validator --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 44343bada2..0090c69269 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -24,6 +24,9 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, def get_invalid(self, instance): """Plugin entry point.""" + if not self.is_active(instance.data): + self.log.debug("Skipping Validate Loaded Plugin...") + return invalid = [] # display all DLL loaded plugins in Max plugin_info = get_plugins() From cb4dd2559b9d51469870a3962cf69435f7d290b4 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 26 Oct 2023 10:44:34 +0200 Subject: [PATCH 131/690] wip create blend scene create render --- .../plugins/create/create_blendScene.py | 41 +++++++++++++++---- .../blender/plugins/create/create_render.py | 35 ++++++++++++---- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index 63bcf212ff..ee8e52d3c5 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -4,7 +4,10 @@ import bpy from openpype.pipeline import get_current_task_name from openpype.hosts.blender.api import plugin, lib, ops -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) class CreateBlendScene(plugin.Creator): @@ -15,12 +18,18 @@ class CreateBlendScene(plugin.Creator): family = "blendScene" icon = "cubes" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) + mti = ops.MainThreadItem( + self._process, subset_name, instance_data, pre_create_data + ) ops.execute_in_main_thread(mti) - def _process(self): + def _process( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: @@ -28,14 +37,28 @@ class CreateBlendScene(plugin.Creator): bpy.context.scene.collection.children.link(instances) # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) + asset = instance_data.get("asset") + name = plugin.asset_name(asset, subset_name) asset_group = bpy.data.objects.new(name=name, object_data=None) asset_group.empty_display_type = 'SINGLE_ARROW' instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) + + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name + } + + instance_data.update( + { + "id": "publish.avalon.instance", + "creator_identifier": self.identifier, + "label": subset_name, + "task": get_current_task_name(), + "subset": subset_name, + "instance_node": instance_node, + } + ) + + lib.imprint(asset_group, instance_data) # Add selected objects to instance if (self.options or {}).get("useSelection"): diff --git a/openpype/hosts/blender/plugins/create/create_render.py b/openpype/hosts/blender/plugins/create/create_render.py index f938a21808..ab3119b32e 100644 --- a/openpype/hosts/blender/plugins/create/create_render.py +++ b/openpype/hosts/blender/plugins/create/create_render.py @@ -4,10 +4,13 @@ import bpy from openpype.pipeline import get_current_task_name from openpype.hosts.blender.api import plugin, lib from openpype.hosts.blender.api.render_lib import prepare_rendering -from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES +from openpype.hosts.blender.api.pipeline import ( + AVALON_INSTANCES, + AVALON_PROPERTY, +) -class CreateRenderlayer(plugin.Creator): +class CreateRenderlayer(plugin.BlenderCreator): """Single baked camera""" name = "renderingMain" @@ -15,7 +18,9 @@ class CreateRenderlayer(plugin.Creator): family = "render" icon = "eye" - def process(self): + def create( + self, subset_name: str, instance_data: dict, pre_create_data: dict + ): # Get Instance Container or create it if it does not exist instances = bpy.data.collections.get(AVALON_INSTANCES) if not instances: @@ -23,15 +28,29 @@ class CreateRenderlayer(plugin.Creator): bpy.context.scene.collection.children.link(instances) # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) + asset = instance_data.get("asset") + name = plugin.asset_name(asset, subset_name) asset_group = bpy.data.collections.new(name=name) try: instances.children.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) + + asset_group[AVALON_PROPERTY] = instance_node = { + "name": asset_group.name + } + + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": subset_name, + "task": get_current_task_name(), + "subset": subset_name, + "instance_node": instance_node, + } + ) + + lib.imprint(asset_group, instance_data) prepare_rendering(asset_group) except Exception: From 5d87d08ab83b81815e6bc47bddcd7300a30fcc60 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 17:04:00 +0800 Subject: [PATCH 132/690] clean up the code of validate loaded plugins --- .../plugins/publish/validate_loaded_plugin.py | 77 +++++++++++-------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 0090c69269..a8bdf7f903 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- -"""Validator for USD plugin.""" -from pyblish.api import InstancePlugin, ValidatorOrder +"""Validator for Loaded Plugin.""" +from pyblish.api import ContextPlugin, ValidatorOrder from pymxs import runtime as rt from openpype.pipeline.publish import ( - RepairAction, + RepairContextAction, OptionalPyblishPluginMixin, PublishValidationError ) @@ -12,7 +12,7 @@ from openpype.hosts.max.api.lib import get_plugins class ValidateLoadedPlugin(OptionalPyblishPluginMixin, - InstancePlugin): + ContextPlugin): """Validates if the specific plugin is loaded in 3ds max. User can add the plugins they want to check through""" @@ -20,29 +20,38 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, hosts = ["max"] label = "Validate Loaded Plugin" optional = True - actions = [RepairAction] + actions = [RepairContextAction] - def get_invalid(self, instance): + def get_invalid(self, context): """Plugin entry point.""" - if not self.is_active(instance.data): + if not self.is_active(context.data): self.log.debug("Skipping Validate Loaded Plugin...") return invalid = [] - # display all DLL loaded plugins in Max - plugin_info = get_plugins() - project_settings = instance.context.data[ - "project_settings"]["max"]["publish"] - target_plugins = project_settings[ - "ValidateLoadedPlugin"]["plugins_for_check"] - for plugin in target_plugins: - if plugin.lower() not in plugin_info: + # get all DLL loaded plugins in Max and their plugin index + available_plugins = { + plugin_name.lower(): index for index, plugin_name in enumerate(\ + get_plugins()) + } + required_plugins = ( + context.data["project_settings"]["max"]["publish"] + ["ValidateLoadedPlugin"]["plugins_for_check"] + ) + for plugin in required_plugins: + plugin_name = plugin.lower() + + plugin_index = available_plugins.get(plugin_name) + + if plugin_index is None: invalid.append( - f"Plugin {plugin} not exists in 3dsMax Plugin List.") - for i, _ in enumerate(plugin_info): - if plugin.lower() == rt.pluginManager.pluginDllName(i): - if not rt.pluginManager.isPluginDllLoaded(i): - invalid.append( - f"Plugin {plugin} not loaded.") + f"Plugin {plugin} not exists in 3dsMax Plugin List." + ) + continue + + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + invalid.append( + f"Plugin {plugin} not loaded.") + return invalid def process(self, instance): @@ -60,14 +69,18 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, report, title="Required Plugins unloaded") @classmethod - def repair(cls, instance): - plugin_info = get_plugins() - project_settings = instance.context.data[ - "project_settings"]["max"]["publish"] - target_plugins = project_settings[ - "ValidateLoadedPlugin"]["plugins_for_check"] - for plugin in target_plugins: - for i, _ in enumerate(plugin_info): - if plugin == rt.pluginManager.pluginDllName(i): - if not rt.pluginManager.isPluginDllLoaded(i): - rt.pluginManager.loadPluginDll(i) + def repair(cls, context): + # get all DLL loaded plugins in Max and their plugin index + available_plugins = { + plugin_name.lower(): index for index, plugin_name in enumerate( + get_plugins()) + } + required_plugins = ( + context.data["project_settings"]["max"]["publish"] + ["ValidateLoadedPlugin"]["plugins_for_check"] + ) + for plugin in required_plugins: + plugin_name = plugin.lower() + plugin_index = available_plugins.get(plugin_name) + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + rt.pluginManager.loadPluginDll(plugin_index) From 6c24e55d9697bd28d6d7e7cac813f2d0756aa6a8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 17:05:10 +0800 Subject: [PATCH 133/690] hound --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index a8bdf7f903..564cfd0e67 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -30,7 +30,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, invalid = [] # get all DLL loaded plugins in Max and their plugin index available_plugins = { - plugin_name.lower(): index for index, plugin_name in enumerate(\ + plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } required_plugins = ( From b0a12848b92a825e7d979fa9c63416310ec6d528 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 17:47:40 +0800 Subject: [PATCH 134/690] clean up code and add condition to make sure the plugin not erroring out during validation --- .../plugins/publish/validate_loaded_plugin.py | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 564cfd0e67..49f0f3041b 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -18,7 +18,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, order = ValidatorOrder hosts = ["max"] - label = "Validate Loaded Plugin" + label = "Validate Loaded Plugins" optional = True actions = [RepairContextAction] @@ -27,16 +27,23 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not self.is_active(context.data): self.log.debug("Skipping Validate Loaded Plugin...") return + + required_plugins = ( + context.data["project_settings"]["max"]["publish"] + ["ValidateLoadedPlugin"]["plugins_for_check"] + ) + + if not required_plugins: + return + invalid = [] + # get all DLL loaded plugins in Max and their plugin index available_plugins = { plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } - required_plugins = ( - context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"]["plugins_for_check"] - ) + for plugin in required_plugins: plugin_name = plugin.lower() @@ -49,8 +56,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, continue if not rt.pluginManager.isPluginDllLoaded(plugin_index): - invalid.append( - f"Plugin {plugin} not loaded.") + invalid.append(f"Plugin {plugin} not loaded.") return invalid @@ -82,5 +88,10 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, for plugin in required_plugins: plugin_name = plugin.lower() plugin_index = available_plugins.get(plugin_name) + + if plugin_index is None: + cls.log.warning(f"Can't enable missing plugin: {plugin}") + continue + if not rt.pluginManager.isPluginDllLoaded(plugin_index): rt.pluginManager.loadPluginDll(plugin_index) From a8c4c05b7329b6ccf22309f14aa3990f18b96844 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 17:58:03 +0800 Subject: [PATCH 135/690] Docstring edit --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 49f0f3041b..9602d0f313 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -14,7 +14,8 @@ from openpype.hosts.max.api.lib import get_plugins class ValidateLoadedPlugin(OptionalPyblishPluginMixin, ContextPlugin): """Validates if the specific plugin is loaded in 3ds max. - User can add the plugins they want to check through""" + Studio Admin(s) can add the plugins they want to check in validation + via studio defined project settings""" order = ValidatorOrder hosts = ["max"] From ca2ff805910510a6ecf75e0ae233b8b818665924 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 26 Oct 2023 12:43:13 +0200 Subject: [PATCH 136/690] nuke: updating colorspace defaults --- .../defaults/project_settings/nuke.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index 1cadedd797..20df0ad5c2 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -19,16 +19,16 @@ "rules": {} }, "viewer": { - "viewerProcess": "sRGB" + "viewerProcess": "sRGB (default)" }, "baking": { - "viewerProcess": "rec709" + "viewerProcess": "rec709 (default)" }, "workfile": { - "colorManagement": "Nuke", + "colorManagement": "OCIO", "OCIO_config": "nuke-default", - "workingSpaceLUT": "linear", - "monitorLut": "sRGB" + "workingSpaceLUT": "scene_linear", + "monitorLut": "sRGB (default)" }, "nodes": { "requiredNodes": [ @@ -76,7 +76,7 @@ { "type": "text", "name": "colorspace", - "value": "linear" + "value": "scene_linear" }, { "type": "bool", @@ -129,7 +129,7 @@ { "type": "text", "name": "colorspace", - "value": "linear" + "value": "scene_linear" }, { "type": "bool", @@ -177,7 +177,7 @@ { "type": "text", "name": "colorspace", - "value": "sRGB" + "value": "texture_paint" }, { "type": "bool", @@ -193,7 +193,7 @@ "inputs": [ { "regex": "(beauty).*(?=.exr)", - "colorspace": "linear" + "colorspace": "scene_linear" } ] } From 1ecd96acf6acb98f9fb27aa70a345ad5014343b9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 21:18:28 +0800 Subject: [PATCH 137/690] use context.data instead of instance data --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 9602d0f313..69f72ccf1d 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -61,8 +61,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, return invalid - def process(self, instance): - invalid_plugins = self.get_invalid(instance) + def process(self, context): + invalid_plugins = self.get_invalid(context) if invalid_plugins: bullet_point_invalid_statement = "\n".join( "- {}".format(invalid) for invalid in invalid_plugins From 5b18acadc0c76e7bd51f5fe8a6b1b93486a0e79e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 26 Oct 2023 21:33:31 +0800 Subject: [PATCH 138/690] Implement ValidateAttributes in 3dsMax --- .../plugins/publish/validate_attributes.py | 62 +++++++++++++++++++ openpype/settings/ayon_settings.py | 9 +++ .../defaults/project_settings/max.json | 4 ++ .../schemas/schema_max_publish.json | 19 ++++++ .../max/server/settings/publishers.py | 36 ++++++++++- 5 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 openpype/hosts/max/plugins/publish/validate_attributes.py diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py new file mode 100644 index 0000000000..e98e73de06 --- /dev/null +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +"""Validator for Attributes.""" +from pyblish.api import ContextPlugin, ValidatorOrder +from pymxs import runtime as rt + +from openpype.pipeline.publish import ( + OptionalPyblishPluginMixin, + PublishValidationError, + RepairContextAction +) + + +class ValidateAttributes(OptionalPyblishPluginMixin, + ContextPlugin): + """Validates attributes are consistent in 3ds max.""" + + order = ValidatorOrder + hosts = ["max"] + label = "Attributes" + actions = [RepairContextAction] + optional = True + + @classmethod + def get_invalid(cls, context): + attributes = ( + context.data["project_settings"]["max"]["publish"] + ["ValidateAttributes"]["attributes"] + ) + if not attributes: + return + + invalid_attributes = [key for key, value in attributes.items() + if rt.Execute(attributes[key]) != value] + + return invalid_attributes + + def process(self, context): + if not self.is_active(context.data): + self.log.debug("Skipping Validate Attributes...") + return + invalid_attributes = self.get_invalid(context) + if invalid_attributes: + bullet_point_invalid_statement = "\n".join( + "- {}".format(invalid) for invalid in invalid_attributes + ) + report = ( + "Required Attribute(s) have invalid value(s).\n\n" + f"{bullet_point_invalid_statement}\n\n" + "You can use repair action to fix it." + ) + raise PublishValidationError( + report, title="Invalid Value(s) for Required Attribute(s)") + + @classmethod + def repair(cls, context): + attributes = ( + context.data["project_settings"]["max"]["publish"] + ["ValidateAttributes"]["attributes"] + ) + invalid_attribute_keys = cls.get_invalid(context) + for key in invalid_attribute_keys: + attributes[key] = rt.Execute(attributes[key]) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 8d4683490b..a31c8a04e0 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -639,6 +639,15 @@ def _convert_3dsmax_project_settings(ayon_settings, output): for item in point_cloud_attribute } ayon_max["PointCloud"]["attribute"] = new_point_cloud_attribute + # --- Publish (START) --- + ayon_publish = ayon_max["publish"] + try: + attributes = json.loads( + ayon_publish["ValidateAttributes"]["attributes"] + ) + except ValueError: + attributes = {} + ayon_publish["ValidateAttributes"]["attributes"] = attributes output["max"] = ayon_max diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index bfb1aa4aeb..24a87020bb 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -36,6 +36,10 @@ "enabled": true, "optional": true, "active": true + }, + "ValidateAttributes": { + "enabled": false, + "attributes": {} } } } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json index ea08c735a6..c3b56bae5e 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json @@ -28,6 +28,25 @@ "label": "Active" } ] + }, + { + "type": "dict", + "collapsible": true, + "key": "ValidateAttributes", + "label": "ValidateAttributes", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "raw-json", + "key": "attributes", + "label": "Attributes" + } + ] } ] } diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index a695b85e89..df8412391a 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -1,6 +1,30 @@ -from pydantic import Field +import json +from pydantic import Field, validator from ayon_server.settings import BaseSettingsModel +from ayon_server.exceptions import BadRequestException + + +class ValidateAttributesModel(BaseSettingsModel): + enabled: bool = Field(title="ValidateAttributes") + attributes: str = Field( + "{}", title="Attributes", widget="textarea") + + @validator("attributes") + def validate_json(cls, value): + if not value.strip(): + return "{}" + try: + converted_value = json.loads(value) + success = isinstance(converted_value, dict) + except json.JSONDecodeError: + success = False + + if not success: + raise BadRequestException( + "The attibutes can't be parsed as json object" + ) + return value class BasicValidateModel(BaseSettingsModel): @@ -15,6 +39,10 @@ class PublishersModel(BaseSettingsModel): title="Validate Frame Range", section="Validators" ) + ValidateAttributes: ValidateAttributesModel = Field( + default_factory=ValidateAttributesModel, + title="Validate Attributes" + ) DEFAULT_PUBLISH_SETTINGS = { @@ -22,5 +50,9 @@ DEFAULT_PUBLISH_SETTINGS = { "enabled": True, "optional": True, "active": True - } + }, + "ValidateAttributes": { + "enabled": False, + "attributes": "{}" + }, } From ae2c4bd5548c6ba81e7937320b0b91554ea614cd Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 26 Oct 2023 17:09:34 +0200 Subject: [PATCH 139/690] nuke: aligning server addon settings with openpype --- server_addon/nuke/server/settings/imageio.py | 16 ++++++++-------- server_addon/nuke/server/version.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/server_addon/nuke/server/settings/imageio.py b/server_addon/nuke/server/settings/imageio.py index 15ccd4e89a..19ad5ff24a 100644 --- a/server_addon/nuke/server/settings/imageio.py +++ b/server_addon/nuke/server/settings/imageio.py @@ -213,16 +213,16 @@ class ImageIOSettings(BaseSettingsModel): DEFAULT_IMAGEIO_SETTINGS = { "viewer": { - "viewerProcess": "sRGB" + "viewerProcess": "sRGB (default)" }, "baking": { - "viewerProcess": "rec709" + "viewerProcess": "rec709 (default)" }, "workfile": { - "color_management": "Nuke", + "color_management": "OCIO", "native_ocio_config": "nuke-default", - "working_space": "linear", - "thumbnail_space": "sRGB", + "working_space": "scene_linear", + "thumbnail_space": "sRGB (default)", }, "nodes": { "required_nodes": [ @@ -269,7 +269,7 @@ DEFAULT_IMAGEIO_SETTINGS = { { "type": "text", "name": "colorspace", - "text": "linear" + "text": "scene_linear" }, { "type": "boolean", @@ -321,7 +321,7 @@ DEFAULT_IMAGEIO_SETTINGS = { { "type": "text", "name": "colorspace", - "text": "linear" + "text": "scene_linear" }, { "type": "boolean", @@ -368,7 +368,7 @@ DEFAULT_IMAGEIO_SETTINGS = { { "type": "text", "name": "colorspace", - "text": "sRGB" + "text": "texture_paint" }, { "type": "boolean", diff --git a/server_addon/nuke/server/version.py b/server_addon/nuke/server/version.py index bbab0242f6..1276d0254f 100644 --- a/server_addon/nuke/server/version.py +++ b/server_addon/nuke/server/version.py @@ -1 +1 @@ -__version__ = "0.1.4" +__version__ = "0.1.5" From b6694606876eba68f3e0cb24928f93f7093e1c70 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 26 Oct 2023 18:06:47 +0200 Subject: [PATCH 140/690] Removed unnecessary condition. --- openpype/client/server/entities.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index c735c558d5..fcb5ec2383 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -226,12 +226,11 @@ def get_assets( new_asset_names = set() folder_paths = set() - if asset_names: - for name in asset_names: - if "/" in name: - folder_paths.add(name) - else: - new_asset_names.add(name) + for name in asset_names: + if "/" in name: + folder_paths.add(name) + else: + new_asset_names.add(name) if folder_paths: for folder in _folders_query( From 130693b798be8c53e18ec02bcacde7b8b6f45fdd Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 18:24:42 +0200 Subject: [PATCH 141/690] use 'AYON_SERVER_ENABLED' in resolve plugin --- .../plugins/publish/precollect_workfile.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py index 28b2350f01..39c28e29f5 100644 --- a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py @@ -1,6 +1,7 @@ import pyblish.api from pprint import pformat +from openpype import AYON_SERVER_ENABLED from openpype.pipeline import get_current_asset_name from openpype.hosts.resolve import api as rapi from openpype.hosts.resolve.otio import davinci_export @@ -13,10 +14,13 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.5 def process(self, context): + current_asset = get_current_asset_name() + if AYON_SERVER_ENABLED: + # AYON compatibility split name and use last piece + asset_name = current_asset.split("/")[-1] + else: + asset_name = current_asset - asset = get_current_asset_name() - # AYON compatibility split name and use last piece - _asset_name = asset.split("/")[-1] subset = "workfile" project = rapi.get_current_project() fps = project.GetSetting("timelineFrameRate") @@ -26,9 +30,9 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): otio_timeline = davinci_export.create_otio_timeline(project) instance_data = { - "name": "{}_{}".format(_asset_name, subset), - "asset": asset, - "subset": "{}{}".format(_asset_name, subset.capitalize()), + "name": "{}_{}".format(asset_name, subset), + "asset": current_asset, + "subset": "{}{}".format(asset_name, subset.capitalize()), "item": project, "family": "workfile", "families": [] From e920c014307e0fcb543f129b6e72b4ba49433cfb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 18:41:47 +0200 Subject: [PATCH 142/690] unify conditions --- .../hosts/tvpaint/plugins/create/create_review.py | 12 ++++++------ .../hosts/tvpaint/plugins/create/create_workfile.py | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/tvpaint/plugins/create/create_review.py b/openpype/hosts/tvpaint/plugins/create/create_review.py index 265cef00ef..5caf20f27d 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_review.py +++ b/openpype/hosts/tvpaint/plugins/create/create_review.py @@ -34,12 +34,12 @@ class TVPaintReviewCreator(TVPaintAutoCreator): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() - existing_asset_name = None - if existing_instance is not None: - if AYON_SERVER_ENABLED: - existing_asset_name = existing_instance.get("folderPath") - if existing_asset_name is None: - existing_asset_name = existing_instance.get("asset") + if existing_instance is None: + existing_asset_name = None + elif AYON_SERVER_ENABLED: + existing_asset_name = existing_instance["folderPath"] + else: + existing_asset_name = existing_instance["asset"] if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) diff --git a/openpype/hosts/tvpaint/plugins/create/create_workfile.py b/openpype/hosts/tvpaint/plugins/create/create_workfile.py index eec0f8483f..4ce5d7fc96 100644 --- a/openpype/hosts/tvpaint/plugins/create/create_workfile.py +++ b/openpype/hosts/tvpaint/plugins/create/create_workfile.py @@ -30,12 +30,12 @@ class TVPaintWorkfileCreator(TVPaintAutoCreator): asset_name = create_context.get_current_asset_name() task_name = create_context.get_current_task_name() - existing_asset_name = None - if existing_instance is not None: - if AYON_SERVER_ENABLED: - existing_asset_name = existing_instance.get("folderPath") - if existing_asset_name is None: - existing_asset_name = existing_instance.get("asset") + if existing_instance is None: + existing_asset_name = None + elif AYON_SERVER_ENABLED: + existing_asset_name = existing_instance["folderPath"] + else: + existing_asset_name = existing_instance["asset"] if existing_instance is None: asset_doc = get_asset_by_name(project_name, asset_name) From 8a9a1e66f3fe007367d7895fcbcb452a88c4a366 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 19:08:08 +0200 Subject: [PATCH 143/690] comparison of UILabelDef is comparing label value --- openpype/lib/attribute_definitions.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index a71d6cc72a..b8faae8f4c 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -240,6 +240,11 @@ class UILabelDef(UIDef): def __init__(self, label): super(UILabelDef, self).__init__(label=label) + def __eq__(self, other): + if not super(UILabelDef, self).__eq__(other): + return False + return self.label == other.label: + # --------------------------------------- # Attribute defintioins should hold value From bbfff158b055b4fcaf520396bdea0d5544321d08 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 26 Oct 2023 19:08:25 +0200 Subject: [PATCH 144/690] it is possible to define key of label to differentiate --- openpype/lib/attribute_definitions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index b8faae8f4c..658a3fe581 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -237,8 +237,8 @@ class UISeparatorDef(UIDef): class UILabelDef(UIDef): type = "label" - def __init__(self, label): - super(UILabelDef, self).__init__(label=label) + def __init__(self, label, key=None): + super(UILabelDef, self).__init__(label=label, key=key) def __eq__(self, other): if not super(UILabelDef, self).__eq__(other): From 576ac94e3168568e1a6e5bc136bc338fac19a8f4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:12:15 +0200 Subject: [PATCH 145/690] Remove semicolon --- openpype/lib/attribute_definitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/lib/attribute_definitions.py b/openpype/lib/attribute_definitions.py index 658a3fe581..3dd284b8e4 100644 --- a/openpype/lib/attribute_definitions.py +++ b/openpype/lib/attribute_definitions.py @@ -243,7 +243,7 @@ class UILabelDef(UIDef): def __eq__(self, other): if not super(UILabelDef, self).__eq__(other): return False - return self.label == other.label: + return self.label == other.label # --------------------------------------- From 0b0cfb4116ed6067b0416bb34ecd8a3dd7e19805 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 27 Oct 2023 14:24:37 +0200 Subject: [PATCH 146/690] add slash at the beginning of path --- openpype/client/entities.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/client/entities.py b/openpype/client/entities.py index d085f90028..cbaa943743 100644 --- a/openpype/client/entities.py +++ b/openpype/client/entities.py @@ -22,4 +22,4 @@ def get_asset_name_identifier(asset_doc): return asset_doc["name"] parents = list(asset_doc["data"]["parents"]) parents.append(asset_doc["name"]) - return "/".join(parents) + return "/" + "/".join(parents) From dd72d45ce7881b46c90c6972f27cc101b02f7696 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 27 Oct 2023 14:36:22 +0200 Subject: [PATCH 147/690] fix path in assets widget --- openpype/tools/publisher/widgets/assets_widget.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/tools/publisher/widgets/assets_widget.py b/openpype/tools/publisher/widgets/assets_widget.py index 5f74b79c99..32be514dd7 100644 --- a/openpype/tools/publisher/widgets/assets_widget.py +++ b/openpype/tools/publisher/widgets/assets_widget.py @@ -140,9 +140,11 @@ class AssetsHierarchyModel(QtGui.QStandardItemModel): for name in sorted(children_by_name.keys()): child = children_by_name[name] child_id = child["_id"] - child_path = name if parent_path: - child_path = "{}/{}".format(parent_path, child_path) + child_path = "{}/{}".format(parent_path, name) + else: + child_path = "/{}".format(name) + has_children = bool(assets_by_parent_id.get(child_id)) icon = get_asset_icon(child, has_children) From 6a0decab459db0b83b777289521584f2eaca02a2 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 27 Oct 2023 21:09:29 +0800 Subject: [PATCH 148/690] make sure to check invalid properties --- .../plugins/publish/validate_attributes.py | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index e98e73de06..2d3f09f972 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -29,10 +29,20 @@ class ValidateAttributes(OptionalPyblishPluginMixin, if not attributes: return - invalid_attributes = [key for key, value in attributes.items() - if rt.Execute(attributes[key]) != value] + for wrap_object, property_name in attributes.items(): + invalid_properties = [key for key in property_name.keys() + if not rt.Execute( + f'isProperty {wrap_object} "{key}"')] + if invalid_properties: + cls.log.error( + "Unknown Property Values:{}".format(invalid_properties)) + return invalid_properties + # TODO: support multiple varaible types in maxscript + invalid_attributes = [key for key, value in property_name.items() + if rt.Execute("{}.{}".format( + wrap_object, property_name[key]))!=value] - return invalid_attributes + return invalid_attributes def process(self, context): if not self.is_active(context.data): @@ -57,6 +67,10 @@ class ValidateAttributes(OptionalPyblishPluginMixin, context.data["project_settings"]["max"]["publish"] ["ValidateAttributes"]["attributes"] ) - invalid_attribute_keys = cls.get_invalid(context) - for key in invalid_attribute_keys: - attributes[key] = rt.Execute(attributes[key]) + for wrap_object, property_name in attributes.items(): + invalid_attributes = [key for key, value in property_name.items() + if rt.Execute("{}.{}".format( + wrap_object, property_name[key]))!=value] + for attrs in invalid_attributes: + rt.Execute("{}.{}={}".format( + wrap_object, attrs, attributes[wrap_object][attrs])) From 4f658d2f51cd3357a3d31ba7d607354debabaa19 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Fri, 27 Oct 2023 16:05:01 +0200 Subject: [PATCH 149/690] update blender creator --- openpype/hosts/blender/api/plugin.py | 14 ++++++++++++-- .../blender/plugins/create/create_blendScene.py | 2 +- .../hosts/blender/plugins/create/create_model.py | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 73d8fc0ed5..dbd9f25d68 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -9,6 +9,7 @@ from openpype.pipeline import ( Creator, CreatedInstance, LoaderPlugin, + get_current_task_name, ) from .pipeline import ( AVALON_CONTAINERS, @@ -235,11 +236,20 @@ class BlenderCreator(Creator): collection = bpy.data.collections.new(name=subset_name) bpy.context.scene.collection.children.link(collection) - collection["instance_node"] = instance_node = { + collection[AVALON_PROPERTY] = instance_node = { "name": collection.name, } - instance_data["instance_node"] = instance_node + instance_data.update( + { + "id": "pyblish.avalon.instance", + "creator_identifier": self.identifier, + "label": subset_name, + "task": get_current_task_name(), + "subset": subset_name, + "instance_node": instance_node, + } + ) instance = CreatedInstance( self.family, subset_name, instance_data, self diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index ee8e52d3c5..23ff991654 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -21,7 +21,7 @@ class CreateBlendScene(plugin.Creator): def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): - """ Run the creator on Blender main thread""" + """Run the creator on Blender main thread.""" mti = ops.MainThreadItem( self._process, subset_name, instance_data, pre_create_data ) diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 3c8e9c4900..761d9fca9f 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -22,7 +22,7 @@ class CreateModel(plugin.BlenderCreator): def create( self, subset_name: str, instance_data: dict, pre_create_data: dict ): - """ Run the creator on Blender main thread""" + """Run the creator on Blender main thread.""" self._add_instance_to_context( CreatedInstance(self.family, subset_name, instance_data, self) ) From ec5bc71eb3529ba096e00d5261dfdf0608a53280 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 27 Oct 2023 16:42:56 +0200 Subject: [PATCH 150/690] skip kitsu module when creating ayon addons --- server_addon/create_ayon_addons.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server_addon/create_ayon_addons.py b/server_addon/create_ayon_addons.py index 61dbd5c8d9..86139a65f8 100644 --- a/server_addon/create_ayon_addons.py +++ b/server_addon/create_ayon_addons.py @@ -205,7 +205,8 @@ def create_openpype_package( "shotgrid", "sync_server", "example_addons", - "slack" + "slack", + "kitsu", ] # Subdirs that won't be added to output zip file ignored_subpaths = [ From 3f8b250510e1cb0e6f8edae6afde87e5d2718c23 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 27 Oct 2023 17:05:00 +0200 Subject: [PATCH 151/690] removed unncessary path filtering --- openpype/client/server/entities.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index fcb5ec2383..9e86dfdd63 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -241,21 +241,9 @@ def get_assets( if not new_asset_names: return - folders_by_name = collections.defaultdict(list) for folder in _folders_query( project_name, con, fields, folder_names=new_asset_names, **kwargs ): - folders_by_name[folder["name"]].append(folder) - - for name, folders in folders_by_name.items(): - folder = next( - ( - folder - for folder in folders - if folder["path"] == name - ), - folders[0] - ) yield convert_v4_folder_to_v3(folder, project_name) From 4bde7b7fd94ab4ca183f90d83ef347e738d8b843 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 27 Oct 2023 18:01:04 +0200 Subject: [PATCH 152/690] hiero: adding folderPath to creator - some minor typos fixes - modules sorting --- openpype/hosts/hiero/api/plugin.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index 0e0632e032..dc90012b0f 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -31,7 +31,7 @@ def load_stylesheet(): class CreatorWidget(QtWidgets.QDialog): # output items - items = dict() + items = {} def __init__(self, name, info, ui_inputs, parent=None): super(CreatorWidget, self).__init__(parent) @@ -642,8 +642,8 @@ class PublishClip: Returns: hiero.core.TrackItem: hiero track item object with pype tag """ - vertical_clip_match = dict() - tag_data = dict() + vertical_clip_match = {} + tag_data = {} types = { "shot": "shot", "folder": "folder", @@ -705,9 +705,10 @@ class PublishClip: self._create_parents() def convert(self): - # solve track item data and add them to tag data - self._convert_to_tag_data() + tag_hierarchy_data = self._convert_to_tag_data() + + self.tag_data.update(tag_hierarchy_data) # if track name is in review track name and also if driving track name # is not in review track name: skip tag creation @@ -721,16 +722,28 @@ class PublishClip: if self.rename: # rename track item self.track_item.setName(new_name) - self.tag_data["asset"] = new_name + self.tag_data["asset_name"] = new_name else: - self.tag_data["asset"] = self.ti_name + self.tag_data["asset_name"] = self.ti_name self.tag_data["hierarchyData"]["shot"] = self.ti_name + # AYON unique identifier + folder_path = "/{}/{}".format( + tag_hierarchy_data["hierarchy"], + self.tag_data["asset_name"] + ) + self.tag_data["folderPath"] = folder_path + + # TODO: remove debug print + log.debug("___ folder_path: {}".format( + folder_path)) + if self.tag_data["heroTrack"] and self.review_layer: self.tag_data.update({"reviewTrack": self.review_layer}) else: self.tag_data.update({"reviewTrack": None}) + # TODO: remove debug print log.debug("___ self.tag_data: {}".format( pformat(self.tag_data) )) @@ -889,7 +902,7 @@ class PublishClip: tag_hierarchy_data = hero_data # add data to return data dict - self.tag_data.update(tag_hierarchy_data) + return tag_hierarchy_data def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): """ Solve tag data from hierarchy data and templates. """ From 4e9173fa71b9e6b4c19994356ce704a7d3bd29f5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 27 Oct 2023 18:02:11 +0200 Subject: [PATCH 153/690] Hiero: adding asset_name and processing folderPath - refactor labels --- .../plugins/publish/precollect_instances.py | 60 +++++++++++++------ .../plugins/publish/precollect_workfile.py | 15 +++-- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/hiero/plugins/publish/precollect_instances.py b/openpype/hosts/hiero/plugins/publish/precollect_instances.py index 65b8fed49c..1acbbb3d88 100644 --- a/openpype/hosts/hiero/plugins/publish/precollect_instances.py +++ b/openpype/hosts/hiero/plugins/publish/precollect_instances.py @@ -1,9 +1,12 @@ import pyblish + +from openpype import AYON_SERVER_ENABLED from openpype.pipeline.editorial import is_overlapping_otio_ranges + from openpype.hosts.hiero import api as phiero from openpype.hosts.hiero.api.otio import hiero_export -import hiero +import hiero # # developer reload modules from pprint import pformat @@ -80,25 +83,24 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if k not in ("id", "applieswhole", "label") }) - asset = tag_data["asset"] + asset, asset_name = self._get_asset_data(tag_data) + subset = tag_data["subset"] # insert family into families - family = tag_data["family"] families = [str(f) for f in tag_data["families"]] - families.insert(0, str(family)) # form label - label = asset - if asset != clip_name: + label = "{} -".format(asset) + if asset_name != clip_name: label += " ({})".format(clip_name) label += " {}".format(subset) - label += " {}".format("[" + ", ".join(families) + "]") data.update({ "name": "{}_{}".format(asset, subset), "label": label, "asset": asset, + "asset_name": asset_name, "item": track_item, "families": families, "publish": tag_data["publish"], @@ -176,6 +178,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): }) def create_shot_instance(self, context, **data): + subset = "shotMain" master_layer = data.get("heroTrack") hierarchy_data = data.get("hierarchyData") item = data.get("item") @@ -188,23 +191,21 @@ class PrecollectInstances(pyblish.api.ContextPlugin): return asset = data["asset"] - subset = "shotMain" + asset_name = data["asset_name"] # insert family into families family = "shot" # form label - label = asset - if asset != clip_name: + label = "{} -".format(asset) + if asset_name != clip_name: label += " ({}) ".format(clip_name) label += " {}".format(subset) - label += " [{}]".format(family) data.update({ "name": "{}_{}".format(asset, subset), "label": label, "subset": subset, - "asset": asset, "family": family, "families": [] }) @@ -214,7 +215,34 @@ class PrecollectInstances(pyblish.api.ContextPlugin): self.log.debug( "_ instance.data: {}".format(pformat(instance.data))) + def _get_asset_data(self, data): + folder_path = ( + data.pop("folderPath") if data.get("folderPath") else None) + + if data.get("asset_name"): + asset_name = data["asset_name"] + else: + asset_name = data["asset"] + + # backward compatibility for clip tags + # which are missing folderPath key + # TODO remove this in future versions + if not folder_path: + hierarchy_path = data["hierarchy"] + folder_path = "/{}/{}".format( + hierarchy_path, + asset_name + ) + + if AYON_SERVER_ENABLED: + asset = folder_path + else: + asset = asset_name + + return asset, asset_name + def create_audio_instance(self, context, **data): + subset = "audioMain" master_layer = data.get("heroTrack") if not master_layer: @@ -229,23 +257,21 @@ class PrecollectInstances(pyblish.api.ContextPlugin): return asset = data["asset"] - subset = "audioMain" + asset_name = data["asset_name"] # insert family into families family = "audio" # form label - label = asset - if asset != clip_name: + label = "{} -".format(asset) + if asset_name != clip_name: label += " ({}) ".format(clip_name) label += " {}".format(subset) - label += " [{}]".format(family) data.update({ "name": "{}_{}".format(asset, subset), "label": label, "subset": subset, - "asset": asset, "family": family, "families": ["clip"] }) diff --git a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py index 1d6bdc0257..8abb0885c6 100644 --- a/openpype/hosts/hiero/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/hiero/plugins/publish/precollect_workfile.py @@ -18,7 +18,8 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.491 def process(self, context): - asset_name = context.data["asset"] + asset = context.data["asset"] + asset_name = asset if AYON_SERVER_ENABLED: asset_name = asset_name.split("/")[-1] @@ -29,7 +30,7 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): # adding otio timeline to context otio_timeline = hiero_export.create_otio_timeline() - # get workfile thumnail paths + # get workfile thumbnail paths tmp_staging = tempfile.mkdtemp(prefix="pyblish_tmp_") thumbnail_name = "workfile_thumbnail.png" thumbnail_path = os.path.join(tmp_staging, thumbnail_name) @@ -51,8 +52,8 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): } # get workfile paths - curent_file = project.path() - staging_dir, base_name = os.path.split(curent_file) + current_file = project.path() + staging_dir, base_name = os.path.split(current_file) # creating workfile representation workfile_representation = { @@ -63,10 +64,12 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): } family = "workfile" instance_data = { + "label": "{} - {}Main".format( + asset, family), "name": "{}_{}".format(asset_name, family), "asset": context.data["asset"], # TODO use 'get_subset_name' - "subset": "{}{}".format(asset_name, family.capitalize()), + "subset": "{}{}Main".format(asset_name, family.capitalize()), "item": project, "family": family, "families": [], @@ -81,7 +84,7 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): "activeProject": project, "activeTimeline": active_timeline, "otioTimeline": otio_timeline, - "currentFile": curent_file, + "currentFile": current_file, "colorspace": self.get_colorspace(project), "fps": fps } From efef9e2fd35abc0e8fe7989776bbaeeef87b8336 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 27 Oct 2023 18:06:54 +0200 Subject: [PATCH 154/690] small fix in timers manager --- openpype/modules/timers_manager/timers_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/timers_manager/timers_manager.py b/openpype/modules/timers_manager/timers_manager.py index 43286f7da4..674d834a1d 100644 --- a/openpype/modules/timers_manager/timers_manager.py +++ b/openpype/modules/timers_manager/timers_manager.py @@ -247,7 +247,7 @@ class TimersManager( return { "project_name": project_name, "asset_id": str(asset_doc["_id"]), - "asset_name": asset_doc["name"], + "asset_name": asset_name, "task_name": task_name, "task_type": task_type, "hierarchy": hierarchy_items From d9a35e7804c5b747d2316d8b6a91b8ee0866809e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 27 Oct 2023 22:51:08 +0200 Subject: [PATCH 155/690] fixing extract hierarchy to ayon --- .../publish/extract_hierarchy_to_ayon.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/openpype/plugins/publish/extract_hierarchy_to_ayon.py b/openpype/plugins/publish/extract_hierarchy_to_ayon.py index fe8cb40ad2..ef69369d67 100644 --- a/openpype/plugins/publish/extract_hierarchy_to_ayon.py +++ b/openpype/plugins/publish/extract_hierarchy_to_ayon.py @@ -191,15 +191,15 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): """ # filter only the active publishing instances - active_folder_names = set() + active_folder_paths = set() for instance in context: if instance.data.get("publish") is not False: - active_folder_names.add(instance.data.get("asset")) + active_folder_paths.add(instance.data.get("asset")) - active_folder_names.discard(None) + active_folder_paths.discard(None) - self.log.debug("Active folder names: {}".format(active_folder_names)) - if not active_folder_names: + self.log.debug("Active folder paths: {}".format(active_folder_paths)) + if not active_folder_paths: return None project_item = None @@ -230,12 +230,13 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): if not children_context: continue - for asset_name, asset_info in children_context.items(): + for asset, asset_info in children_context.items(): if ( - asset_name not in active_folder_names + asset not in active_folder_paths and not asset_info.get("childs") ): continue + asset_name = asset.split("/")[-1] item_id = uuid.uuid4().hex new_item = copy.deepcopy(asset_info) new_item["name"] = asset_name @@ -252,7 +253,7 @@ class ExtractHierarchyToAYON(pyblish.api.ContextPlugin): items_by_id[item_id] = new_item parent_id_by_item_id[item_id] = parent_id - if asset_name in active_folder_names: + if asset in active_folder_paths: valid_ids.add(item_id) hierarchy_queue.append((item_id, new_children_context)) From dcf5855a477f35fd9fc160c8830974ec7cd2b8ed Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 27 Oct 2023 22:51:24 +0200 Subject: [PATCH 156/690] hound --- openpype/hosts/hiero/api/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index dc90012b0f..f72d27fed5 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -902,7 +902,7 @@ class PublishClip: tag_hierarchy_data = hero_data # add data to return data dict - return tag_hierarchy_data + return tag_hierarchy_data def _solve_tag_hierarchy_data(self, hierarchy_formatting_data): """ Solve tag data from hierarchy data and templates. """ From fe4e38190feaea158e077c8075330c69e9f10b4b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 10:00:37 +0100 Subject: [PATCH 157/690] skip 'kitsu' addon in openpype modules load --- openpype/modules/base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 080be251f3..e8b85d0e93 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -66,6 +66,7 @@ IGNORED_FILENAMES_IN_AYON = { "shotgrid", "sync_server", "slack", + "kitsu", } From c029fa632489529e36dbdaec5b74d2e938f46847 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 30 Oct 2023 17:21:29 +0800 Subject: [PATCH 158/690] support invalid checks on different variable types of attributes in Maxscript --- .../max/plugins/publish/validate_attributes.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 2d3f09f972..fa9912de07 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -38,9 +38,20 @@ class ValidateAttributes(OptionalPyblishPluginMixin, "Unknown Property Values:{}".format(invalid_properties)) return invalid_properties # TODO: support multiple varaible types in maxscript - invalid_attributes = [key for key, value in property_name.items() - if rt.Execute("{}.{}".format( - wrap_object, property_name[key]))!=value] + invalid_attributes = [] + for key, value in property_name.items(): + property_key = rt.Execute("{}.{}".format( + wrap_object, key)) + if isinstance(value, str) and "#" not in value: + if property_key != '"{}"'.format(value): + invalid_attributes.append(key) + + elif isinstance(value, bool): + if property_key != value: + invalid_attributes.append(key) + else: + if property_key != '{}'.format(value): + invalid_attributes.append(key) return invalid_attributes @@ -71,6 +82,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, invalid_attributes = [key for key, value in property_name.items() if rt.Execute("{}.{}".format( wrap_object, property_name[key]))!=value] + for attrs in invalid_attributes: rt.Execute("{}.{}={}".format( wrap_object, attrs, attributes[wrap_object][attrs])) From 0550668d3d3356a91f6b9c0fc47d6ebc27000ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Mon, 30 Oct 2023 10:24:01 +0100 Subject: [PATCH 159/690] Update openpype/hosts/hiero/api/plugin.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/hiero/api/plugin.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/openpype/hosts/hiero/api/plugin.py b/openpype/hosts/hiero/api/plugin.py index f72d27fed5..b0c73e41fb 100644 --- a/openpype/hosts/hiero/api/plugin.py +++ b/openpype/hosts/hiero/api/plugin.py @@ -733,11 +733,6 @@ class PublishClip: self.tag_data["asset_name"] ) self.tag_data["folderPath"] = folder_path - - # TODO: remove debug print - log.debug("___ folder_path: {}".format( - folder_path)) - if self.tag_data["heroTrack"] and self.review_layer: self.tag_data.update({"reviewTrack": self.review_layer}) else: From 05ab5e2e0fe53f4d585db7d4050ab6f6051b4f7b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 12:14:55 +0100 Subject: [PATCH 160/690] use 'asset' from context instead of from anatomy data --- .../plugins/publish/create_publish_royalrender_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/royalrender/plugins/publish/create_publish_royalrender_job.py b/openpype/modules/royalrender/plugins/publish/create_publish_royalrender_job.py index 3eb49a39ee..e13bf97e54 100644 --- a/openpype/modules/royalrender/plugins/publish/create_publish_royalrender_job.py +++ b/openpype/modules/royalrender/plugins/publish/create_publish_royalrender_job.py @@ -189,7 +189,7 @@ class CreatePublishRoyalRenderJob(pyblish.api.InstancePlugin, environment = RREnvList({ "AVALON_PROJECT": anatomy_data["project"]["name"], - "AVALON_ASSET": anatomy_data["asset"], + "AVALON_ASSET": instance.context.data["asset"], "AVALON_TASK": anatomy_data["task"]["name"], "OPENPYPE_USERNAME": anatomy_data["user"] }) From f27a25d2440671b19293bfba0c84180657178753 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 12:15:27 +0100 Subject: [PATCH 161/690] add 'folder' key to template data in harmony collectors --- .../plugins/publish/collect_harmony_scenes.py | 3 +++ .../plugins/publish/collect_harmony_zips.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py index 48c36aa067..c435ca2096 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_scenes.py @@ -60,6 +60,9 @@ class CollectHarmonyScenes(pyblish.api.InstancePlugin): # updating hierarchy data anatomy_data_new.update({ "asset": asset_data["name"], + "folder": { + "name": asset_data["name"], + }, "task": { "name": task, "type": task_type, diff --git a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py index 40a969f8df..d90215e767 100644 --- a/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py +++ b/openpype/hosts/standalonepublisher/plugins/publish/collect_harmony_zips.py @@ -56,6 +56,9 @@ class CollectHarmonyZips(pyblish.api.InstancePlugin): anatomy_data_new.update( { "asset": asset_data["name"], + "folder": { + "name": asset_data["name"], + }, "task": { "name": task, "type": task_type, From 4c55f515dd8513382fc8b9b7ac7710716708f6c6 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 12:16:07 +0100 Subject: [PATCH 162/690] do not use 'instance.data["asset"]' to prepare template data --- .../publish/collect_anatomy_instance_data.py | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/openpype/plugins/publish/collect_anatomy_instance_data.py b/openpype/plugins/publish/collect_anatomy_instance_data.py index cc6da9b2c3..1b4b44e40e 100644 --- a/openpype/plugins/publish/collect_anatomy_instance_data.py +++ b/openpype/plugins/publish/collect_anatomy_instance_data.py @@ -187,35 +187,29 @@ class CollectAnatomyInstanceData(pyblish.api.ContextPlugin): self.log.debug("Storing anatomy data to instance data.") project_doc = context.data["projectEntity"] - context_asset_doc = context.data.get("assetEntity") - project_task_types = project_doc["config"]["tasks"] for instance in context: + asset_doc = instance.data.get("assetEntity") anatomy_updates = { - "asset": instance.data["asset"], - "folder": { - "name": instance.data["asset"], - }, "family": instance.data["family"], "subset": instance.data["subset"], } - - # Hierarchy - asset_doc = instance.data.get("assetEntity") - if ( - asset_doc - and ( - not context_asset_doc - or asset_doc["_id"] != context_asset_doc["_id"] - ) - ): + if asset_doc: parents = asset_doc["data"].get("parents") or list() parent_name = project_doc["name"] if parents: parent_name = parents[-1] - anatomy_updates["hierarchy"] = "/".join(parents) - anatomy_updates["parent"] = parent_name + + hierarchy = "/".join(parents) + anatomy_updates.update({ + "asset": asset_doc["name"], + "hierarchy": hierarchy, + "parent": parent_name, + "folder": { + "name": asset_doc["name"], + }, + }) # Task task_type = None From 6c7e5c66a6b85e2ee8e42c2c9b38ea6639d9dd42 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 30 Oct 2023 21:13:42 +0800 Subject: [PATCH 163/690] support invalid checks on different variable types of attributes in Maxscript & repair actions --- .../plugins/publish/validate_attributes.py | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index fa9912de07..f266b2bca1 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -42,16 +42,16 @@ class ValidateAttributes(OptionalPyblishPluginMixin, for key, value in property_name.items(): property_key = rt.Execute("{}.{}".format( wrap_object, key)) - if isinstance(value, str) and "#" not in value: - if property_key != '"{}"'.format(value): - invalid_attributes.append(key) - - elif isinstance(value, bool): - if property_key != value: - invalid_attributes.append(key) + if isinstance(value, str) and ( + value.startswith("#") and not value.endswith(")") + ): + # not applicable for #() array value type + # and only applicable for enum i.e. #bob, #sally + if "#{}".format(property_key) != value: + invalid_attributes.append((wrap_object, key)) else: - if property_key != '{}'.format(value): - invalid_attributes.append(key) + if property_key != value: + invalid_attributes.append((wrap_object, key)) return invalid_attributes @@ -62,12 +62,14 @@ class ValidateAttributes(OptionalPyblishPluginMixin, invalid_attributes = self.get_invalid(context) if invalid_attributes: bullet_point_invalid_statement = "\n".join( - "- {}".format(invalid) for invalid in invalid_attributes + "- {}".format(invalid) for invalid + in invalid_attributes ) report = ( "Required Attribute(s) have invalid value(s).\n\n" f"{bullet_point_invalid_statement}\n\n" - "You can use repair action to fix it." + "You can use repair action to fix them if they are not\n" + "unknown property value(s)" ) raise PublishValidationError( report, title="Invalid Value(s) for Required Attribute(s)") @@ -78,11 +80,16 @@ class ValidateAttributes(OptionalPyblishPluginMixin, context.data["project_settings"]["max"]["publish"] ["ValidateAttributes"]["attributes"] ) - for wrap_object, property_name in attributes.items(): - invalid_attributes = [key for key, value in property_name.items() - if rt.Execute("{}.{}".format( - wrap_object, property_name[key]))!=value] - - for attrs in invalid_attributes: - rt.Execute("{}.{}={}".format( - wrap_object, attrs, attributes[wrap_object][attrs])) + invalid_attributes = cls.get_invalid(context) + for attrs in invalid_attributes: + prop, attr = attrs + value = attributes[prop][attr] + if isinstance(value, str) and not value.startswith("#"): + attribute_fix = '{}.{}="{}"'.format( + prop, attr, value + ) + else: + attribute_fix = "{}.{}={}".format( + prop, attr, value + ) + rt.Execute(attribute_fix) From 319a236bb2bfaf59dcaa2568685fb30bc1a04e8c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 16:07:14 +0100 Subject: [PATCH 164/690] do not strip asset name --- openpype/tools/creator/window.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/creator/window.py b/openpype/tools/creator/window.py index 47f27a262a..117519e1d7 100644 --- a/openpype/tools/creator/window.py +++ b/openpype/tools/creator/window.py @@ -214,7 +214,7 @@ class CreatorWindow(QtWidgets.QDialog): asset_name = self._asset_name_input.text() # Early exit if no asset name - if not asset_name.strip(): + if not asset_name: self._build_menu() self.echo("Asset name is required ..") self._set_valid_state(False) From 027cced5f58bb6af9b476f96744bf0909c5b6ebc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 30 Oct 2023 16:40:46 +0100 Subject: [PATCH 165/690] show full folder path in look assigner --- openpype/hosts/maya/tools/mayalookassigner/commands.py | 8 +++++--- openpype/hosts/maya/tools/mayalookassigner/widgets.py | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/tools/mayalookassigner/commands.py b/openpype/hosts/maya/tools/mayalookassigner/commands.py index 5cc4f84931..86df502ecd 100644 --- a/openpype/hosts/maya/tools/mayalookassigner/commands.py +++ b/openpype/hosts/maya/tools/mayalookassigner/commands.py @@ -4,7 +4,7 @@ from collections import defaultdict import maya.cmds as cmds -from openpype.client import get_assets +from openpype.client import get_assets, get_asset_name_identifier from openpype.pipeline import ( remove_container, registered_host, @@ -128,7 +128,8 @@ def create_items_from_nodes(nodes): project_name = get_current_project_name() asset_ids = set(id_hashes.keys()) - asset_docs = get_assets(project_name, asset_ids, fields=["name"]) + fields = {"_id", "name", "data.parents"} + asset_docs = get_assets(project_name, asset_ids, fields=fields) asset_docs_by_id = { str(asset_doc["_id"]): asset_doc for asset_doc in asset_docs @@ -156,8 +157,9 @@ def create_items_from_nodes(nodes): namespace = get_namespace_from_node(node) namespaces.add(namespace) + label = get_asset_name_identifier(asset_doc) asset_view_items.append({ - "label": asset_doc["name"], + "label": label, "asset": asset_doc, "looks": looks, "namespaces": namespaces diff --git a/openpype/hosts/maya/tools/mayalookassigner/widgets.py b/openpype/hosts/maya/tools/mayalookassigner/widgets.py index 82c37e2104..ef29a4c726 100644 --- a/openpype/hosts/maya/tools/mayalookassigner/widgets.py +++ b/openpype/hosts/maya/tools/mayalookassigner/widgets.py @@ -3,6 +3,7 @@ from collections import defaultdict from qtpy import QtWidgets, QtCore +from openpype.client import get_asset_name_identifier from openpype.tools.utils.models import TreeModel from openpype.tools.utils.lib import ( preserve_expanded_rows, @@ -126,7 +127,7 @@ class AssetOutliner(QtWidgets.QWidget): asset_namespaces = defaultdict(set) for item in items: asset_id = str(item["asset"]["_id"]) - asset_name = item["asset"]["name"] + asset_name = get_asset_name_identifier(item["asset"]) asset_namespaces[asset_name].add(item.get("namespace")) if asset_name in assets: From 246c408ce7036de973b1dc6ba1d918f5670d495c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 30 Oct 2023 22:21:46 +0100 Subject: [PATCH 166/690] Maya: Remove RenderSetup layer observers that are not needed since new publisher --- openpype/hosts/maya/api/lib.py | 153 ---------------------------- openpype/hosts/maya/api/pipeline.py | 10 -- 2 files changed, 163 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 7c49c837e9..6d785234c5 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -3069,159 +3069,6 @@ def _get_render_instances(): return instances -renderItemObserverList = [] - - -class RenderSetupListObserver: - """Observer to catch changes in render setup layers.""" - - def listItemAdded(self, item): - print("--- adding ...") - self._add_render_layer(item) - - def listItemRemoved(self, item): - print("--- removing ...") - self._remove_render_layer(item.name()) - - def _add_render_layer(self, item): - render_sets = _get_render_instances() - layer_name = item.name() - - for render_set in render_sets: - members = cmds.sets(render_set, query=True) or [] - - namespace_name = "_{}".format(render_set) - if not cmds.namespace(exists=namespace_name): - index = 1 - namespace_name = "_{}".format(render_set) - try: - cmds.namespace(rm=namespace_name) - except RuntimeError: - # namespace is not empty, so we leave it untouched - pass - orignal_namespace_name = namespace_name - while(cmds.namespace(exists=namespace_name)): - namespace_name = "{}{}".format( - orignal_namespace_name, index) - index += 1 - - namespace = cmds.namespace(add=namespace_name) - - if members: - # if set already have namespaced members, use the same - # namespace as others. - namespace = members[0].rpartition(":")[0] - else: - namespace = namespace_name - - render_layer_set_name = "{}:{}".format(namespace, layer_name) - if render_layer_set_name in members: - continue - print(" - creating set for {}".format(layer_name)) - maya_set = cmds.sets(n=render_layer_set_name, empty=True) - cmds.sets(maya_set, forceElement=render_set) - rio = RenderSetupItemObserver(item) - print("- adding observer for {}".format(item.name())) - item.addItemObserver(rio.itemChanged) - renderItemObserverList.append(rio) - - def _remove_render_layer(self, layer_name): - render_sets = _get_render_instances() - - for render_set in render_sets: - members = cmds.sets(render_set, query=True) - if not members: - continue - - # all sets under set should have the same namespace - namespace = members[0].rpartition(":")[0] - render_layer_set_name = "{}:{}".format(namespace, layer_name) - - if render_layer_set_name in members: - print(" - removing set for {}".format(layer_name)) - cmds.delete(render_layer_set_name) - - -class RenderSetupItemObserver: - """Handle changes in render setup items.""" - - def __init__(self, item): - self.item = item - self.original_name = item.name() - - def itemChanged(self, *args, **kwargs): - """Item changed callback.""" - if self.item.name() == self.original_name: - return - - render_sets = _get_render_instances() - - for render_set in render_sets: - members = cmds.sets(render_set, query=True) - if not members: - continue - - # all sets under set should have the same namespace - namespace = members[0].rpartition(":")[0] - render_layer_set_name = "{}:{}".format( - namespace, self.original_name) - - if render_layer_set_name in members: - print(" <> renaming {} to {}".format(self.original_name, - self.item.name())) - cmds.rename(render_layer_set_name, - "{}:{}".format( - namespace, self.item.name())) - self.original_name = self.item.name() - - -renderListObserver = RenderSetupListObserver() - - -def add_render_layer_change_observer(): - import maya.app.renderSetup.model.renderSetup as renderSetup - - rs = renderSetup.instance() - render_sets = _get_render_instances() - - layers = rs.getRenderLayers() - for render_set in render_sets: - members = cmds.sets(render_set, query=True) - if not members: - continue - # all sets under set should have the same namespace - namespace = members[0].rpartition(":")[0] - for layer in layers: - render_layer_set_name = "{}:{}".format(namespace, layer.name()) - if render_layer_set_name not in members: - continue - rio = RenderSetupItemObserver(layer) - print("- adding observer for {}".format(layer.name())) - layer.addItemObserver(rio.itemChanged) - renderItemObserverList.append(rio) - - -def add_render_layer_observer(): - import maya.app.renderSetup.model.renderSetup as renderSetup - - print("> adding renderSetup observer ...") - rs = renderSetup.instance() - rs.addListObserver(renderListObserver) - pass - - -def remove_render_layer_observer(): - import maya.app.renderSetup.model.renderSetup as renderSetup - - print("< removing renderSetup observer ...") - rs = renderSetup.instance() - try: - rs.removeListObserver(renderListObserver) - except ValueError: - # no observer set yet - pass - - def update_content_on_context_change(): """ This will update scene content to match new asset on context change diff --git a/openpype/hosts/maya/api/pipeline.py b/openpype/hosts/maya/api/pipeline.py index 6b791c9665..1ecfdfaa40 100644 --- a/openpype/hosts/maya/api/pipeline.py +++ b/openpype/hosts/maya/api/pipeline.py @@ -580,20 +580,11 @@ def on_save(): lib.set_id(node, new_id, overwrite=False) -def _update_render_layer_observers(): - # Helper to trigger update for all renderlayer observer logic - lib.remove_render_layer_observer() - lib.add_render_layer_observer() - lib.add_render_layer_change_observer() - - def on_open(): """On scene open let's assume the containers have changed.""" from openpype.widgets import popup - utils.executeDeferred(_update_render_layer_observers) - # Validate FPS after update_task_from_path to # ensure it is using correct FPS for the asset lib.validate_fps() @@ -630,7 +621,6 @@ def on_new(): with lib.suspended_refresh(): lib.set_context_settings() - utils.executeDeferred(_update_render_layer_observers) _remove_workfile_lock() From 90c8922a8a53f0e2265ca8037d1593d9da6559d3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 30 Oct 2023 22:54:54 +0100 Subject: [PATCH 167/690] Remove remaining unused function --- openpype/hosts/maya/api/lib.py | 37 ---------------------------------- 1 file changed, 37 deletions(-) diff --git a/openpype/hosts/maya/api/lib.py b/openpype/hosts/maya/api/lib.py index 6d785234c5..2d394893cd 100644 --- a/openpype/hosts/maya/api/lib.py +++ b/openpype/hosts/maya/api/lib.py @@ -115,8 +115,6 @@ _alembic_options = { INT_FPS = {15, 24, 25, 30, 48, 50, 60, 44100, 48000} FLOAT_FPS = {23.98, 23.976, 29.97, 47.952, 59.94} -RENDERLIKE_INSTANCE_FAMILIES = ["rendering", "vrayscene"] - DISPLAY_LIGHTS_ENUM = [ {"label": "Use Project Settings", "value": "project_settings"}, @@ -3034,41 +3032,6 @@ class shelf(): cmds.shelfLayout(self.name, p="ShelfLayout") -def _get_render_instances(): - """Return all 'render-like' instances. - - This returns list of instance sets that needs to receive information - about render layer changes. - - Returns: - list: list of instances - - """ - objectset = cmds.ls("*.id", long=True, exactType="objectSet", - recursive=True, objectsOnly=True) - - instances = [] - for objset in objectset: - if not cmds.attributeQuery("id", node=objset, exists=True): - continue - - id_attr = "{}.id".format(objset) - if cmds.getAttr(id_attr) != "pyblish.avalon.instance": - continue - - has_family = cmds.attributeQuery("family", - node=objset, - exists=True) - if not has_family: - continue - - if cmds.getAttr( - "{}.family".format(objset)) in RENDERLIKE_INSTANCE_FAMILIES: - instances.append(objset) - - return instances - - def update_content_on_context_change(): """ This will update scene content to match new asset on context change From 32e88ebc9663431dcc58a62c8e4a4bb784848966 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 30 Oct 2023 23:47:53 +0100 Subject: [PATCH 168/690] Show workfiles tool if current file is not set to make it clear there's user interaction needed to save --- openpype/hosts/resolve/api/menu.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/resolve/api/menu.py b/openpype/hosts/resolve/api/menu.py index 160cc44fdb..9c6fe4957c 100644 --- a/openpype/hosts/resolve/api/menu.py +++ b/openpype/hosts/resolve/api/menu.py @@ -118,6 +118,9 @@ class OpenPypeMenu(QtWidgets.QWidget): host = registered_host() current_file = host.get_current_workfile() if not current_file: + print("Current project is not saved. " + "Please save once first via workfiles tool.") + host_tools.show_workfiles() return print(f"Saving current file to: {current_file}") From f0b8d8d79826df7c27650dfbe68046e2d2d63d9d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 14:19:37 +0800 Subject: [PATCH 169/690] add docstrings and clean up the codes on the validator --- .../plugins/publish/validate_attributes.py | 80 +++++++++++++------ 1 file changed, 55 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index f266b2bca1..f603934eed 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -10,9 +10,47 @@ from openpype.pipeline.publish import ( ) +def has_property(object_name, property_name): + """Return whether an object has a property with given name""" + return rt.Execute(f'isProperty {object_name} "{property_name}"') + +def is_matching_value(object_name, property_name, value): + """Return whether an existing property matches value `value""" + property_value = rt.Execute(f"{object_name}.{property_name}") + + # Wrap property value if value is a string valued attributes + # starting with a `#` + if ( + isinstance(value, str) and + value.startswith("#") and + not value.endswith(")") + ): + # prefix value with `#` + # not applicable for #() array value type + # and only applicable for enum i.e. #bob, #sally + property_value = f"#{property_value}" + + return property_value == value + + class ValidateAttributes(OptionalPyblishPluginMixin, ContextPlugin): - """Validates attributes are consistent in 3ds max.""" + """Validates attributes in the project setting are consistent + with the nodes from MaxWrapper Class in 3ds max. + E.g. "renderers.current.separateAovFiles", + "renderers.production.PrimaryGIEngine" + Admin(s) need to put json below and enable this validator for a check: + { + "renderers.current":{ + "separateAovFiles" : True + } + "renderers.production":{ + "PrimaryGIEngine": "#RS_GIENGINE_BRUTE_FORCE", + } + .... + } + + """ order = ValidatorOrder hosts = ["max"] @@ -28,32 +66,24 @@ class ValidateAttributes(OptionalPyblishPluginMixin, ) if not attributes: return + invalid = [] + for object_name, required_properties in attributes.items(): + if not rt.Execute(f"isValidValue {object_name}"): + # Skip checking if the node does not + # exist in MaxWrapper Class + continue - for wrap_object, property_name in attributes.items(): - invalid_properties = [key for key in property_name.keys() - if not rt.Execute( - f'isProperty {wrap_object} "{key}"')] - if invalid_properties: - cls.log.error( - "Unknown Property Values:{}".format(invalid_properties)) - return invalid_properties - # TODO: support multiple varaible types in maxscript - invalid_attributes = [] - for key, value in property_name.items(): - property_key = rt.Execute("{}.{}".format( - wrap_object, key)) - if isinstance(value, str) and ( - value.startswith("#") and not value.endswith(")") - ): - # not applicable for #() array value type - # and only applicable for enum i.e. #bob, #sally - if "#{}".format(property_key) != value: - invalid_attributes.append((wrap_object, key)) - else: - if property_key != value: - invalid_attributes.append((wrap_object, key)) + for property_name, value in required_properties.items(): + if not has_property(object_name, property_name): + cls.log.error(f"Non-existing property: {object_name}.{property_name}") + invalid.append((object_name, property_name)) - return invalid_attributes + if not is_matching_value(object_name, property_name, value): + cls.log.error( + f"Invalid value for: {object_name}.{property_name}. Should be: {value}") + invalid.append((object_name, property_name)) + + return invalid def process(self, context): if not self.is_active(context.data): From 4c204a87a917ef05bf5b23e3f180d4f95650a3fb Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 14:20:25 +0800 Subject: [PATCH 170/690] hound --- openpype/hosts/max/plugins/publish/validate_attributes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index f603934eed..44d6c64139 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -14,6 +14,7 @@ def has_property(object_name, property_name): """Return whether an object has a property with given name""" return rt.Execute(f'isProperty {object_name} "{property_name}"') + def is_matching_value(object_name, property_name, value): """Return whether an existing property matches value `value""" property_value = rt.Execute(f"{object_name}.{property_name}") From 33a21674c5e752c19be8636ab6587f38f91f8f59 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 14:21:37 +0800 Subject: [PATCH 171/690] hound --- openpype/hosts/max/plugins/publish/validate_attributes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 44d6c64139..5697237c95 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -76,12 +76,14 @@ class ValidateAttributes(OptionalPyblishPluginMixin, for property_name, value in required_properties.items(): if not has_property(object_name, property_name): - cls.log.error(f"Non-existing property: {object_name}.{property_name}") + cls.log.error( + f"Non-existing property: {object_name}.{property_name}") invalid.append((object_name, property_name)) if not is_matching_value(object_name, property_name, value): cls.log.error( - f"Invalid value for: {object_name}.{property_name}. Should be: {value}") + f"Invalid value for: {object_name}.{property_name}" + f". Should be: {value}") invalid.append((object_name, property_name)) return invalid From ce80ca2397c7ed9b609f0358a9c0595289a8e260 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 16:10:22 +0800 Subject: [PATCH 172/690] debug message --- openpype/hosts/max/plugins/publish/validate_attributes.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 5697237c95..00b9d34c06 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -72,6 +72,8 @@ class ValidateAttributes(OptionalPyblishPluginMixin, if not rt.Execute(f"isValidValue {object_name}"): # Skip checking if the node does not # exist in MaxWrapper Class + cls.log.debug(f"Unable to find '{object_name}'." + f" Skipping validation of attributes") continue for property_name, value in required_properties.items(): From 3218b8064cdd00f7efab87bab935e1c8cb130c16 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 16:11:57 +0800 Subject: [PATCH 173/690] hound & docstring tweak --- openpype/hosts/max/plugins/publish/validate_attributes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 00b9d34c06..75d3f05d07 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -46,7 +46,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, "separateAovFiles" : True } "renderers.production":{ - "PrimaryGIEngine": "#RS_GIENGINE_BRUTE_FORCE", + "PrimaryGIEngine": "#RS_GIENGINE_BRUTE_FORCE" } .... } @@ -79,7 +79,8 @@ class ValidateAttributes(OptionalPyblishPluginMixin, for property_name, value in required_properties.items(): if not has_property(object_name, property_name): cls.log.error( - f"Non-existing property: {object_name}.{property_name}") + "Non-existing property: " + f"{object_name}.{property_name}") invalid.append((object_name, property_name)) if not is_matching_value(object_name, property_name, value): From 3606f312b0f671404cea584dfdca2d9af749e18c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 16:33:06 +0800 Subject: [PATCH 174/690] fix the wrong aspect ratio and viewport doesn't maximize to 1 during context --- openpype/hosts/max/api/preview_animation.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index 1bf99b86d0..bef5741343 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -23,8 +23,8 @@ def play_preview_when_done(has_autoplay): @contextlib.contextmanager -def viewport_camera(camera): - """Set viewport camera during context +def viewport_layout_and_camera(camera): + """Set viewport layout and camera during context ***For 3dsMax 2024+ Args: camera (str): viewport camera @@ -36,9 +36,12 @@ def viewport_camera(camera): original = rt.getNodeByName(camera) review_camera = rt.getNodeByName(camera) try: + if rt.viewport.getLayout() != rt.Name("layout_1"): + rt.viewport.setLayout(rt.Name("layout_1")) rt.viewport.setCamera(review_camera) yield finally: + rt.viewport.ResetAllViews() rt.viewport.setCamera(original) @@ -162,6 +165,7 @@ def _render_preview_animation_max_pre_2024( Returns: list: Created filepaths """ + # get the screenshot percent = percentSize / 100.0 res_width = int(round(rt.renderWidth * percent)) @@ -190,7 +194,7 @@ def _render_preview_animation_max_pre_2024( widthCrop = dib_height * renderRatio leftEdge = int((dib_width - widthCrop) / 2.0) tempImage_bmp = rt.bitmap(widthCrop, dib_height) - src_box_value = rt.Box2(0, leftEdge, dib_width, dib_height) + src_box_value = rt.Box2(0, leftEdge, widthCrop, dib_height) rt.pasteBitmap(dib, tempImage_bmp, src_box_value, rt.Point2(0, 0)) # copy the bitmap and close it rt.copy(tempImage_bmp, preview_res) @@ -243,7 +247,7 @@ def render_preview_animation( if viewport_options is None: viewport_options = viewport_options_for_preview_animation() with play_preview_when_done(False): - with viewport_camera(camera): + with viewport_layout_and_camera(camera): with render_resolution(width, height): if int(get_max_version()) < 2024: with viewport_preference_setting( From e120b55fa47d7b716aa71122f4ecc3aa93ff6a06 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 17:13:24 +0800 Subject: [PATCH 175/690] setLayout in regards to original layout --- openpype/hosts/max/api/preview_animation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index bef5741343..22de298175 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -29,11 +29,12 @@ def viewport_layout_and_camera(camera): Args: camera (str): viewport camera """ - original = rt.viewport.getCamera() - if not original: + original_camera = rt.viewport.getCamera() + original_layout = rt.viewport.getLayout() + if not original_camera: # if there is no original camera # use the current camera as original - original = rt.getNodeByName(camera) + original_camera = rt.getNodeByName(camera) review_camera = rt.getNodeByName(camera) try: if rt.viewport.getLayout() != rt.Name("layout_1"): @@ -41,8 +42,8 @@ def viewport_layout_and_camera(camera): rt.viewport.setCamera(review_camera) yield finally: - rt.viewport.ResetAllViews() - rt.viewport.setCamera(original) + rt.viewport.setLayout(original_layout) + rt.viewport.setCamera(original_camera) @contextlib.contextmanager From 009cda005227158561d898aa59c28ca16ae4166c Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 17:18:06 +0800 Subject: [PATCH 176/690] update the debug message with dots --- openpype/hosts/max/plugins/publish/validate_attributes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 75d3f05d07..172b65e955 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -73,7 +73,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, # Skip checking if the node does not # exist in MaxWrapper Class cls.log.debug(f"Unable to find '{object_name}'." - f" Skipping validation of attributes") + " Skipping validation of attributes.") continue for property_name, value in required_properties.items(): @@ -86,7 +86,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, if not is_matching_value(object_name, property_name, value): cls.log.error( f"Invalid value for: {object_name}.{property_name}" - f". Should be: {value}") + f" Should be: {value}") invalid.append((object_name, property_name)) return invalid @@ -105,7 +105,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, "Required Attribute(s) have invalid value(s).\n\n" f"{bullet_point_invalid_statement}\n\n" "You can use repair action to fix them if they are not\n" - "unknown property value(s)" + "unknown property value(s)." ) raise PublishValidationError( report, title="Invalid Value(s) for Required Attribute(s)") From dadd258cf1f1938ef609ecec689d08bb19815198 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 17:26:25 +0800 Subject: [PATCH 177/690] make the viewport_layout_and_camera reuseable --- openpype/hosts/max/api/preview_animation.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index 22de298175..dcf243d31e 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -23,11 +23,13 @@ def play_preview_when_done(has_autoplay): @contextlib.contextmanager -def viewport_layout_and_camera(camera): +def viewport_layout_and_camera(camera, layout="layout_1"): """Set viewport layout and camera during context ***For 3dsMax 2024+ Args: camera (str): viewport camera + layout (str): layout to use in viewport, defaults to `layout_1` + Use None to not change viewport layout during context. """ original_camera = rt.viewport.getCamera() original_layout = rt.viewport.getLayout() @@ -37,8 +39,10 @@ def viewport_layout_and_camera(camera): original_camera = rt.getNodeByName(camera) review_camera = rt.getNodeByName(camera) try: - if rt.viewport.getLayout() != rt.Name("layout_1"): - rt.viewport.setLayout(rt.Name("layout_1")) + if layout is not None: + layout = rt.Name(layout) + if rt.viewport.getLayout() != layout: + rt.viewport.setLayout(layout) rt.viewport.setCamera(review_camera) yield finally: From ad0b941475c67196ad7e09beada2bd81b2d51a63 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 17:28:42 +0800 Subject: [PATCH 178/690] lowercase invalid msg for the condition of not is_maching_value function --- openpype/hosts/max/plugins/publish/validate_attributes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 172b65e955..0cd405aebd 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -86,7 +86,7 @@ class ValidateAttributes(OptionalPyblishPluginMixin, if not is_matching_value(object_name, property_name, value): cls.log.error( f"Invalid value for: {object_name}.{property_name}" - f" Should be: {value}") + f" should be: {value}") invalid.append((object_name, property_name)) return invalid From 6daa1b898a2cfe13509c71861816fad221778816 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 31 Oct 2023 10:47:23 +0000 Subject: [PATCH 179/690] Use collections as asset group for blendscene family --- .../plugins/create/create_blendScene.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index 63bcf212ff..96e63924d3 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -31,21 +31,11 @@ class CreateBlendScene(plugin.Creator): asset = self.data["asset"] subset = self.data["subset"] name = plugin.asset_name(asset, subset) - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) + + # Create the new asset group as collection + asset_group = bpy.data.collections.new(name=name) + instances.children.link(asset_group) self.data['task'] = get_current_task_name() lib.imprint(asset_group, self.data) - # Add selected objects to instance - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - bpy.ops.object.parent_set(keep_transform=True) - return asset_group From 1c45fa139b38ea8f2c9055613a5f536f2b9fa40e Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 31 Oct 2023 10:48:05 +0000 Subject: [PATCH 180/690] Include collections asset group to get unique number --- openpype/hosts/blender/api/plugin.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index fb87d08cce..45b0c60b3b 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -9,7 +9,10 @@ from openpype.pipeline import ( LegacyCreator, LoaderPlugin, ) -from .pipeline import AVALON_CONTAINERS +from .pipeline import ( + AVALON_CONTAINERS, + AVALON_PROPERTY, +) from .ops import ( MainThreadItem, execute_in_main_thread @@ -40,9 +43,16 @@ def get_unique_number( avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) if not avalon_container: return "01" - asset_groups = avalon_container.all_objects - - container_names = [c.name for c in asset_groups if c.type == 'EMPTY'] + # Check the names of both object and collection containers + obj_asset_groups = avalon_container.all_objects + obj_group_names = [ + c.name for c in obj_asset_groups + if c.type == 'EMPTY' and c.get(AVALON_PROPERTY)] + coll_asset_groups = avalon_container.children_recursive + coll_group_names = [ + c.name for c in coll_asset_groups + if c.get(AVALON_PROPERTY)] + container_names = obj_group_names + coll_group_names count = 1 name = f"{asset}_{count:0>2}_{subset}" while name in container_names: From a180a276a3838dd9b433e03c7e52b46bd39d5886 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 31 Oct 2023 10:49:17 +0000 Subject: [PATCH 181/690] Add check that instance is object to pack images --- .../hosts/blender/plugins/publish/extract_blend.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index c8eeef7fd7..4b6d9e7c69 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -25,11 +25,11 @@ class ExtractBlend(publish.Extractor): data_blocks = set() - for obj in instance: - data_blocks.add(obj) - # Pack used images in the blend files. - if obj.type == 'MESH': - for material_slot in obj.material_slots: + for data in instance: + data_blocks.add(data) + if isinstance(data, bpy.types.Object) and data.type == 'MESH': + # Pack used images in the blend files. + for material_slot in data.material_slots: mat = material_slot.material if mat and mat.use_nodes: tree = mat.node_tree From 371f9a52755a6c761b87ff1e6a07fe59384acbc1 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 31 Oct 2023 11:49:17 +0100 Subject: [PATCH 182/690] Bugfix: Collect Rendered Files only collecting first instance (#5832) * Bugfix: Collect all instances from the metadata file - don't return on first iteration * Fix initial state of variable --- .../plugins/publish/collect_rendered_files.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/openpype/plugins/publish/collect_rendered_files.py b/openpype/plugins/publish/collect_rendered_files.py index 8a5a5a83f1..a249b3acda 100644 --- a/openpype/plugins/publish/collect_rendered_files.py +++ b/openpype/plugins/publish/collect_rendered_files.py @@ -56,6 +56,17 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): data_object["stagingDir"] = anatomy.fill_root(staging_dir) def _process_path(self, data, anatomy): + """Process data of a single JSON publish metadata file. + + Args: + data: The loaded metadata from the JSON file + anatomy: Anatomy for the current context + + Returns: + bool: Whether any instance of this particular metadata file + has a persistent staging dir. + + """ # validate basic necessary data data_err = "invalid json file - missing data" required = ["asset", "user", "comment", @@ -89,6 +100,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): os.environ["FTRACK_SERVER"] = ftrack["FTRACK_SERVER"] # now we can just add instances from json file and we are done + any_staging_dir_persistent = False for instance_data in data.get("instances"): self.log.debug(" - processing instance for {}".format( @@ -106,6 +118,9 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): staging_dir_persistent = instance.data.get( "stagingDir_persistent", False ) + if staging_dir_persistent: + any_staging_dir_persistent = True + representations = [] for repre_data in instance_data.get("representations") or []: self._fill_staging_dir(repre_data, anatomy) @@ -127,7 +142,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): self.log.debug( f"Adding audio to instance: {instance.data['audio']}") - return staging_dir_persistent + return any_staging_dir_persistent def process(self, context): self._context = context From fd30a0426cb2a10b93384e8a6ce898e57b7d5114 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 31 Oct 2023 10:49:58 +0000 Subject: [PATCH 183/690] Separate blendscene loader from blend loader --- .../hosts/blender/plugins/load/load_blend.py | 2 +- .../blender/plugins/load/load_blendscene.py | 215 ++++++++++++++++++ 2 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 openpype/hosts/blender/plugins/load/load_blendscene.py diff --git a/openpype/hosts/blender/plugins/load/load_blend.py b/openpype/hosts/blender/plugins/load/load_blend.py index 25d6568889..0719c5c97d 100644 --- a/openpype/hosts/blender/plugins/load/load_blend.py +++ b/openpype/hosts/blender/plugins/load/load_blend.py @@ -20,7 +20,7 @@ from openpype.hosts.blender.api.pipeline import ( class BlendLoader(plugin.AssetLoader): """Load assets from a .blend file.""" - families = ["model", "rig", "layout", "camera", "blendScene"] + families = ["model", "rig", "layout", "camera"] representations = ["blend"] label = "Append Blend" diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py new file mode 100644 index 0000000000..8c43f40bdd --- /dev/null +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -0,0 +1,215 @@ +from typing import Dict, List, Optional +from pathlib import Path + +import bpy + +from openpype.pipeline import ( + get_representation_path, + AVALON_CONTAINER_ID, +) +from openpype.pipeline.create import get_legacy_creator_by_name +from openpype.hosts.blender.api import plugin +from openpype.hosts.blender.api.lib import imprint +from openpype.hosts.blender.api.pipeline import ( + AVALON_CONTAINERS, + AVALON_PROPERTY, +) + + +class BlendSceneLoader(plugin.AssetLoader): + """Load assets from a .blend file.""" + + families = ["blendScene"] + representations = ["blend"] + + label = "Append Blend" + icon = "code-fork" + color = "orange" + + @staticmethod + def _get_asset_container(collections): + for coll in collections: + parents = [c for c in collections if c.user_of_id(coll)] + if coll.get(AVALON_PROPERTY) and not parents: + return coll + + return None + + def _process_data(self, libpath, group_name, family): + # Append all the data from the .blend file + with bpy.data.libraries.load( + libpath, link=False, relative=False + ) as (data_from, data_to): + for attr in dir(data_to): + setattr(data_to, attr, getattr(data_from, attr)) + + members = [] + + # Rename the object to add the asset name + for attr in dir(data_to): + for data in getattr(data_to, attr): + data.name = f"{group_name}:{data.name}" + members.append(data) + + container = self._get_asset_container( + data_to.collections) + assert container, "No asset group found" + + container.name = group_name + + # Link the group to the scene + bpy.context.scene.collection.children.link(container) + + # Remove the library from the blend file + library = bpy.data.libraries.get(bpy.path.basename(libpath)) + bpy.data.libraries.remove(library) + + return container, members + + def process_asset( + self, context: dict, name: str, namespace: Optional[str] = None, + options: Optional[Dict] = None + ) -> Optional[List]: + """ + Arguments: + name: Use pre-defined name + namespace: Use pre-defined namespace + context: Full parenthood of representation to load + options: Additional settings dictionary + """ + libpath = self.filepath_from_context(context) + asset = context["asset"]["name"] + subset = context["subset"]["name"] + + try: + family = context["representation"]["context"]["family"] + except ValueError: + family = "model" + + asset_name = plugin.asset_name(asset, subset) + unique_number = plugin.get_unique_number(asset, subset) + group_name = plugin.asset_name(asset, subset, unique_number) + namespace = namespace or f"{asset}_{unique_number}" + + avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) + if not avalon_container: + avalon_container = bpy.data.collections.new(name=AVALON_CONTAINERS) + bpy.context.scene.collection.children.link(avalon_container) + + container, members = self._process_data(libpath, group_name, family) + + avalon_container.children.link(container) + + data = { + "schema": "openpype:container-2.0", + "id": AVALON_CONTAINER_ID, + "name": name, + "namespace": namespace or '', + "loader": str(self.__class__.__name__), + "representation": str(context["representation"]["_id"]), + "libpath": libpath, + "asset_name": asset_name, + "parent": str(context["representation"]["parent"]), + "family": context["representation"]["context"]["family"], + "objectName": group_name, + "members": members, + } + + container[AVALON_PROPERTY] = data + + objects = [ + obj for obj in bpy.data.objects + if obj.name.startswith(f"{group_name}:") + ] + + self[:] = objects + return objects + + def exec_update(self, container: Dict, representation: Dict): + """ + Update the loaded asset. + """ + group_name = container["objectName"] + asset_group = bpy.data.collections.get(group_name) + libpath = Path(get_representation_path(representation)).as_posix() + + assert asset_group, ( + f"The asset is not loaded: {container['objectName']}" + ) + + collection_parents = {} + members = asset_group.get(AVALON_PROPERTY).get("members", []) + loaded_collections = {c for c in bpy.data.collections if c in members} + loaded_collections.add(bpy.data.collections.get(AVALON_CONTAINERS)) + for member in members: + if isinstance(member, bpy.types.Object): + member_parents = set(member.users_collection) + elif isinstance(member, bpy.types.Collection): + member_parents = { + c for c in bpy.data.collections if c.user_of_id(member)} + else: + continue + + member_parents = member_parents.difference(loaded_collections) + if member_parents: + collection_parents[member.name] = list(member_parents) + + old_data = dict(asset_group.get(AVALON_PROPERTY)) + + self.exec_remove(container) + + family = container["family"] + asset_group, members = self._process_data(libpath, group_name, family) + + for member in members: + if member.name in collection_parents: + for parent in collection_parents[member.name]: + if isinstance(member, bpy.types.Object): + parent.objects.link(member) + elif isinstance(member, bpy.types.Collection): + parent.children.link(member) + + avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) + avalon_container.children.link(asset_group) + + # Restore the old data, but reset memebers, as they don't exist anymore + # This avoids a crash, because the memory addresses of those members + # are not valid anymore + old_data["members"] = [] + asset_group[AVALON_PROPERTY] = old_data + + new_data = { + "libpath": libpath, + "representation": str(representation["_id"]), + "parent": str(representation["parent"]), + "members": members, + } + + imprint(asset_group, new_data) + + def exec_remove(self, container: Dict) -> bool: + """ + Remove an existing container from a Blender scene. + """ + group_name = container["objectName"] + asset_group = bpy.data.collections.get(group_name) + + attrs = [ + attr for attr in dir(bpy.data) + if isinstance( + getattr(bpy.data, attr), + bpy.types.bpy_prop_collection + ) + ] + + members = asset_group.get(AVALON_PROPERTY).get("members", []) + + for attr in attrs: + for data in getattr(bpy.data, attr): + if data in members: + # Skip the asset group + if data == asset_group: + continue + getattr(bpy.data, attr).remove(data) + + bpy.data.collections.remove(asset_group) From 6ec87aa06df1dbb7f9ae28fae286e61e73ba3355 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 31 Oct 2023 11:10:20 +0000 Subject: [PATCH 184/690] Hound fixes --- openpype/hosts/blender/plugins/load/load_blendscene.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py index 8c43f40bdd..fe7afb3119 100644 --- a/openpype/hosts/blender/plugins/load/load_blendscene.py +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -7,7 +7,6 @@ from openpype.pipeline import ( get_representation_path, AVALON_CONTAINER_ID, ) -from openpype.pipeline.create import get_legacy_creator_by_name from openpype.hosts.blender.api import plugin from openpype.hosts.blender.api.lib import imprint from openpype.hosts.blender.api.pipeline import ( From e39689ba8e1a7a9de754ecf5becb487d5fda7665 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 20:28:15 +0800 Subject: [PATCH 185/690] add docs --- website/docs/artist_hosts_3dsmax.md | 24 ++++++++++++++++++ .../assets/3dsmax_validate_attributes.png | Bin 0 -> 35154 bytes 2 files changed, 24 insertions(+) create mode 100644 website/docs/assets/3dsmax_validate_attributes.png diff --git a/website/docs/artist_hosts_3dsmax.md b/website/docs/artist_hosts_3dsmax.md index fffab8ca5d..bc79094746 100644 --- a/website/docs/artist_hosts_3dsmax.md +++ b/website/docs/artist_hosts_3dsmax.md @@ -118,4 +118,28 @@ Current OpenPype integration (ver 3.15.0) supports only ```PointCache```, ```Ca This part of documentation is still work in progress. ::: +## Validators + +Current Openpype integration supports different validators such as Frame Range and Attributes. +Some validators are mandatory while some are optional and user can choose to enable them in the setting. + +**Validate Frame Range**: Optional Validator for checking Frame Range + +**Validate Attributes**: Optional Validator for checking if object properties' attributes are valid + in MaxWrapper Class. +:::note + Users can write the properties' attributes they want to check in dict format in the setting + before validation. + E.g. ```renderers.current.separateAovFiles``` and ```renderers.current.PrimaryGIEngine``` + User can put the attributes in the dict format below + ``` + { + "renderer.current":{ + "separateAovFiles" : True + "PrimaryGIEngine": "#RS_GIENGINE_BRUTE_FORCE" + } + } + ``` + ![Validate Attribute Setting](assets/3dsmax_validate_attributes.png) +::: ## ...to be added diff --git a/website/docs/assets/3dsmax_validate_attributes.png b/website/docs/assets/3dsmax_validate_attributes.png new file mode 100644 index 0000000000000000000000000000000000000000..5af82361887f47fda96607886ec10e15eb355df1 GIT binary patch literal 35154 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 FpM9ou89oV;b5Eca*vLo#<6{~%iTY)O)Z@( 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 sPpdcV0Zhn($&0bNe4%m4rY literal 0 HcmV?d00001 From 1795d501d995f037af9ad81d8731f14b67a7f19e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 20:29:34 +0800 Subject: [PATCH 186/690] add docs --- website/docs/artist_hosts_3dsmax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/artist_hosts_3dsmax.md b/website/docs/artist_hosts_3dsmax.md index bc79094746..6f23a19103 100644 --- a/website/docs/artist_hosts_3dsmax.md +++ b/website/docs/artist_hosts_3dsmax.md @@ -129,7 +129,7 @@ Some validators are mandatory while some are optional and user can choose to ena in MaxWrapper Class. :::note Users can write the properties' attributes they want to check in dict format in the setting - before validation. + before validation. The attributes are then to be converted into Maxscript and do a check. E.g. ```renderers.current.separateAovFiles``` and ```renderers.current.PrimaryGIEngine``` User can put the attributes in the dict format below ``` From cfd9f0f06c26c0d47340f9baf42239674e2cebc8 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 31 Oct 2023 20:32:28 +0800 Subject: [PATCH 187/690] edit docstring --- openpype/hosts/max/plugins/publish/validate_attributes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_attributes.py b/openpype/hosts/max/plugins/publish/validate_attributes.py index 0cd405aebd..0632ee38f0 100644 --- a/openpype/hosts/max/plugins/publish/validate_attributes.py +++ b/openpype/hosts/max/plugins/publish/validate_attributes.py @@ -40,11 +40,11 @@ class ValidateAttributes(OptionalPyblishPluginMixin, with the nodes from MaxWrapper Class in 3ds max. E.g. "renderers.current.separateAovFiles", "renderers.production.PrimaryGIEngine" - Admin(s) need to put json below and enable this validator for a check: + Admin(s) need to put the dict below and enable this validator for a check: { "renderers.current":{ "separateAovFiles" : True - } + }, "renderers.production":{ "PrimaryGIEngine": "#RS_GIENGINE_BRUTE_FORCE" } From 00fb722089a80dae83fe89b387ddcc481053f053 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 31 Oct 2023 13:55:22 +0100 Subject: [PATCH 188/690] use AYON username for user in template data --- openpype/lib/local_settings.py | 6 ++++++ openpype/plugins/publish/collect_current_pype_user.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openpype/lib/local_settings.py b/openpype/lib/local_settings.py index dae6e074af..9b780fd88a 100644 --- a/openpype/lib/local_settings.py +++ b/openpype/lib/local_settings.py @@ -611,6 +611,12 @@ def get_openpype_username(): settings and last option is to use `getpass.getuser()` which returns machine username. """ + + if AYON_SERVER_ENABLED: + import ayon_api + + return ayon_api.get_user()["name"] + username = os.environ.get("OPENPYPE_USERNAME") if not username: local_settings = get_local_settings() diff --git a/openpype/plugins/publish/collect_current_pype_user.py b/openpype/plugins/publish/collect_current_pype_user.py index 2d507ba292..5c0c4fc82e 100644 --- a/openpype/plugins/publish/collect_current_pype_user.py +++ b/openpype/plugins/publish/collect_current_pype_user.py @@ -1,4 +1,6 @@ import pyblish.api + +from openpype import AYON_SERVER_ENABLED from openpype.lib import get_openpype_username @@ -7,7 +9,11 @@ class CollectCurrentUserPype(pyblish.api.ContextPlugin): # Order must be after default pyblish-base CollectCurrentUser order = pyblish.api.CollectorOrder + 0.001 - label = "Collect Pype User" + label = ( + "Collect AYON User" + if AYON_SERVER_ENABLED + else "Collect OpenPype User" + ) def process(self, context): user = get_openpype_username() From 98f91ce932c4b544f0cb6d54f6010f8d99d493c4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Tue, 31 Oct 2023 15:37:15 +0100 Subject: [PATCH 189/690] Fix typo `actions_dir` -> `path` to fix register launcher actions from OpenPypeModule --- openpype/modules/launcher_action.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/launcher_action.py b/openpype/modules/launcher_action.py index 5e14f25f76..4f0674c94f 100644 --- a/openpype/modules/launcher_action.py +++ b/openpype/modules/launcher_action.py @@ -40,7 +40,7 @@ class LauncherAction(OpenPypeModule, ITrayAction): actions_paths = self.manager.collect_plugin_paths()["actions"] for path in actions_paths: if path and os.path.exists(path): - register_launcher_action_path(actions_dir) + register_launcher_action_path(path) paths_str = os.environ.get("AVALON_ACTIONS") or "" if paths_str: From 711976e68586a6110b04a0b7d650effca08dcd30 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 31 Oct 2023 18:05:20 +0200 Subject: [PATCH 190/690] fix bug when loading shelf files --- openpype/hosts/houdini/api/shelves.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/api/shelves.py b/openpype/hosts/houdini/api/shelves.py index 4b5ebd4202..0afc737665 100644 --- a/openpype/hosts/houdini/api/shelves.py +++ b/openpype/hosts/houdini/api/shelves.py @@ -44,7 +44,7 @@ def generate_shelves(): "{}".format(shelf_set_os_filepath)) continue - hou.shelves.newShelfSet(file_path=shelf_set_os_filepath) + hou.shelves.loadFile(shelf_set_os_filepath) continue shelf_set_name = shelf_set_config.get('shelf_set_name') From dd070c6fcc0ded177fefebcf64f5272bb4d007d3 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Tue, 31 Oct 2023 18:06:06 +0200 Subject: [PATCH 191/690] Enhance shelves settings visual appeal --- .../schemas/schema_houdini_scriptshelf.json | 24 ++++++++++++------- .../houdini/server/settings/shelves.py | 14 +++++++---- server_addon/houdini/server/version.py | 2 +- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json index 35d768843d..f45377c8b4 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json @@ -7,22 +7,30 @@ "object_type": { "type": "dict", "children": [ + { + "type": "label", + "label": "Option 1: Add a .shelf file" + }, + { + "type": "path", + "key": "shelf_set_source_path", + "label": "Shelf Set Path", + "multipath": false, + "multiplatform": true + }, + { + "type": "label", + "label": "OR Option 2: Add Shelf Set Name and Shelves Definitions" + }, { "type": "text", "key": "shelf_set_name", "label": "Shelf Set Name" }, - { - "type": "path", - "key": "shelf_set_source_path", - "label": "Shelf Set Path (optional)", - "multipath": false, - "multiplatform": true - }, { "type": "list", "key": "shelf_definition", - "label": "Shelves", + "label": "Shelves Definitions", "use_label_wrap": true, "object_type": { "type": "dict", diff --git a/server_addon/houdini/server/settings/shelves.py b/server_addon/houdini/server/settings/shelves.py index 8d0512bdeb..e02ddf1c34 100644 --- a/server_addon/houdini/server/settings/shelves.py +++ b/server_addon/houdini/server/settings/shelves.py @@ -24,14 +24,18 @@ class ShelfDefinitionModel(BaseSettingsModel): class ShelvesModel(BaseSettingsModel): _layout = "expanded" - shelf_set_name: str = Field("", title="Shelfs set name") - shelf_set_source_path: MultiplatformPathModel = Field( default_factory=MultiplatformPathModel, - title="Shelf Set Path (optional)" + title="Shelf Set Path", + section="Option 1: Add a .shelf file." + ) + shelf_set_name: str = Field( + "", + title="Shelf Set Name", + section=("OR Option 2: Add Shelf Set Name " + "and Shelves Definitions.") ) - shelf_definition: list[ShelfDefinitionModel] = Field( default_factory=list, - title="Shelf Definitions" + title="Shelves Definitions" ) diff --git a/server_addon/houdini/server/version.py b/server_addon/houdini/server/version.py index 01ef12070d..6cd38b7465 100644 --- a/server_addon/houdini/server/version.py +++ b/server_addon/houdini/server/version.py @@ -1 +1 @@ -__version__ = "0.2.6" +__version__ = "0.2.7" From 918770f817e5ab1a1c930bae81a441609b4d5ce2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 31 Oct 2023 18:57:28 +0100 Subject: [PATCH 192/690] 'get_current_context_template_data' returns same values as base function 'get_template_data' --- openpype/pipeline/context_tools.py | 93 +++++++----------------------- 1 file changed, 22 insertions(+), 71 deletions(-) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 13630ae7ca..5afdb30f7b 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -25,10 +25,7 @@ from openpype.tests.lib import is_in_tests from .publish.lib import filter_pyblish_plugins from .anatomy import Anatomy -from .template_data import ( - get_template_data_with_names, - get_template_data -) +from .template_data import get_template_data_with_names from .workfile import ( get_workfile_template_key, get_custom_workfile_template_by_string_context, @@ -483,6 +480,27 @@ def get_template_data_from_session(session=None, system_settings=None): ) +def get_current_context_template_data(system_settings=None): + """Prepare template data for current context. + + Args: + system_settings (Optional[Dict[str, Any]]): Prepared system settings. + + Returns: + Dict[str, Any] Template data for current context. + """ + + context = get_current_context() + project_name = context["project_name"] + asset_name = context["asset_name"] + task_name = context["task_name"] + host_name = get_current_host_name() + + return get_template_data_with_names( + project_name, asset_name, task_name, host_name, system_settings + ) + + def get_workdir_from_session(session=None, template_key=None): """Template data for template fill from session keys. @@ -661,70 +679,3 @@ def get_process_id(): if _process_id is None: _process_id = str(uuid.uuid4()) return _process_id - - -def get_current_context_template_data(): - """Template data for template fill from current context - - Returns: - Dict[str, Any] of the following tokens and their values - Supported Tokens: - - Regular Tokens - - app - - user - - asset - - parent - - hierarchy - - folder[name] - - root[work, ...] - - studio[code, name] - - project[code, name] - - task[type, name, short] - - - Context Specific Tokens - - assetData[frameStart] - - assetData[frameEnd] - - assetData[handleStart] - - assetData[handleEnd] - - assetData[frameStartHandle] - - assetData[frameEndHandle] - - assetData[resolutionHeight] - - assetData[resolutionWidth] - - """ - - # pre-prepare get_template_data args - current_context = get_current_context() - project_name = current_context["project_name"] - asset_name = current_context["asset_name"] - anatomy = Anatomy(project_name) - - # prepare get_template_data args - project_doc = get_project(project_name) - asset_doc = get_asset_by_name(project_name, asset_name) - task_name = current_context["task_name"] - host_name = get_current_host_name() - - # get regular template data - template_data = get_template_data( - project_doc, asset_doc, task_name, host_name - ) - - template_data["root"] = anatomy.roots - - # get context specific vars - asset_data = asset_doc["data"].copy() - - # compute `frameStartHandle` and `frameEndHandle` - if "frameStart" in asset_data and "handleStart" in asset_data: - asset_data["frameStartHandle"] = \ - asset_data["frameStart"] - asset_data["handleStart"] - - if "frameEnd" in asset_data and "handleEnd" in asset_data: - asset_data["frameEndHandle"] = \ - asset_data["frameEnd"] + asset_data["handleEnd"] - - # add assetData - template_data["assetData"] = asset_data - - return template_data From 4a11eed09ba8936351ce8acf1fa06fdd0ef904fb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 31 Oct 2023 18:59:06 +0100 Subject: [PATCH 193/690] implemented new function which does what houdini requires --- openpype/hosts/houdini/api/lib.py | 56 +++++++++++++++++++++++---- openpype/hosts/houdini/api/shelves.py | 5 ++- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index cadeaa8ed4..ac375c56d6 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -11,20 +11,21 @@ import json import six from openpype.lib import StringTemplate -from openpype.client import get_asset_by_name +from openpype.client import get_project, get_asset_by_name from openpype.settings import get_current_project_settings from openpype.pipeline import ( + Anatomy, get_current_project_name, get_current_asset_name, - registered_host -) -from openpype.pipeline.context_tools import ( - get_current_context_template_data, - get_current_project_asset + registered_host, + get_current_context, + get_current_host_name, ) +from openpype.pipeline.create import CreateContext +from openpype.pipeline.template_data import get_template_data +from openpype.pipeline.context_tools import get_current_project_asset from openpype.widgets import popup from openpype.tools.utils.host_tools import get_tool_by_name -from openpype.pipeline.create import CreateContext import hou @@ -804,6 +805,45 @@ def get_camera_from_container(container): return cameras[0] +def get_current_context_template_data_with_asset_data(): + """ + TODOs: + Support both 'assetData' and 'folderData' in future. + """ + + context = get_current_context() + project_name = context["project_name"] + asset_name = context["asset_name"] + task_name = context["task_name"] + host_name = get_current_host_name() + + anatomy = Anatomy(project_name) + project_doc = get_project(project_name) + asset_doc = get_asset_by_name(project_name, asset_name) + + # get context specific vars + asset_data = asset_doc["data"] + + # compute `frameStartHandle` and `frameEndHandle` + frame_start = asset_data.get("frameStart") + frame_end = asset_data.get("frameEnd") + handle_start = asset_data.get("handleStart") + handle_end = asset_data.get("handleEnd") + if frame_start is not None and handle_start is not None: + asset_data["frameStartHandle"] = frame_start - handle_start + + if frame_end is not None and handle_end is not None: + asset_data["frameEndHandle"] = frame_end + handle_end + + template_data = get_template_data( + project_doc, asset_doc, task_name, host_name + ) + template_data["root"] = anatomy.roots + template_data["assetData"] = asset_data + + return template_data + + def get_context_var_changes(): """get context var changes.""" @@ -823,7 +863,7 @@ def get_context_var_changes(): return houdini_vars_to_update # Get Template data - template_data = get_current_context_template_data() + template_data = get_current_context_template_data_with_asset_data() # Set Houdini Vars for item in houdini_vars: diff --git a/openpype/hosts/houdini/api/shelves.py b/openpype/hosts/houdini/api/shelves.py index 4b5ebd4202..5df45a1f72 100644 --- a/openpype/hosts/houdini/api/shelves.py +++ b/openpype/hosts/houdini/api/shelves.py @@ -7,10 +7,11 @@ from openpype.settings import get_project_settings from openpype.pipeline import get_current_project_name from openpype.lib import StringTemplate -from openpype.pipeline.context_tools import get_current_context_template_data import hou +from .lib import get_current_context_template_data_with_asset_data + log = logging.getLogger("openpype.hosts.houdini.shelves") @@ -30,7 +31,7 @@ def generate_shelves(): return # Get Template data - template_data = get_current_context_template_data() + template_data = get_current_context_template_data_with_asset_data() for shelf_set_config in shelves_set_config: shelf_set_filepath = shelf_set_config.get('shelf_set_source_path') From 9e85cc17a989fa88d4df8a5a8644ccb30470270f Mon Sep 17 00:00:00 2001 From: Ynbot Date: Wed, 1 Nov 2023 03:25:26 +0000 Subject: [PATCH 194/690] [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 d6839c9b70..4865fcfb31 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.17.5-nightly.1" +__version__ = "3.17.5-nightly.2" From 15414809828905c24f89ce67547b101817d1309d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 1 Nov 2023 03:26:11 +0000 Subject: [PATCH 195/690] chore(): update bug report / version --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 73505368dd..249da3da0e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,6 +35,7 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.17.5-nightly.2 - 3.17.5-nightly.1 - 3.17.4 - 3.17.4-nightly.2 @@ -134,7 +135,6 @@ body: - 3.15.1-nightly.4 - 3.15.1-nightly.3 - 3.15.1-nightly.2 - - 3.15.1-nightly.1 validations: required: true - type: dropdown From f330f87993d6826b519c7ee949c8c1a2c21e197b Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 10:37:41 +0200 Subject: [PATCH 196/690] Add options to Houdini shelves manager settings --- .../schemas/schema_houdini_scriptshelf.json | 141 +++++++++--------- .../houdini/server/settings/shelves.py | 11 ++ 2 files changed, 85 insertions(+), 67 deletions(-) diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json index f45377c8b4..2dfce906b7 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json @@ -5,78 +5,85 @@ "is_group": true, "use_label_wrap": true, "object_type": { - "type": "dict", - "children": [ + "type": "dict-conditional", + "enum_key": "options", + "enum_label": "Options", + "enum_children": [ { - "type": "label", - "label": "Option 1: Add a .shelf file" + + "key": "add_shelf_file", + "label": "Add a .shelf file", + "children": [ + { + "type": "path", + "key": "shelf_set_source_path", + "label": "Shelf Set Path", + "multipath": false, + "multiplatform": true + } + ] }, { - "type": "path", - "key": "shelf_set_source_path", - "label": "Shelf Set Path", - "multipath": false, - "multiplatform": true - }, - { - "type": "label", - "label": "OR Option 2: Add Shelf Set Name and Shelves Definitions" - }, - { - "type": "text", - "key": "shelf_set_name", - "label": "Shelf Set Name" - }, - { - "type": "list", - "key": "shelf_definition", - "label": "Shelves Definitions", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "text", - "key": "shelf_name", - "label": "Shelf Name" - }, - { - "type": "list", - "key": "tools_list", - "label": "Tools", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "label", - "label": "Name and Script Path are mandatory." - }, - { - "type": "text", - "key": "label", - "label": "Name" - }, - { - "type": "path", - "key": "script", - "label": "Script" - }, - { - "type": "path", - "key": "icon", - "label": "Icon" - }, - { - "type": "text", - "key": "help", - "label": "Help" + "key": "add_set_and_definitions", + "label": "Add Shelf Set Name and Shelves Definitions", + "children": [ + { + "type": "text", + "key": "shelf_set_name", + "label": "Shelf Set Name" + }, + { + "type": "list", + "key": "shelf_definition", + "label": "Shelves Definitions", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "text", + "key": "shelf_name", + "label": "Shelf Name" + }, + { + "type": "list", + "key": "tools_list", + "label": "Tools", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "label", + "label": "Name and Script Path are mandatory." + }, + { + "type": "text", + "key": "label", + "label": "Name" + }, + { + "type": "path", + "key": "script", + "label": "Script" + }, + { + "type": "path", + "key": "icon", + "label": "Icon" + }, + { + "type": "text", + "key": "help", + "label": "Help" + } + ] } - ] - } + } + ] } - ] - } + } + ] } ] } diff --git a/server_addon/houdini/server/settings/shelves.py b/server_addon/houdini/server/settings/shelves.py index e02ddf1c34..651af27537 100644 --- a/server_addon/houdini/server/settings/shelves.py +++ b/server_addon/houdini/server/settings/shelves.py @@ -21,9 +21,20 @@ class ShelfDefinitionModel(BaseSettingsModel): title="Shelf Tools" ) +def shelves_enum_options(): + return [ + {"value": "add_shelf_file", "label": "Add a .shelf file"}, + {"value": "add_set_and_definitions", "label": "Add Shelf Set Name and Shelves Definitions"} + ] class ShelvesModel(BaseSettingsModel): _layout = "expanded" + options: str = Field( + title="Options", + description="Switch between shelves manager options", + enum_resolver=shelves_enum_options, + conditionalEnum=True + ) shelf_set_source_path: MultiplatformPathModel = Field( default_factory=MultiplatformPathModel, title="Shelf Set Path", From 0e331db93a0de805a55e88711d5d880f6281715e Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 11:24:48 +0200 Subject: [PATCH 197/690] Adjust Houdini Shelves Ayon settings --- .../houdini/server/settings/shelves.py | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/server_addon/houdini/server/settings/shelves.py b/server_addon/houdini/server/settings/shelves.py index 651af27537..a0acc90505 100644 --- a/server_addon/houdini/server/settings/shelves.py +++ b/server_addon/houdini/server/settings/shelves.py @@ -21,32 +21,47 @@ class ShelfDefinitionModel(BaseSettingsModel): title="Shelf Tools" ) + +class AddShelfFileModel(BaseSettingsModel): + shelf_set_source_path: MultiplatformPathModel = Field( + default_factory=MultiplatformPathModel, + title="Shelf Set Path" + ) + + +class AddSetAndDefinitionsModel(BaseSettingsModel): + shelf_set_name: str = Field(title="Shelf Set Name") + shelf_definition: list[ShelfDefinitionModel] = Field( + default_factory=list, + title="Shelves Definitions" + ) + + def shelves_enum_options(): return [ - {"value": "add_shelf_file", "label": "Add a .shelf file"}, - {"value": "add_set_and_definitions", "label": "Add Shelf Set Name and Shelves Definitions"} + { + "value": "add_shelf_file", + "label": "Add a .shelf file" + }, + { + "value": "add_set_and_definitions", + "label": "Add Shelf Set Name and Shelves Definitions" + } ] + class ShelvesModel(BaseSettingsModel): - _layout = "expanded" options: str = Field( title="Options", description="Switch between shelves manager options", enum_resolver=shelves_enum_options, conditionalEnum=True ) - shelf_set_source_path: MultiplatformPathModel = Field( - default_factory=MultiplatformPathModel, - title="Shelf Set Path", - section="Option 1: Add a .shelf file." + add_shelf_file: AddShelfFileModel = Field( + title="Add a .shelf file", + default_factory=AddShelfFileModel ) - shelf_set_name: str = Field( - "", - title="Shelf Set Name", - section=("OR Option 2: Add Shelf Set Name " - "and Shelves Definitions.") - ) - shelf_definition: list[ShelfDefinitionModel] = Field( - default_factory=list, - title="Shelves Definitions" + add_set_and_definitions: AddSetAndDefinitionsModel = Field( + title="Add Shelf Set Name and Shelves Definitions", + default_factory=AddSetAndDefinitionsModel ) From 381c00c3342193442e46b3e2475db64dda129beb Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 12:29:41 +0200 Subject: [PATCH 198/690] Align Openpype and Ayon settings, quick fix in shelves loader script --- openpype/hosts/houdini/api/shelves.py | 34 +++-- .../schemas/schema_houdini_scriptshelf.json | 128 ++++++++++-------- .../houdini/server/settings/shelves.py | 2 +- 3 files changed, 91 insertions(+), 73 deletions(-) diff --git a/openpype/hosts/houdini/api/shelves.py b/openpype/hosts/houdini/api/shelves.py index 0afc737665..6fb3967be8 100644 --- a/openpype/hosts/houdini/api/shelves.py +++ b/openpype/hosts/houdini/api/shelves.py @@ -23,29 +23,33 @@ def generate_shelves(): # load configuration of houdini shelves project_name = get_current_project_name() project_settings = get_project_settings(project_name) - shelves_set_config = project_settings["houdini"]["shelves"] + shelves_configs = project_settings["houdini"]["shelves"] - if not shelves_set_config: + if not shelves_configs: log.debug("No custom shelves found in project settings.") return # Get Template data template_data = get_current_context_template_data() - for shelf_set_config in shelves_set_config: - shelf_set_filepath = shelf_set_config.get('shelf_set_source_path') - shelf_set_os_filepath = shelf_set_filepath[current_os] - if shelf_set_os_filepath: - shelf_set_os_filepath = get_path_using_template_data( - shelf_set_os_filepath, template_data - ) - if not os.path.isfile(shelf_set_os_filepath): - log.error("Shelf path doesn't exist - " - "{}".format(shelf_set_os_filepath)) - continue + for config in shelves_configs: + selected_option = config["options"] + shelf_set_config = config[selected_option] - hou.shelves.loadFile(shelf_set_os_filepath) - continue + shelf_set_filepath = shelf_set_config.get('shelf_set_source_path') + if shelf_set_filepath: + shelf_set_os_filepath = shelf_set_filepath[current_os] + if shelf_set_os_filepath: + shelf_set_os_filepath = get_path_using_template_data( + shelf_set_os_filepath, template_data + ) + if not os.path.isfile(shelf_set_os_filepath): + log.error("Shelf path doesn't exist - " + "{}".format(shelf_set_os_filepath)) + continue + + hou.shelves.loadFile(shelf_set_os_filepath) + continue shelf_set_name = shelf_set_config.get('shelf_set_name') if not shelf_set_name: diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json index 2dfce906b7..cee04b73e5 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_scriptshelf.json @@ -15,11 +15,18 @@ "label": "Add a .shelf file", "children": [ { - "type": "path", - "key": "shelf_set_source_path", - "label": "Shelf Set Path", - "multipath": false, - "multiplatform": true + "type": "dict", + "key": "add_shelf_file", + "label": "Add a .shelf file", + "children": [ + { + "type": "path", + "key": "shelf_set_source_path", + "label": "Shelf Set Path", + "multipath": false, + "multiplatform": true + } + ] } ] }, @@ -28,60 +35,67 @@ "label": "Add Shelf Set Name and Shelves Definitions", "children": [ { - "type": "text", - "key": "shelf_set_name", - "label": "Shelf Set Name" - }, - { - "type": "list", - "key": "shelf_definition", - "label": "Shelves Definitions", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "text", - "key": "shelf_name", - "label": "Shelf Name" - }, - { - "type": "list", - "key": "tools_list", - "label": "Tools", - "use_label_wrap": true, - "object_type": { - "type": "dict", - "children": [ - { - "type": "label", - "label": "Name and Script Path are mandatory." - }, - { - "type": "text", - "key": "label", - "label": "Name" - }, - { - "type": "path", - "key": "script", - "label": "Script" - }, - { - "type": "path", - "key": "icon", - "label": "Icon" - }, - { - "type": "text", - "key": "help", - "label": "Help" + "key": "add_set_and_definitions", + "label": "Add Shelf Set Name and Shelves Definitions", + "type": "dict", + "children": [ + { + "type": "text", + "key": "shelf_set_name", + "label": "Shelf Set Name" + }, + { + "type": "list", + "key": "shelf_definition", + "label": "Shelves Definitions", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "text", + "key": "shelf_name", + "label": "Shelf Name" + }, + { + "type": "list", + "key": "tools_list", + "label": "Tools", + "use_label_wrap": true, + "object_type": { + "type": "dict", + "children": [ + { + "type": "label", + "label": "Name and Script Path are mandatory." + }, + { + "type": "text", + "key": "label", + "label": "Name" + }, + { + "type": "path", + "key": "script", + "label": "Script" + }, + { + "type": "path", + "key": "icon", + "label": "Icon" + }, + { + "type": "text", + "key": "help", + "label": "Help" + } + ] } - ] - } + } + ] } - ] - } + } + ] } ] } diff --git a/server_addon/houdini/server/settings/shelves.py b/server_addon/houdini/server/settings/shelves.py index a0acc90505..133c18f77c 100644 --- a/server_addon/houdini/server/settings/shelves.py +++ b/server_addon/houdini/server/settings/shelves.py @@ -30,7 +30,7 @@ class AddShelfFileModel(BaseSettingsModel): class AddSetAndDefinitionsModel(BaseSettingsModel): - shelf_set_name: str = Field(title="Shelf Set Name") + shelf_set_name: str = Field("", title="Shelf Set Name") shelf_definition: list[ShelfDefinitionModel] = Field( default_factory=list, title="Shelves Definitions" From c185d2cab8b9cb1a21d17c26acfeb8180eedcb15 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 12:35:41 +0200 Subject: [PATCH 199/690] resolve hound --- openpype/hosts/houdini/api/shelves.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/api/shelves.py b/openpype/hosts/houdini/api/shelves.py index 8b27ecd67e..5093a90988 100644 --- a/openpype/hosts/houdini/api/shelves.py +++ b/openpype/hosts/houdini/api/shelves.py @@ -46,7 +46,7 @@ def generate_shelves(): ) if not os.path.isfile(shelf_set_os_filepath): log.error("Shelf path doesn't exist - " - "{}".format(shelf_set_os_filepath)) + "{}".format(shelf_set_os_filepath)) continue hou.shelves.loadFile(shelf_set_os_filepath) From 82f3b5e07f9d5b2bbe2a7679f11c52adf5ad51ff Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 1 Nov 2023 18:40:28 +0800 Subject: [PATCH 200/690] avoid using asset from context in collect render and also clean up unncessary code from the collector --- .../max/plugins/publish/collect_render.py | 19 +------------------ .../plugins/publish/collect_scene_version.py | 1 + 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/collect_render.py b/openpype/hosts/max/plugins/publish/collect_render.py index 7765b3b924..38194a0735 100644 --- a/openpype/hosts/max/plugins/publish/collect_render.py +++ b/openpype/hosts/max/plugins/publish/collect_render.py @@ -4,11 +4,9 @@ import os import pyblish.api from pymxs import runtime as rt -from openpype.pipeline import get_current_asset_name from openpype.hosts.max.api import colorspace from openpype.hosts.max.api.lib import get_max_version, get_current_renderer from openpype.hosts.max.api.lib_renderproducts import RenderProducts -from openpype.client import get_last_version_by_subset_name class CollectRender(pyblish.api.InstancePlugin): @@ -27,7 +25,6 @@ class CollectRender(pyblish.api.InstancePlugin): filepath = current_file.replace("\\", "/") context.data['currentFile'] = current_file - asset = get_current_asset_name() files_by_aov = RenderProducts().get_beauty(instance.name) aovs = RenderProducts().get_aovs(instance.name) @@ -49,19 +46,6 @@ class CollectRender(pyblish.api.InstancePlugin): instance.data["files"].append(files_by_aov) img_format = RenderProducts().image_format() - project_name = context.data["projectName"] - asset_doc = context.data["assetEntity"] - asset_id = asset_doc["_id"] - version_doc = get_last_version_by_subset_name(project_name, - instance.name, - asset_id) - self.log.debug("version_doc: {0}".format(version_doc)) - version_int = 1 - if version_doc: - version_int += int(version_doc["name"]) - - self.log.debug(f"Setting {version_int} to context.") - context.data["version"] = version_int # OCIO config not support in # most of the 3dsmax renderers # so this is currently hard coded @@ -87,7 +71,7 @@ class CollectRender(pyblish.api.InstancePlugin): renderer = str(renderer_class).split(":")[0] # also need to get the render dir for conversion data = { - "asset": asset, + "asset": instance.data["asset"], "subset": str(instance.name), "publish": True, "maxversion": str(get_max_version()), @@ -99,7 +83,6 @@ class CollectRender(pyblish.api.InstancePlugin): "plugin": "3dsmax", "frameStart": instance.data["frameStartHandle"], "frameEnd": instance.data["frameEndHandle"], - "version": version_int, "farm": True } instance.data.update(data) diff --git a/openpype/plugins/publish/collect_scene_version.py b/openpype/plugins/publish/collect_scene_version.py index 7920c1e82b..f870ae9ad7 100644 --- a/openpype/plugins/publish/collect_scene_version.py +++ b/openpype/plugins/publish/collect_scene_version.py @@ -24,6 +24,7 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): "hiero", "houdini", "maya", + "max", "nuke", "photoshop", "resolve", From 424a0d6f2fdb9ab866aeb7bbf2c8d552e7a19a95 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 1 Nov 2023 11:14:38 +0000 Subject: [PATCH 201/690] Fix missing grease pencils in thumbnails and playblasts --- openpype/hosts/blender/plugins/publish/collect_review.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_review.py b/openpype/hosts/blender/plugins/publish/collect_review.py index 3bf2e39e24..2760ab9811 100644 --- a/openpype/hosts/blender/plugins/publish/collect_review.py +++ b/openpype/hosts/blender/plugins/publish/collect_review.py @@ -31,11 +31,12 @@ class CollectReview(pyblish.api.InstancePlugin): focal_length = cameras[0].data.lens - # get isolate objects list from meshes instance members . + # get isolate objects list from meshes instance members. + types = {"MESH", "GPENCIL"} isolate_objects = [ obj for obj in instance - if isinstance(obj, bpy.types.Object) and obj.type == "MESH" + if isinstance(obj, bpy.types.Object) and obj.type in types ] if not instance.data.get("remove"): From e4aa43e91bdc9e8f81055d7357bfb219cdd98a68 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 1 Nov 2023 11:53:49 +0000 Subject: [PATCH 202/690] Fix Blender Render Settings in Ayon --- server_addon/blender/server/settings/main.py | 2 +- server_addon/blender/server/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/blender/server/settings/main.py b/server_addon/blender/server/settings/main.py index 4476ea709b..374b2fafa2 100644 --- a/server_addon/blender/server/settings/main.py +++ b/server_addon/blender/server/settings/main.py @@ -41,7 +41,7 @@ class BlenderSettings(BaseSettingsModel): default_factory=BlenderImageIOModel, title="Color Management (ImageIO)" ) - render_settings: RenderSettingsModel = Field( + RenderSettings: RenderSettingsModel = Field( default_factory=RenderSettingsModel, title="Render Settings") workfile_builder: TemplateWorkfileBaseOptions = Field( default_factory=TemplateWorkfileBaseOptions, diff --git a/server_addon/blender/server/version.py b/server_addon/blender/server/version.py index ae7362549b..bbab0242f6 100644 --- a/server_addon/blender/server/version.py +++ b/server_addon/blender/server/version.py @@ -1 +1 @@ -__version__ = "0.1.3" +__version__ = "0.1.4" From 0916db5fa0c98e239e65ff5a95fa76184fec613f Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 14:35:22 +0200 Subject: [PATCH 203/690] set f1 and f2 to $FSTART and $FEND respectively --- openpype/hosts/houdini/plugins/create/create_composite.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/houdini/plugins/create/create_composite.py b/openpype/hosts/houdini/plugins/create/create_composite.py index 9d4f7969bb..52ea6fa054 100644 --- a/openpype/hosts/houdini/plugins/create/create_composite.py +++ b/openpype/hosts/houdini/plugins/create/create_composite.py @@ -45,6 +45,11 @@ class CreateCompositeSequence(plugin.HoudiniCreator): instance_node.setParms(parms) + # Manually set f1 & f2 to $FSTART and $FEND respectively + # to match other Houdini nodes default. + instance_node.parm("f1").setExpression("$FSTART") + instance_node.parm("f2").setExpression("$FEND") + # Lock any parameters in this list to_lock = ["prim_to_detail_pattern"] self.lock_parameters(instance_node, to_lock) From 41d9cf65b0d8d70affefe47e6feaca71c406a4d0 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 15:05:33 +0200 Subject: [PATCH 204/690] make tab menu name change according to the app whether OpenPype or AYON --- openpype/hosts/houdini/api/creator_node_shelves.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/api/creator_node_shelves.py b/openpype/hosts/houdini/api/creator_node_shelves.py index 1f9fef7417..085642a277 100644 --- a/openpype/hosts/houdini/api/creator_node_shelves.py +++ b/openpype/hosts/houdini/api/creator_node_shelves.py @@ -173,6 +173,7 @@ def install(): os.remove(filepath) icon = get_openpype_icon_filepath() + tab_menu_label = os.environ.get("AVALON_LABEL") or "OpenPype" # Create context only to get creator plugins, so we don't reset and only # populate what we need to retrieve the list of creator plugins @@ -197,14 +198,14 @@ def install(): if not network_categories: continue - key = "openpype_create.{}".format(identifier) + key = "ayon_create.{}".format(identifier) log.debug(f"Registering {key}") script = CREATE_SCRIPT.format(identifier=identifier) data = { "script": script, "language": hou.scriptLanguage.Python, "icon": icon, - "help": "Create OpenPype publish instance for {}".format( + "help": "Create Ayon publish instance for {}".format( creator.label ), "help_url": None, @@ -213,7 +214,7 @@ def install(): "cop_viewer_categories": [], "network_op_type": None, "viewer_op_type": None, - "locations": ["OpenPype"] + "locations": [tab_menu_label] } label = "Create {}".format(creator.label) tool = hou.shelves.tool(key) From c577d2bc84854382ecf157b22f293d4f23c38298 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 1 Nov 2023 13:09:57 +0000 Subject: [PATCH 205/690] Fix default settings --- server_addon/blender/server/settings/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/blender/server/settings/main.py b/server_addon/blender/server/settings/main.py index 374b2fafa2..5eff276ef5 100644 --- a/server_addon/blender/server/settings/main.py +++ b/server_addon/blender/server/settings/main.py @@ -61,7 +61,7 @@ DEFAULT_VALUES = { }, "set_frames_startup": True, "set_resolution_startup": True, - "render_settings": DEFAULT_RENDER_SETTINGS, + "RenderSettings": DEFAULT_RENDER_SETTINGS, "publish": DEFAULT_BLENDER_PUBLISH_SETTINGS, "workfile_builder": { "create_first_version": False, From eb242e78a5afeef40c814bc27a140dbfdc0e7f85 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 15:13:40 +0200 Subject: [PATCH 206/690] add get_network_categories --- openpype/hosts/houdini/plugins/create/create_bgeo.py | 8 +++++++- openpype/hosts/houdini/plugins/create/create_hda.py | 7 ++++++- .../houdini/plugins/create/create_redshift_proxy.py | 12 +++++++++--- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/houdini/plugins/create/create_bgeo.py b/openpype/hosts/houdini/plugins/create/create_bgeo.py index a3f31e7e94..0f629cf9c9 100644 --- a/openpype/hosts/houdini/plugins/create/create_bgeo.py +++ b/openpype/hosts/houdini/plugins/create/create_bgeo.py @@ -3,6 +3,7 @@ from openpype.hosts.houdini.api import plugin from openpype.pipeline import CreatedInstance, CreatorError from openpype.lib import EnumDef +import hou class CreateBGEO(plugin.HoudiniCreator): @@ -13,7 +14,6 @@ class CreateBGEO(plugin.HoudiniCreator): icon = "gears" def create(self, subset_name, instance_data, pre_create_data): - import hou instance_data.pop("active", None) @@ -90,3 +90,9 @@ class CreateBGEO(plugin.HoudiniCreator): return attrs + [ EnumDef("bgeo_type", bgeo_enum, label="BGEO Options"), ] + + def get_network_categories(self): + return [ + hou.ropNodeTypeCategory(), + hou.sopNodeTypeCategory() + ] diff --git a/openpype/hosts/houdini/plugins/create/create_hda.py b/openpype/hosts/houdini/plugins/create/create_hda.py index c4093bfbc6..ac075d2072 100644 --- a/openpype/hosts/houdini/plugins/create/create_hda.py +++ b/openpype/hosts/houdini/plugins/create/create_hda.py @@ -5,6 +5,7 @@ from openpype.client import ( get_subsets, ) from openpype.hosts.houdini.api import plugin +import hou class CreateHDA(plugin.HoudiniCreator): @@ -35,7 +36,6 @@ class CreateHDA(plugin.HoudiniCreator): def create_instance_node( self, node_name, parent, node_type="geometry"): - import hou parent_node = hou.node("/obj") if self.selected_nodes: @@ -81,3 +81,8 @@ class CreateHDA(plugin.HoudiniCreator): pre_create_data) # type: plugin.CreatedInstance return instance + + def get_network_categories(self): + return [ + hou.objNodeTypeCategory() + ] diff --git a/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py b/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py index b814dd9d57..3a4ab7008b 100644 --- a/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py +++ b/openpype/hosts/houdini/plugins/create/create_redshift_proxy.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Creator plugin for creating Redshift proxies.""" from openpype.hosts.houdini.api import plugin -from openpype.pipeline import CreatedInstance +import hou class CreateRedshiftProxy(plugin.HoudiniCreator): @@ -12,7 +12,7 @@ class CreateRedshiftProxy(plugin.HoudiniCreator): icon = "magic" def create(self, subset_name, instance_data, pre_create_data): - import hou # noqa + # Remove the active, we are checking the bypass flag of the nodes instance_data.pop("active", None) @@ -28,7 +28,7 @@ class CreateRedshiftProxy(plugin.HoudiniCreator): instance = super(CreateRedshiftProxy, self).create( subset_name, instance_data, - pre_create_data) # type: CreatedInstance + pre_create_data) instance_node = hou.node(instance.get("instance_node")) @@ -44,3 +44,9 @@ class CreateRedshiftProxy(plugin.HoudiniCreator): # Lock some Avalon attributes to_lock = ["family", "id", "prim_to_detail_pattern"] self.lock_parameters(instance_node, to_lock) + + def get_network_categories(self): + return [ + hou.ropNodeTypeCategory(), + hou.sopNodeTypeCategory() + ] From aed9b13e0048951f9cc8605415ea7d5142ca11cb Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 15:15:09 +0200 Subject: [PATCH 207/690] update ids to 'ayon' instead of 'openpype' --- openpype/hosts/houdini/startup/MainMenuCommon.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/startup/MainMenuCommon.xml b/openpype/hosts/houdini/startup/MainMenuCommon.xml index b2e32a70f9..c875cac0f5 100644 --- a/openpype/hosts/houdini/startup/MainMenuCommon.xml +++ b/openpype/hosts/houdini/startup/MainMenuCommon.xml @@ -16,7 +16,7 @@ return label - + - + - + Date: Wed, 1 Nov 2023 15:35:09 +0200 Subject: [PATCH 208/690] update get_network_categories --- openpype/hosts/houdini/plugins/create/create_pointcache.py | 1 + openpype/hosts/houdini/plugins/create/create_staticmesh.py | 1 + openpype/hosts/houdini/plugins/create/create_vbd_cache.py | 1 + 3 files changed, 3 insertions(+) diff --git a/openpype/hosts/houdini/plugins/create/create_pointcache.py b/openpype/hosts/houdini/plugins/create/create_pointcache.py index 7eaf2aff2b..8fe8052e0a 100644 --- a/openpype/hosts/houdini/plugins/create/create_pointcache.py +++ b/openpype/hosts/houdini/plugins/create/create_pointcache.py @@ -83,6 +83,7 @@ class CreatePointCache(plugin.HoudiniCreator): def get_network_categories(self): return [ hou.ropNodeTypeCategory(), + hou.objNodeTypeCategory(), hou.sopNodeTypeCategory() ] diff --git a/openpype/hosts/houdini/plugins/create/create_staticmesh.py b/openpype/hosts/houdini/plugins/create/create_staticmesh.py index ea0b36f03f..d0985198bd 100644 --- a/openpype/hosts/houdini/plugins/create/create_staticmesh.py +++ b/openpype/hosts/houdini/plugins/create/create_staticmesh.py @@ -54,6 +54,7 @@ class CreateStaticMesh(plugin.HoudiniCreator): def get_network_categories(self): return [ hou.ropNodeTypeCategory(), + hou.objNodeTypeCategory(), hou.sopNodeTypeCategory() ] diff --git a/openpype/hosts/houdini/plugins/create/create_vbd_cache.py b/openpype/hosts/houdini/plugins/create/create_vbd_cache.py index 9c96e48e3a..69418f9575 100644 --- a/openpype/hosts/houdini/plugins/create/create_vbd_cache.py +++ b/openpype/hosts/houdini/plugins/create/create_vbd_cache.py @@ -40,6 +40,7 @@ class CreateVDBCache(plugin.HoudiniCreator): def get_network_categories(self): return [ hou.ropNodeTypeCategory(), + hou.objNodeTypeCategory(), hou.sopNodeTypeCategory() ] From 25c8a424ec65330777bc3968c41d9fe6f59d470c Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 15:40:29 +0200 Subject: [PATCH 209/690] skip check if node has no 'trange' parameter --- .../hosts/houdini/plugins/publish/validate_frame_range.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py index 6a66f3de9f..2264372549 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py @@ -57,6 +57,14 @@ class ValidateFrameRange(pyblish.api.InstancePlugin): return rop_node = hou.node(instance.data["instance_node"]) + + if rop_node.parm("trange") is None: + cls.log.debug( + "Skipping Check, Node has no 'trange' parameter: {}" + .format(rop_node.path()) + ) + return + if instance.data["frameStart"] > instance.data["frameEnd"]: cls.log.info( "The ROP node render range is set to " From 60438ab4a8bed39a8ee681f03e995e88a8b17943 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 17:00:41 +0200 Subject: [PATCH 210/690] BigRoy's comments - Better conditional and debug message --- .../houdini/plugins/publish/validate_frame_range.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py index 2264372549..5d3866cfdb 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py @@ -57,15 +57,17 @@ class ValidateFrameRange(pyblish.api.InstancePlugin): return rop_node = hou.node(instance.data["instance_node"]) + frame_start = instance.data.get("frameStart") + frame_end = instance.data.get("frameEnd") - if rop_node.parm("trange") is None: + if not (frame_start or frame_end): cls.log.debug( - "Skipping Check, Node has no 'trange' parameter: {}" - .format(rop_node.path()) + "Skipping frame range validation for " + "instance without frame data: {}".format(rop_node.path()) ) return - if instance.data["frameStart"] > instance.data["frameEnd"]: + if frame_start > frame_end: cls.log.info( "The ROP node render range is set to " "{0[frameStartHandle]} - {0[frameEndHandle]} " From 5a873368ee9b2544ea2c19401354ec5f94712537 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 17:56:23 +0200 Subject: [PATCH 211/690] fix loading bug --- openpype/hosts/houdini/plugins/load/load_image.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/load/load_image.py b/openpype/hosts/houdini/plugins/load/load_image.py index 663a93e48b..cff2b74e52 100644 --- a/openpype/hosts/houdini/plugins/load/load_image.py +++ b/openpype/hosts/houdini/plugins/load/load_image.py @@ -119,7 +119,8 @@ class ImageLoader(load.LoaderPlugin): if not parent.children(): parent.destroy() - def _get_file_sequence(self, root): + def _get_file_sequence(self, file_path): + root = os.path.dirname(file_path) files = sorted(os.listdir(root)) first_fname = files[0] From dca872e1fce9f1735063769d17e8256f9c003125 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 17:57:00 +0200 Subject: [PATCH 212/690] fix collector order to fix the missing frames --- openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py | 4 ++-- openpype/hosts/houdini/plugins/publish/collect_frames.py | 4 +++- openpype/hosts/houdini/plugins/publish/collect_karma_rop.py | 4 ++-- openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py | 4 ++-- .../hosts/houdini/plugins/publish/collect_redshift_rop.py | 4 ++-- openpype/hosts/houdini/plugins/publish/collect_vray_rop.py | 4 ++-- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py index b489f83b29..420a8324fe 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -21,8 +21,8 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): label = "Arnold ROP Render Products" # This specific order value is used so that - # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + # this plugin runs after CollectFrames + order = pyblish.api.CollectorOrder + 0.49999 hosts = ["houdini"] families = ["arnold_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_frames.py b/openpype/hosts/houdini/plugins/publish/collect_frames.py index 01df809d4c..79cfcc6139 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_frames.py +++ b/openpype/hosts/houdini/plugins/publish/collect_frames.py @@ -11,7 +11,9 @@ from openpype.hosts.houdini.api import lib class CollectFrames(pyblish.api.InstancePlugin): """Collect all frames which would be saved from the ROP nodes""" - order = pyblish.api.CollectorOrder + 0.01 + # This specific order value is used so that + # this plugin runs after CollectRopFrameRange + order = pyblish.api.CollectorOrder + 0.4999 label = "Collect Frames" families = ["vdbcache", "imagesequence", "ass", "redshiftproxy", "review", "bgeo"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py index fe0b8711fc..a477529df9 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py @@ -25,8 +25,8 @@ class CollectKarmaROPRenderProducts(pyblish.api.InstancePlugin): label = "Karma ROP Render Products" # This specific order value is used so that - # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + # this plugin runs after CollectFrames + order = pyblish.api.CollectorOrder + 0.49999 hosts = ["houdini"] families = ["karma_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py index cc412f30a1..9f0ae8d33c 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -25,8 +25,8 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): label = "Mantra ROP Render Products" # This specific order value is used so that - # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + # this plugin runs after CollectFrames + order = pyblish.api.CollectorOrder + 0.49999 hosts = ["houdini"] families = ["mantra_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py index deb9eac971..0bd7b41641 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -25,8 +25,8 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): label = "Redshift ROP Render Products" # This specific order value is used so that - # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + # this plugin runs after CollectFrames + order = pyblish.api.CollectorOrder + 0.49999 hosts = ["houdini"] families = ["redshift_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index 53072aebc6..519c12aede 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -25,8 +25,8 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): label = "VRay ROP Render Products" # This specific order value is used so that - # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + # this plugin runs after CollectFrames + order = pyblish.api.CollectorOrder + 0.49999 hosts = ["houdini"] families = ["vray_rop"] From c15adfa327cdb30f13c21f9e0f6c11d18c73ca9e Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 18:05:23 +0200 Subject: [PATCH 213/690] BigRoys' commit - fallback to AYON --- openpype/hosts/houdini/api/creator_node_shelves.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/api/creator_node_shelves.py b/openpype/hosts/houdini/api/creator_node_shelves.py index 085642a277..14662dc419 100644 --- a/openpype/hosts/houdini/api/creator_node_shelves.py +++ b/openpype/hosts/houdini/api/creator_node_shelves.py @@ -173,7 +173,7 @@ def install(): os.remove(filepath) icon = get_openpype_icon_filepath() - tab_menu_label = os.environ.get("AVALON_LABEL") or "OpenPype" + tab_menu_label = os.environ.get("AVALON_LABEL") or "AYON" # Create context only to get creator plugins, so we don't reset and only # populate what we need to retrieve the list of creator plugins From c64af8ddef70412de33b8c04ff048cfbdc41d77d Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 18:06:36 +0200 Subject: [PATCH 214/690] BigRoy's comment - remove Obj from network_categories to avoid possible confusion --- openpype/hosts/houdini/plugins/create/create_pointcache.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/create/create_pointcache.py b/openpype/hosts/houdini/plugins/create/create_pointcache.py index 8fe8052e0a..7eaf2aff2b 100644 --- a/openpype/hosts/houdini/plugins/create/create_pointcache.py +++ b/openpype/hosts/houdini/plugins/create/create_pointcache.py @@ -83,7 +83,6 @@ class CreatePointCache(plugin.HoudiniCreator): def get_network_categories(self): return [ hou.ropNodeTypeCategory(), - hou.objNodeTypeCategory(), hou.sopNodeTypeCategory() ] From bd8638caa10524dca1554208d4b301413729983b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 1 Nov 2023 17:16:37 +0100 Subject: [PATCH 215/690] ftrack events are not processed if project is not available in OpenPype database --- .../event_first_version_status.py | 45 ++++++++++++++----- .../event_next_task_update.py | 6 +++ .../event_push_frame_values_to_task.py | 6 +++ .../event_task_to_parent_status.py | 6 +++ .../event_task_to_version_status.py | 6 +++ .../event_thumbnail_updates.py | 6 +++ .../event_version_to_task_statuses.py | 5 +++ 7 files changed, 70 insertions(+), 10 deletions(-) diff --git a/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py b/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py index 8ef333effd..2ac02f233e 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py +++ b/openpype/modules/ftrack/event_handlers_server/event_first_version_status.py @@ -1,3 +1,6 @@ +import collections + +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -73,8 +76,21 @@ class FirstVersionStatus(BaseEvent): if not self.task_status_map: return - entities_info = self.filter_event_ents(event) - if not entities_info: + filtered_entities_info = self.filter_entities_info(event) + if not filtered_entities_info: + return + + for project_id, entities_info in filtered_entities_info.items(): + self.process_by_project(session, event, project_id, entities_info) + + def process_by_project(self, session, event, project_id, entities_info): + project_name = self.get_project_name_from_event( + session, event, project_id + ) + if get_project(project_name) is None: + self.log.debug( + f"Project '{project_name}' not found in OpenPype. Skipping" + ) return entity_ids = [] @@ -154,18 +170,18 @@ class FirstVersionStatus(BaseEvent): exc_info=True ) - def filter_event_ents(self, event): - filtered_ents = [] - for entity in event["data"].get("entities", []): + def filter_entities_info(self, event): + filtered_entities_info = collections.defaultdict(list) + for entity_info in event["data"].get("entities", []): # Care only about add actions - if entity.get("action") != "add": + if entity_info.get("action") != "add": continue # Filter AssetVersions - if entity["entityType"] != "assetversion": + if entity_info["entityType"] != "assetversion": continue - entity_changes = entity.get("changes") or {} + entity_changes = entity_info.get("changes") or {} # Check if version of Asset Version is `1` version_num = entity_changes.get("version", {}).get("new") @@ -177,9 +193,18 @@ class FirstVersionStatus(BaseEvent): if not task_id: continue - filtered_ents.append(entity) + project_id = None + for parent_item in reversed(entity_info["parents"]): + if parent_item["entityType"] == "show": + project_id = parent_item["entityId"] + break - return filtered_ents + if project_id is None: + continue + + filtered_entities_info[project_id].append(entity_info) + + return filtered_entities_info def register(session): diff --git a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py b/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py index a100c34f67..07a8ff433e 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py +++ b/openpype/modules/ftrack/event_handlers_server/event_next_task_update.py @@ -1,4 +1,6 @@ import collections + +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -99,6 +101,10 @@ class NextTaskUpdate(BaseEvent): project_name = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return + # Load settings project_settings = self.get_project_settings_from_event( event, project_name diff --git a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py b/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py index ed630ad59d..65c3c1a69a 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py +++ b/openpype/modules/ftrack/event_handlers_server/event_push_frame_values_to_task.py @@ -3,6 +3,8 @@ import copy from typing import Any import ftrack_api + +from openpype.client import get_project from openpype_modules.ftrack.lib import ( BaseEvent, query_custom_attributes, @@ -139,6 +141,10 @@ class PushHierValuesToNonHierEvent(BaseEvent): project_name: str = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return set(), set() + # Load settings project_settings: dict[str, Any] = ( self.get_project_settings_from_event(event, project_name) diff --git a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py b/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py index 25fa3b0535..d2b395a1a3 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py +++ b/openpype/modules/ftrack/event_handlers_server/event_task_to_parent_status.py @@ -1,4 +1,6 @@ import collections + +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -60,6 +62,10 @@ class TaskStatusToParent(BaseEvent): project_name = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return + # Load settings project_settings = self.get_project_settings_from_event( event, project_name diff --git a/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py b/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py index b77849c678..91ee2410d7 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py +++ b/openpype/modules/ftrack/event_handlers_server/event_task_to_version_status.py @@ -1,4 +1,6 @@ import collections + +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -102,6 +104,10 @@ class TaskToVersionStatus(BaseEvent): project_name = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return + # Load settings project_settings = self.get_project_settings_from_event( event, project_name diff --git a/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py b/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py index 64673f792c..318e69f414 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py +++ b/openpype/modules/ftrack/event_handlers_server/event_thumbnail_updates.py @@ -1,4 +1,6 @@ import collections + +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -22,6 +24,10 @@ class ThumbnailEvents(BaseEvent): project_name = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return + # Load settings project_settings = self.get_project_settings_from_event( event, project_name diff --git a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py b/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py index fb40fd6417..fbe44bcba7 100644 --- a/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py +++ b/openpype/modules/ftrack/event_handlers_server/event_version_to_task_statuses.py @@ -1,3 +1,4 @@ +from openpype.client import get_project from openpype_modules.ftrack.lib import BaseEvent @@ -50,6 +51,10 @@ class VersionToTaskStatus(BaseEvent): project_name = self.get_project_name_from_event( session, event, project_id ) + if get_project(project_name) is None: + self.log.debug("Project not found in OpenPype. Skipping") + return + # Load settings project_settings = self.get_project_settings_from_event( event, project_name From d4b75797c69a59725e3d8348f44aefedb5136455 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 1 Nov 2023 20:49:05 +0100 Subject: [PATCH 216/690] nuke: making sure duplicated loader is not removed --- openpype/hosts/nuke/api/plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openpype/hosts/nuke/api/plugin.py b/openpype/hosts/nuke/api/plugin.py index c39e3c339d..301b9533a9 100644 --- a/openpype/hosts/nuke/api/plugin.py +++ b/openpype/hosts/nuke/api/plugin.py @@ -537,6 +537,7 @@ class NukeLoader(LoaderPlugin): node.addKnob(knob) def clear_members(self, parent_node): + parent_class = parent_node.Class() members = self.get_members(parent_node) dependent_nodes = None @@ -549,6 +550,8 @@ class NukeLoader(LoaderPlugin): break for member in members: + if member.Class() == parent_class: + continue self.log.info("removing node: `{}".format(member.name())) nuke.delete(member) From e3eea5a8e35fedd12bebfdc0da77338850b22457 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 1 Nov 2023 20:49:36 +0100 Subject: [PATCH 217/690] Nuke: updating without node renameing --- openpype/hosts/nuke/plugins/load/load_clip.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/openpype/hosts/nuke/plugins/load/load_clip.py b/openpype/hosts/nuke/plugins/load/load_clip.py index 19038b168d..737da3746d 100644 --- a/openpype/hosts/nuke/plugins/load/load_clip.py +++ b/openpype/hosts/nuke/plugins/load/load_clip.py @@ -299,9 +299,6 @@ class LoadClip(plugin.NukeLoader): "Representation id `{}` is failing to load".format(repre_id)) return - read_name = self._get_node_name(representation) - - read_node["name"].setValue(read_name) read_node["file"].setValue(filepath) # to avoid multiple undo steps for rest of process From 83798a7b5e3daa3c71bb34d0849e70817730b311 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 22:15:41 +0200 Subject: [PATCH 218/690] BigRoy's comment - fallback to 'AYON' --- openpype/hosts/houdini/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index ac375c56d6..db7f0886c3 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -1018,7 +1018,7 @@ def self_publish(): def add_self_publish_button(node): """Adds a self publish button to the rop node.""" - label = os.environ.get("AVALON_LABEL") or "OpenPype" + label = os.environ.get("AVALON_LABEL") or "AYON" button_parm = hou.ButtonParmTemplate( "ayon_self_publish", From 3a78230ba4c8fc69285d9b660499891245479765 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 1 Nov 2023 22:16:57 +0200 Subject: [PATCH 219/690] BigRoy's comment - fallback to 'AYON' --- openpype/hosts/houdini/startup/MainMenuCommon.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/startup/MainMenuCommon.xml b/openpype/hosts/houdini/startup/MainMenuCommon.xml index c875cac0f5..0903aef7bc 100644 --- a/openpype/hosts/houdini/startup/MainMenuCommon.xml +++ b/openpype/hosts/houdini/startup/MainMenuCommon.xml @@ -4,7 +4,7 @@ Date: Wed, 1 Nov 2023 22:20:42 +0200 Subject: [PATCH 220/690] BigRoy's comment - Update COnditional --- openpype/hosts/houdini/plugins/publish/validate_frame_range.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py index 5d3866cfdb..90a079217b 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py @@ -60,7 +60,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin): frame_start = instance.data.get("frameStart") frame_end = instance.data.get("frameEnd") - if not (frame_start or frame_end): + if frame_start is None or frame_end is None: cls.log.debug( "Skipping frame range validation for " "instance without frame data: {}".format(rop_node.path()) From 978ec89f6562c82d2cb9d878cc3563448a21aca3 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 1 Nov 2023 21:35:20 +0100 Subject: [PATCH 221/690] Nuke: updating ls method to have full name and node --- openpype/hosts/nuke/api/pipeline.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index a1d290646c..f6ba33f00f 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -478,8 +478,6 @@ def parse_container(node): """ data = read_avalon_data(node) - # (TODO) Remove key validation when `ls` has re-implemented. - # # If not all required data return the empty container required = ["schema", "id", "name", "namespace", "loader", "representation"] @@ -487,7 +485,10 @@ def parse_container(node): return # Store the node's name - data["objectName"] = node["name"].value() + data.update({ + "objectName": node.fullName(), + "node": node, + }) return data From 16aad9928823a10034d6d9bfc1ba7cb25fd24a53 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 1 Nov 2023 21:36:48 +0100 Subject: [PATCH 222/690] nuke: updating loaders so they are using nodes rather then objectName --- .../hosts/nuke/plugins/load/load_backdrop.py | 16 ++++---- .../nuke/plugins/load/load_camera_abc.py | 24 ++++++----- openpype/hosts/nuke/plugins/load/load_clip.py | 6 +-- .../hosts/nuke/plugins/load/load_effects.py | 30 +++++++------- .../nuke/plugins/load/load_effects_ip.py | 40 ++++++++----------- .../hosts/nuke/plugins/load/load_gizmo.py | 28 +++++++------ .../hosts/nuke/plugins/load/load_gizmo_ip.py | 28 +++++++------ .../hosts/nuke/plugins/load/load_image.py | 6 +-- .../hosts/nuke/plugins/load/load_model.py | 29 ++++++++------ .../hosts/nuke/plugins/load/load_ociolook.py | 25 +++++------- .../nuke/plugins/load/load_script_precomp.py | 7 +--- 11 files changed, 117 insertions(+), 122 deletions(-) diff --git a/openpype/hosts/nuke/plugins/load/load_backdrop.py b/openpype/hosts/nuke/plugins/load/load_backdrop.py index 0cbd380697..54d37da203 100644 --- a/openpype/hosts/nuke/plugins/load/load_backdrop.py +++ b/openpype/hosts/nuke/plugins/load/load_backdrop.py @@ -64,8 +64,7 @@ class LoadBackdropNodes(load.LoaderPlugin): data_imprint = { "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name + "colorspaceInput": colorspace } for k in add_keys: @@ -194,7 +193,7 @@ class LoadBackdropNodes(load.LoaderPlugin): version_doc = get_version_by_id(project_name, representation["parent"]) # get corresponding node - GN = nuke.toNode(container['objectName']) + GN = container["node"] file = get_representation_path(representation).replace("\\", "/") @@ -207,10 +206,11 @@ class LoadBackdropNodes(load.LoaderPlugin): add_keys = ["source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "version": vname, + "colorspaceInput": colorspace, + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -252,6 +252,6 @@ class LoadBackdropNodes(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_camera_abc.py b/openpype/hosts/nuke/plugins/load/load_camera_abc.py index e245b0cb5e..898c5e4e7b 100644 --- a/openpype/hosts/nuke/plugins/load/load_camera_abc.py +++ b/openpype/hosts/nuke/plugins/load/load_camera_abc.py @@ -48,10 +48,11 @@ class AlembicCameraLoader(load.LoaderPlugin): # add additional metadata from the version to imprint to Avalon knob add_keys = ["source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname, + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -111,7 +112,7 @@ class AlembicCameraLoader(load.LoaderPlugin): project_name = get_current_project_name() version_doc = get_version_by_id(project_name, representation["parent"]) - object_name = container['objectName'] + object_name = container["node"] # get main variables version_data = version_doc.get("data", {}) @@ -124,11 +125,12 @@ class AlembicCameraLoader(load.LoaderPlugin): # add additional metadata from the version to imprint to Avalon knob add_keys = ["source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -194,6 +196,6 @@ class AlembicCameraLoader(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_clip.py b/openpype/hosts/nuke/plugins/load/load_clip.py index 737da3746d..3a2ec3dbee 100644 --- a/openpype/hosts/nuke/plugins/load/load_clip.py +++ b/openpype/hosts/nuke/plugins/load/load_clip.py @@ -189,8 +189,6 @@ class LoadClip(plugin.NukeLoader): value_ = value_.replace("\\", "/") data_imprint[key] = value_ - data_imprint["objectName"] = read_name - if add_retime and version_data.get("retime", None): data_imprint["addRetime"] = True @@ -254,7 +252,7 @@ class LoadClip(plugin.NukeLoader): is_sequence = len(representation["files"]) > 1 - read_node = nuke.toNode(container['objectName']) + read_node = container["node"] if is_sequence: representation = self._representation_with_hash_in_frame( @@ -353,7 +351,7 @@ class LoadClip(plugin.NukeLoader): self.set_as_member(read_node) def remove(self, container): - read_node = nuke.toNode(container['objectName']) + read_node = container["node"] assert read_node.Class() == "Read", "Must be Read" with viewer_update_and_undo_stop(): diff --git a/openpype/hosts/nuke/plugins/load/load_effects.py b/openpype/hosts/nuke/plugins/load/load_effects.py index cacc00854e..cc048372d4 100644 --- a/openpype/hosts/nuke/plugins/load/load_effects.py +++ b/openpype/hosts/nuke/plugins/load/load_effects.py @@ -62,11 +62,12 @@ class LoadEffects(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace, + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -159,7 +160,7 @@ class LoadEffects(load.LoaderPlugin): version_doc = get_version_by_id(project_name, representation["parent"]) # get corresponding node - GN = nuke.toNode(container['objectName']) + GN = container["node"] file = get_representation_path(representation).replace("\\", "/") name = container['name'] @@ -175,12 +176,13 @@ class LoadEffects(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -212,7 +214,7 @@ class LoadEffects(load.LoaderPlugin): pre_node = nuke.createNode("Input") pre_node["name"].setValue("rgb") - for ef_name, ef_val in nodes_order.items(): + for _, ef_val in nodes_order.items(): node = nuke.createNode(ef_val["class"]) for k, v in ef_val["node"].items(): if k in self.ignore_attr: @@ -346,6 +348,6 @@ class LoadEffects(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_effects_ip.py b/openpype/hosts/nuke/plugins/load/load_effects_ip.py index bdf3cd6965..cdfdfef3b8 100644 --- a/openpype/hosts/nuke/plugins/load/load_effects_ip.py +++ b/openpype/hosts/nuke/plugins/load/load_effects_ip.py @@ -63,11 +63,12 @@ class LoadEffectsInputProcess(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace, + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -98,7 +99,7 @@ class LoadEffectsInputProcess(load.LoaderPlugin): pre_node = nuke.createNode("Input") pre_node["name"].setValue("rgb") - for ef_name, ef_val in nodes_order.items(): + for _, ef_val in nodes_order.items(): node = nuke.createNode(ef_val["class"]) for k, v in ef_val["node"].items(): if k in self.ignore_attr: @@ -164,28 +165,26 @@ class LoadEffectsInputProcess(load.LoaderPlugin): version_doc = get_version_by_id(project_name, representation["parent"]) # get corresponding node - GN = nuke.toNode(container['objectName']) + GN = container["node"] file = get_representation_path(representation).replace("\\", "/") - name = container['name'] version_data = version_doc.get("data", {}) vname = version_doc.get("name", None) first = version_data.get("frameStart", None) last = version_data.get("frameEnd", None) workfile_first_frame = int(nuke.root()["first_frame"].getValue()) - namespace = container['namespace'] colorspace = version_data.get("colorspace", None) - object_name = "{}_{}".format(name, namespace) add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace, + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -217,7 +216,7 @@ class LoadEffectsInputProcess(load.LoaderPlugin): pre_node = nuke.createNode("Input") pre_node["name"].setValue("rgb") - for ef_name, ef_val in nodes_order.items(): + for _, ef_val in nodes_order.items(): node = nuke.createNode(ef_val["class"]) for k, v in ef_val["node"].items(): if k in self.ignore_attr: @@ -251,11 +250,6 @@ class LoadEffectsInputProcess(load.LoaderPlugin): output = nuke.createNode("Output") output.setInput(0, pre_node) - # # try to place it under Viewer1 - # if not self.connect_active_viewer(GN): - # nuke.delete(GN) - # return - # get all versions in list last_version_doc = get_last_version_by_subset_id( project_name, version_doc["parent"], fields=["_id"] @@ -365,6 +359,6 @@ class LoadEffectsInputProcess(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_gizmo.py b/openpype/hosts/nuke/plugins/load/load_gizmo.py index 23cf4d7741..19b5cca74e 100644 --- a/openpype/hosts/nuke/plugins/load/load_gizmo.py +++ b/openpype/hosts/nuke/plugins/load/load_gizmo.py @@ -64,11 +64,12 @@ class LoadGizmo(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -111,7 +112,7 @@ class LoadGizmo(load.LoaderPlugin): version_doc = get_version_by_id(project_name, representation["parent"]) # get corresponding node - group_node = nuke.toNode(container['objectName']) + group_node = container["node"] file = get_representation_path(representation).replace("\\", "/") name = container['name'] @@ -126,12 +127,13 @@ class LoadGizmo(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -175,6 +177,6 @@ class LoadGizmo(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_gizmo_ip.py b/openpype/hosts/nuke/plugins/load/load_gizmo_ip.py index ce0a1615f1..5b4877678a 100644 --- a/openpype/hosts/nuke/plugins/load/load_gizmo_ip.py +++ b/openpype/hosts/nuke/plugins/load/load_gizmo_ip.py @@ -66,11 +66,12 @@ class LoadGizmoInputProcess(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -118,7 +119,7 @@ class LoadGizmoInputProcess(load.LoaderPlugin): version_doc = get_version_by_id(project_name, representation["parent"]) # get corresponding node - group_node = nuke.toNode(container['objectName']) + group_node = container["node"] file = get_representation_path(representation).replace("\\", "/") name = container['name'] @@ -133,12 +134,13 @@ class LoadGizmoInputProcess(load.LoaderPlugin): add_keys = ["frameStart", "frameEnd", "handleStart", "handleEnd", "source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "colorspaceInput": colorspace, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname, + "colorspaceInput": colorspace + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -256,6 +258,6 @@ class LoadGizmoInputProcess(load.LoaderPlugin): self.update(container, representation) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) diff --git a/openpype/hosts/nuke/plugins/load/load_image.py b/openpype/hosts/nuke/plugins/load/load_image.py index 6bffb97e6f..411a61d77b 100644 --- a/openpype/hosts/nuke/plugins/load/load_image.py +++ b/openpype/hosts/nuke/plugins/load/load_image.py @@ -146,8 +146,6 @@ class LoadImage(load.LoaderPlugin): data_imprint.update( {k: context["version"]['data'].get(k, str(None))}) - data_imprint.update({"objectName": read_name}) - r["tile_color"].setValue(int("0x4ecd25ff", 16)) return containerise(r, @@ -168,7 +166,7 @@ class LoadImage(load.LoaderPlugin): inputs: """ - node = nuke.toNode(container["objectName"]) + node = container["node"] frame_number = node["first"].value() assert node.Class() == "Read", "Must be Read" @@ -237,7 +235,7 @@ class LoadImage(load.LoaderPlugin): self.log.info("updated to version: {}".format(version_doc.get("name"))) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] assert node.Class() == "Read", "Must be Read" with viewer_update_and_undo_stop(): diff --git a/openpype/hosts/nuke/plugins/load/load_model.py b/openpype/hosts/nuke/plugins/load/load_model.py index b9b8a0f4c0..3fe92b74d0 100644 --- a/openpype/hosts/nuke/plugins/load/load_model.py +++ b/openpype/hosts/nuke/plugins/load/load_model.py @@ -46,10 +46,11 @@ class AlembicModelLoader(load.LoaderPlugin): # add additional metadata from the version to imprint to Avalon knob add_keys = ["source", "author", "fps"] - data_imprint = {"frameStart": first, - "frameEnd": last, - "version": vname, - "objectName": object_name} + data_imprint = { + "frameStart": first, + "frameEnd": last, + "version": vname + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -114,9 +115,9 @@ class AlembicModelLoader(load.LoaderPlugin): # Get version from io project_name = get_current_project_name() version_doc = get_version_by_id(project_name, representation["parent"]) - object_name = container['objectName'] + # get corresponding node - model_node = nuke.toNode(object_name) + model_node = container["node"] # get main variables version_data = version_doc.get("data", {}) @@ -129,11 +130,12 @@ class AlembicModelLoader(load.LoaderPlugin): # add additional metadata from the version to imprint to Avalon knob add_keys = ["source", "author", "fps"] - data_imprint = {"representation": str(representation["_id"]), - "frameStart": first, - "frameEnd": last, - "version": vname, - "objectName": object_name} + data_imprint = { + "representation": str(representation["_id"]), + "frameStart": first, + "frameEnd": last, + "version": vname + } for k in add_keys: data_imprint.update({k: version_data[k]}) @@ -142,7 +144,6 @@ class AlembicModelLoader(load.LoaderPlugin): file = get_representation_path(representation).replace("\\", "/") with maintained_selection(): - model_node = nuke.toNode(object_name) model_node['selected'].setValue(True) # collect input output dependencies @@ -163,8 +164,10 @@ class AlembicModelLoader(load.LoaderPlugin): ypos = model_node.ypos() nuke.nodeCopy("%clipboard%") nuke.delete(model_node) + + # paste the node back and set the position nuke.nodePaste("%clipboard%") - model_node = nuke.toNode(object_name) + model_node = nuke.selectedNode() model_node.setXYpos(xpos, ypos) # link to original input nodes diff --git a/openpype/hosts/nuke/plugins/load/load_ociolook.py b/openpype/hosts/nuke/plugins/load/load_ociolook.py index 18c8cdba35..c0f8235253 100644 --- a/openpype/hosts/nuke/plugins/load/load_ociolook.py +++ b/openpype/hosts/nuke/plugins/load/load_ociolook.py @@ -55,7 +55,7 @@ class LoadOcioLookNodes(load.LoaderPlugin): """ namespace = namespace or context['asset']['name'] suffix = secrets.token_hex(nbytes=4) - object_name = "{}_{}_{}".format( + node_name = "{}_{}_{}".format( name, namespace, suffix) # getting file path @@ -64,7 +64,9 @@ class LoadOcioLookNodes(load.LoaderPlugin): json_f = self._load_json_data(filepath) group_node = self._create_group_node( - object_name, filepath, json_f["data"]) + filepath, json_f["data"]) + # renaming group node + group_node["name"].setValue(node_name) self._node_version_color(context["version"], group_node) @@ -76,17 +78,14 @@ class LoadOcioLookNodes(load.LoaderPlugin): name=name, namespace=namespace, context=context, - loader=self.__class__.__name__, - data={ - "objectName": object_name, - } + loader=self.__class__.__name__ ) def _create_group_node( self, - object_name, filepath, - data + data, + group_node=None ): """Creates group node with all the nodes inside. @@ -94,9 +93,9 @@ class LoadOcioLookNodes(load.LoaderPlugin): in between - in case those are needed. Arguments: - object_name (str): name of the group node filepath (str): path to json file data (dict): data from json file + group_node (Optional[nuke.Node]): group node or None Returns: nuke.Node: group node with all the nodes inside @@ -117,7 +116,6 @@ class LoadOcioLookNodes(load.LoaderPlugin): input_node = None output_node = None - group_node = nuke.toNode(object_name) if group_node: # remove all nodes between Input and Output nodes for node in group_node.nodes(): @@ -130,7 +128,6 @@ class LoadOcioLookNodes(load.LoaderPlugin): else: group_node = nuke.createNode( "Group", - "name {}_1".format(object_name), inpanel=False ) @@ -227,16 +224,16 @@ class LoadOcioLookNodes(load.LoaderPlugin): project_name = get_current_project_name() version_doc = get_version_by_id(project_name, representation["parent"]) - object_name = container['objectName'] + group_node = container["node"] filepath = get_representation_path(representation) json_f = self._load_json_data(filepath) group_node = self._create_group_node( - object_name, filepath, - json_f["data"] + json_f["data"], + group_node ) self._node_version_color(version_doc, group_node) diff --git a/openpype/hosts/nuke/plugins/load/load_script_precomp.py b/openpype/hosts/nuke/plugins/load/load_script_precomp.py index d5f9d24765..cbe19d217b 100644 --- a/openpype/hosts/nuke/plugins/load/load_script_precomp.py +++ b/openpype/hosts/nuke/plugins/load/load_script_precomp.py @@ -46,8 +46,6 @@ class LinkAsGroup(load.LoaderPlugin): file = self.filepath_from_context(context).replace("\\", "/") self.log.info("file: {}\n".format(file)) - precomp_name = context["representation"]["context"]["subset"] - self.log.info("versionData: {}\n".format(context["version"]["data"])) # add additional metadata from the version to imprint to Avalon knob @@ -62,7 +60,6 @@ class LinkAsGroup(load.LoaderPlugin): } for k in add_keys: data_imprint.update({k: context["version"]['data'][k]}) - data_imprint.update({"objectName": precomp_name}) # group context is set to precomp, so back up one level. nuke.endGroup() @@ -118,7 +115,7 @@ class LinkAsGroup(load.LoaderPlugin): inputs: """ - node = nuke.toNode(container['objectName']) + node = container["node"] root = get_representation_path(representation).replace("\\", "/") @@ -159,6 +156,6 @@ class LinkAsGroup(load.LoaderPlugin): self.log.info("updated to version: {}".format(version_doc.get("name"))) def remove(self, container): - node = nuke.toNode(container['objectName']) + node = container["node"] with viewer_update_and_undo_stop(): nuke.delete(node) From 8bf570ceef7823a2bf8615a30ac15dfc59c8eaf7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 12:24:25 +0800 Subject: [PATCH 223/690] up version for the max bundle --- server_addon/max/server/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py index 3dc1f76bc6..485f44ac21 100644 --- a/server_addon/max/server/version.py +++ b/server_addon/max/server/version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" From 881340b60a1dd2eba9d76331082679b9e26e6df9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 12:27:22 +0800 Subject: [PATCH 224/690] supports families check before the validation of loaded plugins --- .../plugins/publish/validate_loaded_plugin.py | 59 +++++++++++++------ .../plugins/publish/collect_scene_version.py | 1 + openpype/settings/ayon_settings.py | 13 ++++ .../defaults/project_settings/max.json | 2 +- .../schemas/schema_max_publish.json | 12 ++-- .../max/server/settings/publishers.py | 12 +++- 6 files changed, 74 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 69f72ccf1d..e8284aeedd 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- """Validator for Loaded Plugin.""" -from pyblish.api import ContextPlugin, ValidatorOrder +import os +from pyblish.api import InstancePlugin, ValidatorOrder from pymxs import runtime as rt from openpype.pipeline.publish import ( - RepairContextAction, + RepairAction, OptionalPyblishPluginMixin, PublishValidationError ) @@ -12,7 +13,7 @@ from openpype.hosts.max.api.lib import get_plugins class ValidateLoadedPlugin(OptionalPyblishPluginMixin, - ContextPlugin): + InstancePlugin): """Validates if the specific plugin is loaded in 3ds max. Studio Admin(s) can add the plugins they want to check in validation via studio defined project settings""" @@ -21,17 +22,17 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, hosts = ["max"] label = "Validate Loaded Plugins" optional = True - actions = [RepairContextAction] + actions = [RepairAction] - def get_invalid(self, context): + def get_invalid(self, instance): """Plugin entry point.""" - if not self.is_active(context.data): + if not self.is_active(instance.data): self.log.debug("Skipping Validate Loaded Plugin...") return required_plugins = ( - context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"]["plugins_for_check"] + instance.context.data["project_settings"]["max"]["publish"] + ["ValidateLoadedPlugin"]["family_plugins_mapping"] ) if not required_plugins: @@ -45,9 +46,21 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, get_plugins()) } - for plugin in required_plugins: - plugin_name = plugin.lower() + for families, plugin in required_plugins.items(): + families_list = families.split(",") + excluded_families = [family for family in families_list + if instance.data["family"]!=family + and family!="_"] + if excluded_families: + self.log.debug("The {} instance is not part of {}.".format( + instance.data["family"], excluded_families + )) + return + if not plugin: + return + + plugin_name = plugin.format(**os.environ).lower() plugin_index = available_plugins.get(plugin_name) if plugin_index is None: @@ -61,8 +74,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, return invalid - def process(self, context): - invalid_plugins = self.get_invalid(context) + def process(self, instance): + invalid_plugins = self.get_invalid(instance) if invalid_plugins: bullet_point_invalid_statement = "\n".join( "- {}".format(invalid) for invalid in invalid_plugins @@ -76,18 +89,30 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, report, title="Required Plugins unloaded") @classmethod - def repair(cls, context): + def repair(cls, instance): # get all DLL loaded plugins in Max and their plugin index available_plugins = { plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } required_plugins = ( - context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"]["plugins_for_check"] + instance.context.data["project_settings"]["max"]["publish"] + ["ValidateLoadedPlugin"]["family_plugins_mapping"] ) - for plugin in required_plugins: - plugin_name = plugin.lower() + for families, plugin in required_plugins.items(): + families_list = families.split(",") + excluded_families = [family for family in families_list + if instance.data["family"]!=family + and family!="_"] + if excluded_families: + cls.log.debug("The {} instance is not part of {}.".format( + instance.data["family"], excluded_families + )) + continue + if not plugin: + continue + + plugin_name = plugin.format(**os.environ).lower() plugin_index = available_plugins.get(plugin_name) if plugin_index is None: diff --git a/openpype/plugins/publish/collect_scene_version.py b/openpype/plugins/publish/collect_scene_version.py index 7920c1e82b..f870ae9ad7 100644 --- a/openpype/plugins/publish/collect_scene_version.py +++ b/openpype/plugins/publish/collect_scene_version.py @@ -24,6 +24,7 @@ class CollectSceneVersion(pyblish.api.ContextPlugin): "hiero", "houdini", "maya", + "max", "nuke", "photoshop", "resolve", diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 8d4683490b..0cc2abdda4 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -640,6 +640,19 @@ def _convert_3dsmax_project_settings(ayon_settings, output): } ayon_max["PointCloud"]["attribute"] = new_point_cloud_attribute + ayon_publish = ayon_max["publish"] + if "ValidateLoadedPlugin" in ayon_publish: + family_plugin_mapping = ( + ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] + ) + new_family_plugin_mapping = { + item["families"]: item["plugins"] + for item in family_plugin_mapping + } + ayon_max["ValidateLoadedPlugin"]["family_plugins_mapping"] = ( + new_family_plugin_mapping + ) + output["max"] = ayon_max diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index 45246fdf2b..78eba08750 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -40,7 +40,7 @@ "ValidateLoadedPlugin": { "enabled": false, "optional": true, - "plugins_for_check": [] + "family_plugins_mapping": {} } } } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json index 4490c5353d..74c06f8156 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json @@ -47,10 +47,14 @@ "label": "Optional" }, { - "type": "list", - "key": "plugins_for_check", - "label": "Plugins Needed For Check", - "object_type": "text" + "type": "dict-modifiable", + "collapsible": true, + "key": "family_plugins_mapping", + "label": "Family Plugins Mapping", + "use_label_wrap": true, + "object_type": { + "type": "text" + } } ] } diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index 8a28224a07..3cf3ecf2a5 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -3,11 +3,17 @@ from pydantic import Field from ayon_server.settings import BaseSettingsModel +class FamilyPluginsMappingModel(BaseSettingsModel): + _layout = "compact" + families: str = Field(title="Families") + plugins: str = Field(title="Plugins") + + class ValidateLoadedPluginModel(BaseSettingsModel): enabled: bool = Field(title="ValidateLoadedPlugin") optional: bool = Field(title="Optional") - plugins_for_check: list[str] = Field( - default_factory=list, title="Plugins Needed For Check" + family_plugins_mapping: list[FamilyPluginsMappingModel] = Field( + default_factory=list, title="Family Plugins Mapping" ) @@ -37,6 +43,6 @@ DEFAULT_PUBLISH_SETTINGS = { "ValidateLoadedPlugin": { "enabled": False, "optional": True, - "plugins_for_check": [] + "family_plugins_mapping": {} } } From 8d727a9b80922bb07b468f694ab4f57f69945926 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 12:30:38 +0800 Subject: [PATCH 225/690] hound --- .../max/plugins/publish/validate_loaded_plugin.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index e8284aeedd..dc82c7ed65 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -32,7 +32,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, required_plugins = ( instance.context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"]["family_plugins_mapping"] + ["ValidateLoadedPlugin"] + ["family_plugins_mapping"] ) if not required_plugins: @@ -49,8 +50,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, for families, plugin in required_plugins.items(): families_list = families.split(",") excluded_families = [family for family in families_list - if instance.data["family"]!=family - and family!="_"] + if instance.data["family"] != family + and family != "_"] if excluded_families: self.log.debug("The {} instance is not part of {}.".format( instance.data["family"], excluded_families @@ -97,13 +98,14 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, } required_plugins = ( instance.context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"]["family_plugins_mapping"] + ["ValidateLoadedPlugin"] + ["family_plugins_mapping"] ) for families, plugin in required_plugins.items(): families_list = families.split(",") excluded_families = [family for family in families_list - if instance.data["family"]!=family - and family!="_"] + if instance.data["family"] != family + and family != "_"] if excluded_families: cls.log.debug("The {} instance is not part of {}.".format( instance.data["family"], excluded_families From 1aef9dc449b525313760db6e3d7e86378e6f1ab9 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 12:45:48 +0800 Subject: [PATCH 226/690] make sure the validator can be loaded in AYON --- openpype/settings/ayon_settings.py | 2 +- server_addon/max/server/settings/publishers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 0cc2abdda4..4fe19c95a2 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -649,7 +649,7 @@ def _convert_3dsmax_project_settings(ayon_settings, output): item["families"]: item["plugins"] for item in family_plugin_mapping } - ayon_max["ValidateLoadedPlugin"]["family_plugins_mapping"] = ( + ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] = ( new_family_plugin_mapping ) diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index 3cf3ecf2a5..d0fbb3d552 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -43,6 +43,6 @@ DEFAULT_PUBLISH_SETTINGS = { "ValidateLoadedPlugin": { "enabled": False, "optional": True, - "family_plugins_mapping": {} + "family_plugins_mapping": [] } } From 3da4e1c8e7eafec01b4a501234c6a78cf7a1c686 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Thu, 2 Nov 2023 08:33:08 +0000 Subject: [PATCH 227/690] Add Nuke 11.0 --- .../system_settings/applications.json | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/openpype/settings/defaults/system_settings/applications.json b/openpype/settings/defaults/system_settings/applications.json index 6a0ddb398e..a5283751e9 100644 --- a/openpype/settings/defaults/system_settings/applications.json +++ b/openpype/settings/defaults/system_settings/applications.json @@ -344,13 +344,30 @@ }, "environment": {} }, + "11-0": { + "use_python_2": true, + "executables": { + "windows": [ + "C:\\Program Files\\Nuke11.0v4\\Nuke11.0.exe" + ], + "darwin": [], + "linux": [] + }, + "arguments": { + "windows": [], + "darwin": [], + "linux": [] + }, + "environment": {} + }, "__dynamic_keys_labels__": { "13-2": "13.2", "13-0": "13.0", "12-2": "12.2", "12-0": "12.0", "11-3": "11.3", - "11-2": "11.2" + "11-2": "11.2", + "11-0": "11.0" } } }, From 58c9664f7e8ac2082a44279e652a1fb82674769d Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 2 Nov 2023 10:39:28 +0000 Subject: [PATCH 228/690] Use sets and don't check container children when getting unique number --- openpype/hosts/blender/api/plugin.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 45b0c60b3b..2f940011ba 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -44,15 +44,15 @@ def get_unique_number( if not avalon_container: return "01" # Check the names of both object and collection containers - obj_asset_groups = avalon_container.all_objects - obj_group_names = [ + obj_asset_groups = avalon_container.objects + obj_group_names = { c.name for c in obj_asset_groups - if c.type == 'EMPTY' and c.get(AVALON_PROPERTY)] - coll_asset_groups = avalon_container.children_recursive - coll_group_names = [ + if c.type == 'EMPTY' and c.get(AVALON_PROPERTY)} + coll_asset_groups = avalon_container.children + coll_group_names = { c.name for c in coll_asset_groups - if c.get(AVALON_PROPERTY)] - container_names = obj_group_names + coll_group_names + if c.get(AVALON_PROPERTY)} + container_names = obj_group_names.union(coll_group_names) count = 1 name = f"{asset}_{count:0>2}_{subset}" while name in container_names: From 59bb86dc3337cb340d3ed9bf1c842167f98fa6b0 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 2 Nov 2023 11:42:39 +0100 Subject: [PATCH 229/690] Rename BlenderCreator into BaseCreator --- openpype/hosts/blender/api/plugin.py | 2 +- openpype/hosts/blender/plugins/create/create_action.py | 2 +- openpype/hosts/blender/plugins/create/create_animation.py | 2 +- openpype/hosts/blender/plugins/create/create_camera.py | 2 +- openpype/hosts/blender/plugins/create/create_layout.py | 2 +- openpype/hosts/blender/plugins/create/create_model.py | 2 +- openpype/hosts/blender/plugins/create/create_pointcache.py | 2 +- openpype/hosts/blender/plugins/create/create_render.py | 2 +- openpype/hosts/blender/plugins/create/create_review.py | 2 +- openpype/hosts/blender/plugins/create/create_rig.py | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index dbd9f25d68..3ddc375670 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -140,7 +140,7 @@ def deselect_all(): bpy.context.view_layer.objects.active = active -class BlenderCreator(Creator): +class BaseCreator(Creator): """Base class for Blender Creator plug-ins.""" defaults = ['Main'] diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index e7b689c54e..7d00aa1dcb 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -8,7 +8,7 @@ from openpype.hosts.blender.api import lib from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class CreateAction(openpype.hosts.blender.api.plugin.BlenderCreator): +class CreateAction(openpype.hosts.blender.api.plugin.BaseCreator): """Action output for character rigs""" identifier = "io.openpype.creators.blender.action" diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 8b4214ceda..6cfd054e74 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateAnimation(plugin.BlenderCreator): +class CreateAnimation(plugin.BaseCreator): """Animation output for character rigs""" identifier = "io.openpype.creators.blender.animation" diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 4747e50b2e..5d9682e575 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateCamera(plugin.BlenderCreator): +class CreateCamera(plugin.BaseCreator): """Polygonal static geometry""" identifier = "io.openpype.creators.blender.camera" diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index 0c97d57af3..ed47b0632f 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateLayout(plugin.BlenderCreator): +class CreateLayout(plugin.BaseCreator): """Layout output for character rigs""" identifier = "io.openpype.creators.blender.layout" diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 761d9fca9f..949fae0f76 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateModel(plugin.BlenderCreator): +class CreateModel(plugin.BaseCreator): """Polygonal static geometry""" identifier = "io.openpype.creators.blender.model" diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index a40bd5af61..2ad12caa9c 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -8,7 +8,7 @@ from openpype.hosts.blender.api.pipeline import AVALON_INSTANCES from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY -class CreatePointcache(plugin.BlenderCreator): +class CreatePointcache(plugin.BaseCreator): """Polygonal static geometry""" identifier = "io.openpype.creators.blender.pointcache" diff --git a/openpype/hosts/blender/plugins/create/create_render.py b/openpype/hosts/blender/plugins/create/create_render.py index ab3119b32e..45570f3491 100644 --- a/openpype/hosts/blender/plugins/create/create_render.py +++ b/openpype/hosts/blender/plugins/create/create_render.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateRenderlayer(plugin.BlenderCreator): +class CreateRenderlayer(plugin.BaseCreator): """Single baked camera""" name = "renderingMain" diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index 8c9a8d5927..e8b893b4c0 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateReview(plugin.BlenderCreator): +class CreateReview(plugin.BaseCreator): """Single baked camera""" identifier = "io.openpype.creators.blender.review" diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 110a9f5c8e..6223e64174 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -10,7 +10,7 @@ from openpype.hosts.blender.api.pipeline import ( ) -class CreateRig(plugin.BlenderCreator): +class CreateRig(plugin.BaseCreator): """Artist-friendly rig with controls to direct motion""" identifier = "io.openpype.creators.blender.rig" From 7a1099b57e351e47d57e500c9184d2183527e61d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:08:49 +0100 Subject: [PATCH 230/690] fix access to bundles in dev mode --- openpype/settings/ayon_settings.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 8d4683490b..5b179158f0 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -1436,7 +1436,10 @@ class _AyonSettingsCache: def _use_bundles(cls): if _AyonSettingsCache.use_bundles is None: major, minor, _, _, _ = ayon_api.get_server_version_tuple() - _AyonSettingsCache.use_bundles = major == 0 and minor >= 3 + use_bundles = True + if (major, minor) < (0, 3): + use_bundles = False + _AyonSettingsCache.use_bundles = use_bundles return _AyonSettingsCache.use_bundles @classmethod @@ -1467,7 +1470,7 @@ class _AyonSettingsCache: bundles = ayon_api.get_bundles() user = ayon_api.get_user() username = user["name"] - for bundle in bundles: + for bundle in bundles["bundles"]: if ( bundle.get("isDev") and bundle.get("activeUser") == username From 13ec4d9a537296e648a4cf33ab5e9da865e78145 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:31:58 +0100 Subject: [PATCH 231/690] fix formatting order --- openpype/modules/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index e8b85d0e93..15bde39f68 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -106,7 +106,7 @@ class _ModuleClass(object): if attr_name in self.__attributes__: self.log.warning( "Duplicated name \"{}\" in {}. Overriding.".format( - self.name, attr_name + attr_name, self.name ) ) self.__attributes__[attr_name] = value From 36f928151dc1e9a9996654ff8d698b7f1b51058a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:32:18 +0100 Subject: [PATCH 232/690] safe call of get plugins path --- openpype/modules/base.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 15bde39f68..f47baa0e4d 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -997,7 +997,17 @@ class ModulesManager: continue method = getattr(module, method_name) - paths = method(*args, **kwargs) + try: + paths = method(*args, **kwargs) + except Exception: + self.log.warning( + "Failed to get plugin paths from module {}.".format( + module.__class__.__name__ + ), + exc_info=True + ) + continue + if paths: # Convert to list if value is not list if not isinstance(paths, (list, tuple, set)): From f912c2c69c9743be16705781d4a388c355ecf68c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:32:35 +0100 Subject: [PATCH 233/690] change if conditions order --- openpype/modules/base.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index f47baa0e4d..1a3280a6e5 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -467,19 +467,19 @@ def _load_ayon_addons(openpype_modules, modules_key, log): )) continue - if len(imported_modules) == 1: - mod = imported_modules[0] - addon_alias = getattr(mod, "V3_ALIAS", None) - if not addon_alias: - addon_alias = addon_name - v3_addons_to_skip.append(addon_alias) - new_import_str = "{}.{}".format(modules_key, addon_alias) + if len(imported_modules) > 1: + log.info("More then one module '{}' was imported.".format(name)) + continue - sys.modules[new_import_str] = mod - setattr(openpype_modules, addon_alias, mod) + mod = imported_modules[0] + addon_alias = getattr(mod, "V3_ALIAS", None) + if not addon_alias: + addon_alias = addon_name + v3_addons_to_skip.append(addon_alias) + new_import_str = "{}.{}".format(modules_key, addon_alias) - else: - log.info("More then one module was imported") + sys.modules[new_import_str] = mod + setattr(openpype_modules, addon_alias, mod) return v3_addons_to_skip From d55ac7aff7cd7d470ddac5aa9d8f9d2b43cf2cd2 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:33:23 +0100 Subject: [PATCH 234/690] removed unused import --- openpype/hosts/tvpaint/api/pipeline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/tvpaint/api/pipeline.py b/openpype/hosts/tvpaint/api/pipeline.py index 58fbd09545..a84f196f09 100644 --- a/openpype/hosts/tvpaint/api/pipeline.py +++ b/openpype/hosts/tvpaint/api/pipeline.py @@ -7,7 +7,7 @@ import requests import pyblish.api -from openpype.client import get_project, get_asset_by_name +from openpype.client import get_asset_by_name from openpype.host import HostBase, IWorkfileHost, ILoadHost, IPublishHost from openpype.hosts.tvpaint import TVPAINT_ROOT_DIR from openpype.settings import get_current_project_settings From 9d77421d9de2b2a7cee1d8c9e32290a632f6ac80 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:33:36 +0100 Subject: [PATCH 235/690] use AYON label when in AYON mode --- openpype/hosts/tvpaint/api/communication_server.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/tvpaint/api/communication_server.py b/openpype/hosts/tvpaint/api/communication_server.py index d67ef8f798..34302eef6e 100644 --- a/openpype/hosts/tvpaint/api/communication_server.py +++ b/openpype/hosts/tvpaint/api/communication_server.py @@ -21,6 +21,7 @@ from aiohttp_json_rpc.protocol import ( ) from aiohttp_json_rpc.exceptions import RpcError +from openpype import AYON_SERVER_ENABLED from openpype.lib import emit_event from openpype.hosts.tvpaint.tvpaint_plugin import get_plugin_files_path @@ -834,8 +835,9 @@ class BaseCommunicator: class QtCommunicator(BaseCommunicator): + title = "AYON Tools" if AYON_SERVER_ENABLED else "OpenPype Tools" menu_definitions = { - "title": "OpenPype Tools", + "title": title, "menu_items": [ { "callback": "workfiles_tool", From 0cc90ceb081a5988192a993374b488ea0051618f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 12:33:46 +0100 Subject: [PATCH 236/690] removed unused 'previous_context' data --- openpype/hosts/tvpaint/plugins/publish/collect_workfile_data.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/hosts/tvpaint/plugins/publish/collect_workfile_data.py b/openpype/hosts/tvpaint/plugins/publish/collect_workfile_data.py index 95a5cd77bd..56b51c812a 100644 --- a/openpype/hosts/tvpaint/plugins/publish/collect_workfile_data.py +++ b/openpype/hosts/tvpaint/plugins/publish/collect_workfile_data.py @@ -69,7 +69,6 @@ class CollectWorkfileData(pyblish.api.ContextPlugin): "asset_name": context.data["asset"], "task_name": context.data["task"] } - context.data["previous_context"] = current_context self.log.debug("Current context is: {}".format(current_context)) # Collect context from workfile metadata From add4a1566d9dde015ac9b4422c0497f1c8710ab0 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 2 Nov 2023 13:40:41 +0100 Subject: [PATCH 237/690] Use 'AVALON_LABEL' for label --- openpype/hosts/tvpaint/api/communication_server.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/tvpaint/api/communication_server.py b/openpype/hosts/tvpaint/api/communication_server.py index 34302eef6e..2c4d8160a6 100644 --- a/openpype/hosts/tvpaint/api/communication_server.py +++ b/openpype/hosts/tvpaint/api/communication_server.py @@ -835,7 +835,10 @@ class BaseCommunicator: class QtCommunicator(BaseCommunicator): - title = "AYON Tools" if AYON_SERVER_ENABLED else "OpenPype Tools" + label = os.getenv("AVALON_LABEL") + if not label: + label = "AYON" if AYON_SERVER_ENABLED else "OpenPype" + title = "{} Tools".format(label) menu_definitions = { "title": title, "menu_items": [ From e9699d2cef653a00b185ed04d7874c458ae18f94 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 2 Nov 2023 13:43:27 +0100 Subject: [PATCH 238/690] fix grammar and use warning Co-authored-by: Roy Nieterau --- openpype/modules/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 1a3280a6e5..2d3f0d4bc1 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -468,7 +468,7 @@ def _load_ayon_addons(openpype_modules, modules_key, log): continue if len(imported_modules) > 1: - log.info("More then one module '{}' was imported.".format(name)) + log.warning("More than one module '{}' was imported.".format(name)) continue mod = imported_modules[0] From 88116be4c63079598ec8a38b45ad3cc329155a87 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 20:44:21 +0800 Subject: [PATCH 239/690] allows users to preset the settings before the creator setting --- .../hosts/max/plugins/create/create_review.py | 58 ++++++++--- openpype/plugins/publish/extract_review.py | 2 +- .../defaults/project_settings/max.json | 10 ++ .../projects_schema/schema_project_max.json | 98 +++++++++++++++++++ 4 files changed, 154 insertions(+), 14 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_review.py b/openpype/hosts/max/plugins/create/create_review.py index 8052b74f06..67dc158001 100644 --- a/openpype/hosts/max/plugins/create/create_review.py +++ b/openpype/hosts/max/plugins/create/create_review.py @@ -12,6 +12,32 @@ class CreateReview(plugin.MaxCreator): family = "review" icon = "video-camera" + review_width = 1920 + review_height = 1080 + percentSize = 100 + keep_images = False + image_format = "png" + visual_style = "Realistic" + viewport_preset = "Quality" + vp_texture = True + anti_aliasing = None + + + @classmethod + def apply_settings(cls, project_settings): + settings = project_settings["max"]["PreviewAnimation"] # noqa + + # Take some defaults from settings + cls.review_width = settings.get("review_width", cls.review_width) + cls.review_height = settings.get("review_height", cls.review_height) + cls.percentSize = settings.get("percentSize", cls.percentSize) + cls.keep_images = settings.get("keep_images", cls.keep_images) + cls.image_format = settings.get("image_format", cls.image_format) + cls.visual_style = settings.get("visual_style", cls.visual_style) + cls.viewport_preset = settings.get("viewport_preset", cls.viewport_preset) + cls.vp_texture = settings.get("vp_texture", cls.vp_texture) + cls.anti_aliasing = settings.get("anti_aliasing", cls.anti_aliasing) + def create(self, subset_name, instance_data, pre_create_data): # Transfer settings from pre create to instance creator_attributes = instance_data.setdefault( @@ -23,6 +49,7 @@ class CreateReview(plugin.MaxCreator): "percentSize", "visualStyleMode", "viewportPreset", + "anti_aliasing", "vpTexture"]: if key in pre_create_data: creator_attributes[key] = pre_create_data[key] @@ -33,7 +60,7 @@ class CreateReview(plugin.MaxCreator): pre_create_data) def get_instance_attr_defs(self): - image_format_enum = ["exr", "jpg", "png"] + image_format_enum = ["exr", "jpg", "png", "tga"] visual_style_preset_enum = [ "Realistic", "Shaded", "Facets", @@ -45,41 +72,46 @@ class CreateReview(plugin.MaxCreator): preview_preset_enum = [ "Quality", "Standard", "Performance", "DXMode", "Customize"] + anti_aliasing_enum = ["None", "2X", "4X", "8X"] return [ NumberDef("review_width", label="Review width", decimals=0, minimum=0, - default=1920), + default=self.review_width), NumberDef("review_height", label="Review height", decimals=0, minimum=0, - default=1080), - BoolDef("keepImages", - label="Keep Image Sequences", - default=False), - EnumDef("imageFormat", - image_format_enum, - default="png", - label="Image Format Options"), + default=self.review_height), NumberDef("percentSize", label="Percent of Output", default=100, minimum=1, decimals=0), + BoolDef("keepImages", + label="Keep Image Sequences", + default=self.keep_images), + EnumDef("imageFormat", + image_format_enum, + default=self.image_format, + label="Image Format Options"), EnumDef("visualStyleMode", visual_style_preset_enum, - default="Realistic", + default=self.visual_style, label="Preference"), EnumDef("viewportPreset", preview_preset_enum, - default="Quality", + default=self.viewport_preset, label="Pre-View Preset"), + EnumDef("anti_aliasing", + anti_aliasing_enum, + default=self.anti_aliasing, + label="Anti-aliasing Quality"), BoolDef("vpTexture", label="Viewport Texture", - default=False) + default=self.vp_texture) ] def get_pre_create_attr_defs(self): diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 0ae941511c..db8a030dfa 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -68,7 +68,7 @@ class ExtractReview(pyblish.api.InstancePlugin): ] # Supported extensions - image_exts = ["exr", "jpg", "jpeg", "png", "dpx"] + image_exts = ["exr", "jpg", "jpeg", "png", "dpx", "tga"] video_exts = ["mov", "mp4"] supported_exts = image_exts + video_exts diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index bfb1aa4aeb..c610a963d4 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -16,6 +16,16 @@ "image_format": "exr", "multipass": true }, + "PreviewAnimation": { + "review_width": 1920, + "review_height": 1080, + "percentSize": 100, + "keep_images": false, + "image_format": "png", + "visual_style": "Realistic", + "viewport_preset": "Quality", + "vp_texture": true + }, "PointCloud": { "attribute": { "Age": "age", diff --git a/openpype/settings/entities/schemas/projects_schema/schema_project_max.json b/openpype/settings/entities/schemas/projects_schema/schema_project_max.json index e314174dff..b012e73fc4 100644 --- a/openpype/settings/entities/schemas/projects_schema/schema_project_max.json +++ b/openpype/settings/entities/schemas/projects_schema/schema_project_max.json @@ -65,6 +65,104 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "PreviewAnimation", + "label": "Preview Animation", + "children": [ + { + "type": "number", + "key": "review_width", + "label": "Review Width" + }, + { + "type": "number", + "key": "review_height", + "label": "Review Height" + }, + { + "type": "number", + "key": "percentSize", + "label": "Percent of Output" + }, + { + "type": "boolean", + "key": "keep_images", + "label": "Keep Image Sequences" + }, + { + "key": "image_format", + "label": "Image Format Options", + "type": "enum", + "multiselection": false, + "defaults": "exr", + "enum_items": [ + {"exr": "exr"}, + {"jpg": "jpg"}, + {"png": "png"}, + {"tga": "tga"} + ] + }, + { + "key": "visual_style", + "label": "Preference", + "type": "enum", + "multiselection": false, + "defaults": "Realistic", + "enum_items": [ + {"Realistic": "Realistic"}, + {"Shaded": "Shaded"}, + {"Facets": "Facets"}, + {"ConsistentColors": "ConsistentColors"}, + {"HiddenLine": "HiddenLine"}, + {"Wireframe": "Wireframe"}, + {"BoundingBox": "BoundingBox"}, + {"Ink": "Ink"}, + {"ColorInk": "ColorInk"}, + {"Acrylic": "Acrylic"}, + {"Tech": "Tech"}, + {"Graphite": "Graphite"}, + {"ColorPencil": "ColorPencil"}, + {"Pastel": "Pastel"}, + {"Clay": "Clay"}, + {"ModelAssist": "ModelAssist"} + ] + }, + { + "key": "viewport_preset", + "label": "Pre-View Preset", + "type": "enum", + "multiselection": false, + "defaults": "Quality", + "enum_items": [ + {"Quality": "Quality"}, + {"Standard": "Standard"}, + {"Performance": "Performance"}, + {"DXMode": "DXMode"}, + {"Customize": "Customize"} + ] + }, + { + "key": "anti_aliasing", + "label": "Anti-aliasing Quality", + "type": "enum", + "multiselection": false, + "defaults": "None", + "enum_items": [ + {"None": "None"}, + {"2X": "2X"}, + {"4X": "4X"}, + {"8X": "8X"} + ] + }, + { + "type": "boolean", + "key": "vp_texture", + "label": "Viewport Texture" + } + ] + }, { "type": "dict", "collapsible": true, From 3428ec08a5592e54586ea8f0126e4907a8f4eeee Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 13:46:05 +0100 Subject: [PATCH 240/690] log which method was used to get plugins --- openpype/modules/base.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 2d3f0d4bc1..03ec3d271a 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -1001,9 +1001,10 @@ class ModulesManager: paths = method(*args, **kwargs) except Exception: self.log.warning( - "Failed to get plugin paths from module {}.".format( - module.__class__.__name__ - ), + ( + "Failed to get plugin paths from module" + " '{}' using '{}'." + ).format(module.__class__.__name__, method_name), exc_info=True ) continue From 597260ad520393f2942b5685a817210d18544f45 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 20:49:40 +0800 Subject: [PATCH 241/690] cosmetic fix --- openpype/settings/defaults/project_settings/max.json | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index c610a963d4..ac04c60b54 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -24,6 +24,7 @@ "image_format": "png", "visual_style": "Realistic", "viewport_preset": "Quality", + "anti_aliasing": "None", "vp_texture": true }, "PointCloud": { From 026aae1d0d9ebc6409acedc545c9d20950b5365a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 21:35:18 +0800 Subject: [PATCH 242/690] add AA quality setting options & add the correct aspect ratio --- openpype/hosts/max/api/preview_animation.py | 4 +++- openpype/hosts/max/plugins/create/create_review.py | 8 +++++++- openpype/hosts/max/plugins/publish/collect_review.py | 1 + openpype/plugins/publish/extract_review.py | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index dcf243d31e..5f36b12edb 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -189,7 +189,8 @@ def _render_preview_animation_max_pre_2024( dib = rt.gw.getViewportDib() dib_width = float(dib.width) dib_height = float(dib.height) - renderRatio = float(dib_width / dib_height) + # aspect ratio + renderRatio = rt.getRendImageAspect() if viewportRatio <= renderRatio: heightCrop = (dib_width / renderRatio) topEdge = int((dib_height - heightCrop) / 2.0) @@ -311,6 +312,7 @@ def viewport_options_for_preview_animation(): viewport_options["nitrous_viewport"] = { "VisualStyleMode": "defaultshading", "ViewportPreset": "highquality", + "AntialiasingQuality": "None", "UseTextureEnabled": False } viewport_options["vp_btn_mgr"] = { diff --git a/openpype/hosts/max/plugins/create/create_review.py b/openpype/hosts/max/plugins/create/create_review.py index 8052b74f06..331d2f30ea 100644 --- a/openpype/hosts/max/plugins/create/create_review.py +++ b/openpype/hosts/max/plugins/create/create_review.py @@ -23,6 +23,7 @@ class CreateReview(plugin.MaxCreator): "percentSize", "visualStyleMode", "viewportPreset", + "antialiasingQuality", "vpTexture"]: if key in pre_create_data: creator_attributes[key] = pre_create_data[key] @@ -33,7 +34,7 @@ class CreateReview(plugin.MaxCreator): pre_create_data) def get_instance_attr_defs(self): - image_format_enum = ["exr", "jpg", "png"] + image_format_enum = ["exr", "jpg", "png", "tga"] visual_style_preset_enum = [ "Realistic", "Shaded", "Facets", @@ -45,6 +46,7 @@ class CreateReview(plugin.MaxCreator): preview_preset_enum = [ "Quality", "Standard", "Performance", "DXMode", "Customize"] + anti_aliasing_enum = ["None", "2X", "4X", "8X"] return [ NumberDef("review_width", @@ -77,6 +79,10 @@ class CreateReview(plugin.MaxCreator): preview_preset_enum, default="Quality", label="Pre-View Preset"), + EnumDef("antialiasingQuality", + anti_aliasing_enum, + default="None", + label="Anti-aliasing Quality"), BoolDef("vpTexture", label="Viewport Texture", default=False) diff --git a/openpype/hosts/max/plugins/publish/collect_review.py b/openpype/hosts/max/plugins/publish/collect_review.py index b1d9c2d25e..a579b3f4b0 100644 --- a/openpype/hosts/max/plugins/publish/collect_review.py +++ b/openpype/hosts/max/plugins/publish/collect_review.py @@ -93,6 +93,7 @@ class CollectReview(pyblish.api.InstancePlugin, nitrous_viewport = { "VisualStyleMode": creator_attrs["visualStyleMode"], "ViewportPreset": creator_attrs["viewportPreset"], + "AntialiasingQuality": creator_attrs["antialiasingQuality"], "UseTextureEnabled": creator_attrs["vpTexture"] } preview_data = { diff --git a/openpype/plugins/publish/extract_review.py b/openpype/plugins/publish/extract_review.py index 0ae941511c..db8a030dfa 100644 --- a/openpype/plugins/publish/extract_review.py +++ b/openpype/plugins/publish/extract_review.py @@ -68,7 +68,7 @@ class ExtractReview(pyblish.api.InstancePlugin): ] # Supported extensions - image_exts = ["exr", "jpg", "jpeg", "png", "dpx"] + image_exts = ["exr", "jpg", "jpeg", "png", "dpx", "tga"] video_exts = ["mov", "mp4"] supported_exts = image_exts + video_exts From 2d940227b1144e67c0dc37384575aea067a37d25 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 14:54:29 +0100 Subject: [PATCH 243/690] skip openpype addon --- openpype/modules/base.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 03ec3d271a..aa3deff475 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -408,6 +408,10 @@ def _load_ayon_addons(openpype_modules, modules_key, log): addon_name = addon_info["name"] addon_version = addon_info["version"] + # OpenPype addon does not have any addon object + if addon_name == "openpype": + continue + dev_addon_info = dev_addons_info.get(addon_name, {}) use_dev_path = dev_addon_info.get("enabled", False) From 27dd549c7dae21960f38e548598da4d884b61cd8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 14:54:40 +0100 Subject: [PATCH 244/690] ignore pycahce folders --- openpype/modules/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index aa3deff475..df7286e7b7 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -442,7 +442,7 @@ def _load_ayon_addons(openpype_modules, modules_key, log): # Ignore of files is implemented to be able to run code from code # where usually is more files than just the addon # Ignore start and setup scripts - if name in ("setup.py", "start.py"): + if name in ("setup.py", "start.py", "__pycache__"): continue path = os.path.join(addon_dir, name) From 87c3682d61392b1828e6b4c09060a77400f14b00 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 14:55:06 +0100 Subject: [PATCH 245/690] imported modules must have Module class --- openpype/modules/base.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index df7286e7b7..eb6e7d6b73 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -458,7 +458,15 @@ def _load_ayon_addons(openpype_modules, modules_key, log): try: mod = __import__(basename, fromlist=("",)) - imported_modules.append(mod) + for attr_name in dir(mod): + attr = getattr(mod, attr_name) + if ( + inspect.isclass(attr) + and issubclass(attr, OpenPypeModule) + ): + imported_modules.append(mod) + break + except BaseException: log.warning( "Failed to import \"{}\"".format(basename), From db26cdd6e35a08d0025dcf8a54024b17af484099 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 21:55:22 +0800 Subject: [PATCH 246/690] hound --- openpype/hosts/max/plugins/create/create_review.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openpype/hosts/max/plugins/create/create_review.py b/openpype/hosts/max/plugins/create/create_review.py index 67dc158001..ed0359ebd7 100644 --- a/openpype/hosts/max/plugins/create/create_review.py +++ b/openpype/hosts/max/plugins/create/create_review.py @@ -22,7 +22,6 @@ class CreateReview(plugin.MaxCreator): vp_texture = True anti_aliasing = None - @classmethod def apply_settings(cls, project_settings): settings = project_settings["max"]["PreviewAnimation"] # noqa @@ -34,9 +33,11 @@ class CreateReview(plugin.MaxCreator): cls.keep_images = settings.get("keep_images", cls.keep_images) cls.image_format = settings.get("image_format", cls.image_format) cls.visual_style = settings.get("visual_style", cls.visual_style) - cls.viewport_preset = settings.get("viewport_preset", cls.viewport_preset) + cls.viewport_preset = settings.get( + "viewport_preset", cls.viewport_preset) cls.vp_texture = settings.get("vp_texture", cls.vp_texture) - cls.anti_aliasing = settings.get("anti_aliasing", cls.anti_aliasing) + cls.anti_aliasing = settings.get( + "anti_aliasing", cls.anti_aliasing) def create(self, subset_name, instance_data, pre_create_data): # Transfer settings from pre create to instance @@ -49,7 +50,7 @@ class CreateReview(plugin.MaxCreator): "percentSize", "visualStyleMode", "viewportPreset", - "anti_aliasing", + "antialiasingQuality", "vpTexture"]: if key in pre_create_data: creator_attributes[key] = pre_create_data[key] @@ -105,7 +106,7 @@ class CreateReview(plugin.MaxCreator): preview_preset_enum, default=self.viewport_preset, label="Pre-View Preset"), - EnumDef("anti_aliasing", + EnumDef("antialiasingQuality", anti_aliasing_enum, default=self.anti_aliasing, label="Anti-aliasing Quality"), From 541d333ab8f2ee0b92bab36d96b8c07e7a2457dc Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 2 Nov 2023 14:56:33 +0100 Subject: [PATCH 247/690] more specific message when loaded multiple modules in addon dir --- openpype/modules/base.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openpype/modules/base.py b/openpype/modules/base.py index eb6e7d6b73..457e29905d 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -480,7 +480,14 @@ def _load_ayon_addons(openpype_modules, modules_key, log): continue if len(imported_modules) > 1: - log.warning("More than one module '{}' was imported.".format(name)) + log.warning(( + "Skipping addon '{}'." + " Multiple modules were found ({}) in dir {}." + ).format( + addon_name, + ", ".join([m.__name__ for m in imported_modules]), + addon_dir, + )) continue mod = imported_modules[0] From 487d8dfde72a9af0b2964a15d4b57a07954ce767 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 2 Nov 2023 22:34:20 +0800 Subject: [PATCH 248/690] make sure the code doesn't break the extractor --- openpype/hosts/max/api/preview_animation.py | 14 +++++++++++++- .../hosts/max/plugins/publish/collect_review.py | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index 5f36b12edb..0754fa61c4 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -52,6 +52,7 @@ def viewport_layout_and_camera(camera, layout="layout_1"): @contextlib.contextmanager def viewport_preference_setting(general_viewport, + nitrous_manager, nitrous_viewport, vp_button_mgr): """Function to set viewport setting during context @@ -59,6 +60,7 @@ def viewport_preference_setting(general_viewport, Args: camera (str): Viewport camera for review render general_viewport (dict): General viewport setting + nitrous_manager (dict): Nitrous graphic manager nitrous_viewport (dict): Nitrous setting for preview animation vp_button_mgr (dict): Viewport button manager Setting @@ -72,6 +74,9 @@ def viewport_preference_setting(general_viewport, vp_button_mgr_original = { key: getattr(rt.ViewportButtonMgr, key) for key in vp_button_mgr } + nitrous_manager_original = { + key: getattr(nitrousGraphicMgr, key) for key in nitrous_manager + } nitrous_viewport_original = { key: getattr(viewport_setting, key) for key in nitrous_viewport } @@ -81,6 +86,8 @@ def viewport_preference_setting(general_viewport, rt.viewport.EnableSolidBackgroundColorMode(general_viewport["dspBkg"]) for key, value in vp_button_mgr.items(): setattr(rt.ViewportButtonMgr, key, value) + for key, value in nitrous_manager.items(): + setattr(nitrousGraphicMgr, key, value) for key, value in nitrous_viewport.items(): if nitrous_viewport[key] != nitrous_viewport_original[key]: setattr(viewport_setting, key, value) @@ -91,6 +98,8 @@ def viewport_preference_setting(general_viewport, rt.viewport.EnableSolidBackgroundColorMode(orig_vp_bkg) for key, value in vp_button_mgr_original.items(): setattr(rt.ViewportButtonMgr, key, value) + for key, value in nitrous_manager_original.items(): + setattr(nitrousGraphicMgr, key, value) for key, value in nitrous_viewport_original.items(): setattr(viewport_setting, key, value) @@ -258,6 +267,7 @@ def render_preview_animation( if int(get_max_version()) < 2024: with viewport_preference_setting( viewport_options["general_viewport"], + viewport_options["nitrous_manager"], viewport_options["nitrous_viewport"], viewport_options["vp_btn_mgr"] ): @@ -309,10 +319,12 @@ def viewport_options_for_preview_animation(): "dspBkg": True, "dspGrid": False } + viewport_options["nitrous_manager"] = { + "AntialiasingQuality": "None" + } viewport_options["nitrous_viewport"] = { "VisualStyleMode": "defaultshading", "ViewportPreset": "highquality", - "AntialiasingQuality": "None", "UseTextureEnabled": False } viewport_options["vp_btn_mgr"] = { diff --git a/openpype/hosts/max/plugins/publish/collect_review.py b/openpype/hosts/max/plugins/publish/collect_review.py index a579b3f4b0..e7e957e6f1 100644 --- a/openpype/hosts/max/plugins/publish/collect_review.py +++ b/openpype/hosts/max/plugins/publish/collect_review.py @@ -90,14 +90,17 @@ class CollectReview(pyblish.api.InstancePlugin, "dspBkg": attr_values.get("dspBkg"), "dspGrid": attr_values.get("dspGrid") } + nitrous_manager = { + "AntialiasingQuality": creator_attrs["antialiasingQuality"], + } nitrous_viewport = { "VisualStyleMode": creator_attrs["visualStyleMode"], "ViewportPreset": creator_attrs["viewportPreset"], - "AntialiasingQuality": creator_attrs["antialiasingQuality"], "UseTextureEnabled": creator_attrs["vpTexture"] } preview_data = { "general_viewport": general_viewport, + "nitrous_manager": nitrous_manager, "nitrous_viewport": nitrous_viewport, "vp_btn_mgr": {"EnableButtons": False} } From ae536f2409cf9b622b617150dbd9778b6c180e91 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 2 Nov 2023 16:15:03 +0100 Subject: [PATCH 249/690] traypublisher: folder path implementation --- openpype/hosts/traypublisher/api/editorial.py | 6 +++++- .../hosts/traypublisher/plugins/create/create_editorial.py | 4 +++- .../traypublisher/plugins/publish/collect_shot_instances.py | 1 - 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/traypublisher/api/editorial.py b/openpype/hosts/traypublisher/api/editorial.py index e8f76bd314..2f5e709ffc 100644 --- a/openpype/hosts/traypublisher/api/editorial.py +++ b/openpype/hosts/traypublisher/api/editorial.py @@ -319,8 +319,12 @@ class ShotMetadataSolver: tasks = self._generate_tasks_from_settings( project_doc) + # generate hierarchy path from parents + hierarchy_path = self._create_hierarchy_path(parents) + return shot_name, { - "hierarchy": self._create_hierarchy_path(parents), + "hierarchy": hierarchy_path, + "folderPath": f"{hierarchy_path}/{shot_name}", "parents": parents, "tasks": tasks } diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 23cf066362..5dc3893697 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -217,9 +217,10 @@ or updating already created. Publishing will create OTIO file. } # Create otio editorial instance if AYON_SERVER_ENABLED: - asset_name = instance_data["folderPath"] + asset_name = instance_data.pop("folderPath") else: asset_name = instance_data["asset"] + asset_doc = get_asset_by_name(self.project_name, asset_name) if pre_create_data["fps"] == "from_selection": @@ -682,6 +683,7 @@ or updating already created. Publishing will create OTIO file. # create creator attributes creator_attributes = { "asset_name": shot_name, + "Folder path": shot_metadata["folderPath"], "Parent hierarchy path": shot_metadata["hierarchy"], "workfile_start_frame": workfile_start_frame, "fps": fps, diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py index 78c1f14e4e..b08397caf7 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -120,7 +120,6 @@ class CollectShotInstance(pyblish.api.InstancePlugin): frame_dur = frame_end - frame_start return { - "asset": _cr_attrs["asset_name"], "fps": float(_cr_attrs["fps"]), "handleStart": _cr_attrs["handle_start"], "handleEnd": _cr_attrs["handle_end"], From 976ff308e97abed1efd6b87f09c477ad16c8f329 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 2 Nov 2023 16:18:51 +0100 Subject: [PATCH 250/690] Add Create workfile plugin --- .../blender/plugins/create/create_workfile.py | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 openpype/hosts/blender/plugins/create/create_workfile.py diff --git a/openpype/hosts/blender/plugins/create/create_workfile.py b/openpype/hosts/blender/plugins/create/create_workfile.py new file mode 100644 index 0000000000..d1529f75f6 --- /dev/null +++ b/openpype/hosts/blender/plugins/create/create_workfile.py @@ -0,0 +1,100 @@ +import bpy + +from openpype.pipeline import CreatedInstance, AutoCreator +from openpype.client import get_asset_by_name +from openpype.hosts.blender.api.plugin import BaseCreator +from openpype.hosts.blender.api.lib import imprint +from openpype.hosts.blender.api.pipeline import AVALON_PROPERTY + + +class CreateWorkfile(BaseCreator, AutoCreator): + """Workfile auto-creator.""" + identifier = "io.openpype.creators.blender.workfile" + label = "Workfile" + family = "workfile" + icon = "fa5.file" + + def create(self): + """Create workfile instances.""" + current_instance = next( + ( + instance for instance in self.create_context.instances + if instance.creator_identifier == self.identifier + ), + None, + ) + + project_name = self.project_name + asset_name = self.create_context.get_current_asset_name() + task_name = self.create_context.get_current_task_name() + host_name = self.create_context.host_name + + if not current_instance: + asset_doc = get_asset_by_name(project_name, asset_name) + subset_name = self.get_subset_name( + task_name, task_name, asset_doc, project_name, host_name + ) + data = { + "asset": asset_name, + "task": task_name, + "variant": task_name, + } + data.update( + self.get_dynamic_data( + task_name, + task_name, + asset_doc, + project_name, + host_name, + current_instance, + ) + ) + self.log.info("Auto-creating workfile instance...") + current_instance = CreatedInstance( + self.family, subset_name, data, self + ) + self._add_instance_to_context(current_instance) + elif ( + current_instance["asset"] != asset_name + or current_instance["task"] != task_name + ): + # Update instance context if it's different + asset_doc = get_asset_by_name(project_name, asset_name) + subset_name = self.get_subset_name( + task_name, task_name, asset_doc, project_name, host_name + ) + + current_instance.update( + { + "asset": asset_name, + "task": task_name, + "subset": subset_name, + } + ) + + def collect_instances(self): + """Collect workfile instances.""" + self.cache_subsets(self.collection_shared_data) + cached_subsets = self.collection_shared_data["blender_cached_subsets"] + for node in cached_subsets.get(self.identifier, []): + created_instance = CreatedInstance.from_existing( + self.read_instance_node(node), self + ) + self._add_instance_to_context(created_instance) + + def update_instances(self, update_list): + """Update workfile instances.""" + for created_inst, _changes in update_list: + data = created_inst.data_to_store() + node = data.get("instance_node") + if not node: + task_name = self.create_context.get_current_task_name() + + bpy.context.scene[AVALON_PROPERTY] = node = { + "name": f"workfile{task_name}" + } + + created_inst["instance_node"] = node + data = created_inst.data_to_store() + + imprint(node, data) From 6a619d023b4f4bac7d48883bd16081193950d950 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 Nov 2023 00:53:37 +0100 Subject: [PATCH 251/690] Remove on instance toggled callback which isn't relevant to the new publisher --- openpype/hosts/houdini/api/pipeline.py | 56 ------------------- .../publish/collect_instances_usd_layered.py | 4 -- 2 files changed, 60 deletions(-) diff --git a/openpype/hosts/houdini/api/pipeline.py b/openpype/hosts/houdini/api/pipeline.py index f8db45c56b..11135e20b2 100644 --- a/openpype/hosts/houdini/api/pipeline.py +++ b/openpype/hosts/houdini/api/pipeline.py @@ -3,7 +3,6 @@ import os import sys import logging -import contextlib import hou # noqa @@ -66,10 +65,6 @@ class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): register_event_callback("open", on_open) register_event_callback("new", on_new) - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) - self._has_been_setup = True # add houdini vendor packages hou_pythonpath = os.path.join(HOUDINI_HOST_DIR, "vendor") @@ -406,54 +401,3 @@ def _set_context_settings(): lib.reset_framerange() lib.update_houdini_vars_context() - - -def on_pyblish_instance_toggled(instance, new_value, old_value): - """Toggle saver tool passthrough states on instance toggles.""" - @contextlib.contextmanager - def main_take(no_update=True): - """Enter root take during context""" - original_take = hou.takes.currentTake() - original_update_mode = hou.updateModeSetting() - root = hou.takes.rootTake() - has_changed = False - try: - if original_take != root: - has_changed = True - if no_update: - hou.setUpdateMode(hou.updateMode.Manual) - hou.takes.setCurrentTake(root) - yield - finally: - if has_changed: - if no_update: - hou.setUpdateMode(original_update_mode) - hou.takes.setCurrentTake(original_take) - - if not instance.data.get("_allowToggleBypass", True): - return - - nodes = instance[:] - if not nodes: - return - - # Assume instance node is first node - instance_node = nodes[0] - - if not hasattr(instance_node, "isBypassed"): - # Likely not a node that can actually be bypassed - log.debug("Can't bypass node: %s", instance_node.path()) - return - - if instance_node.isBypassed() != (not old_value): - print("%s old bypass state didn't match old instance state, " - "updating anyway.." % instance_node.path()) - - try: - # Go into the main take, because when in another take changing - # the bypass state of a note cannot be done due to it being locked - # by default. - with main_take(no_update=True): - instance_node.bypass(not new_value) - except hou.PermissionError as exc: - log.warning("%s - %s", instance_node.path(), exc) diff --git a/openpype/hosts/houdini/plugins/publish/collect_instances_usd_layered.py b/openpype/hosts/houdini/plugins/publish/collect_instances_usd_layered.py index 0600730d00..d154cdc7c0 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_instances_usd_layered.py +++ b/openpype/hosts/houdini/plugins/publish/collect_instances_usd_layered.py @@ -122,10 +122,6 @@ class CollectInstancesUsdLayered(pyblish.api.ContextPlugin): instance.data.update(save_data) instance.data["usdLayer"] = layer - # Don't allow the Pyblish `instanceToggled` we have installed - # to set this node to bypass. - instance.data["_allowToggleBypass"] = False - instances.append(instance) # Store the collected ROP node dependencies From d94c19d0ba44a5d48b8964fe3fa6d98a29b3f0da Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 Nov 2023 00:59:42 +0100 Subject: [PATCH 252/690] Remove non-working LOPs USD output processors - These do not show up in recent Houdini versions - The recent output processor API is very different and processors should be registered differently - These are non-functional in current OpenPype code --- openpype/hosts/houdini/api/pipeline.py | 4 - .../vendor/husdoutputprocessors/__init__.py | 1 - .../avalon_uri_processor.py | 152 ------------------ .../stagingdir_processor.py | 90 ----------- 4 files changed, 247 deletions(-) delete mode 100644 openpype/hosts/houdini/vendor/husdoutputprocessors/__init__.py delete mode 100644 openpype/hosts/houdini/vendor/husdoutputprocessors/avalon_uri_processor.py delete mode 100644 openpype/hosts/houdini/vendor/husdoutputprocessors/stagingdir_processor.py diff --git a/openpype/hosts/houdini/api/pipeline.py b/openpype/hosts/houdini/api/pipeline.py index f8db45c56b..095004ea6f 100644 --- a/openpype/hosts/houdini/api/pipeline.py +++ b/openpype/hosts/houdini/api/pipeline.py @@ -71,10 +71,6 @@ class HoudiniHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): ) self._has_been_setup = True - # add houdini vendor packages - hou_pythonpath = os.path.join(HOUDINI_HOST_DIR, "vendor") - - sys.path.append(hou_pythonpath) # Set asset settings for the empty scene directly after launch of # Houdini so it initializes into the correct scene FPS, diff --git a/openpype/hosts/houdini/vendor/husdoutputprocessors/__init__.py b/openpype/hosts/houdini/vendor/husdoutputprocessors/__init__.py deleted file mode 100644 index 69e3be50da..0000000000 --- a/openpype/hosts/houdini/vendor/husdoutputprocessors/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__path__ = __import__('pkgutil').extend_path(__path__, __name__) diff --git a/openpype/hosts/houdini/vendor/husdoutputprocessors/avalon_uri_processor.py b/openpype/hosts/houdini/vendor/husdoutputprocessors/avalon_uri_processor.py deleted file mode 100644 index 310d057a11..0000000000 --- a/openpype/hosts/houdini/vendor/husdoutputprocessors/avalon_uri_processor.py +++ /dev/null @@ -1,152 +0,0 @@ -import os -import hou -import husdoutputprocessors.base as base - -import colorbleed.usdlib as usdlib - -from openpype.client import get_asset_by_name -from openpype.pipeline import Anatomy, get_current_project_name - - -class AvalonURIOutputProcessor(base.OutputProcessorBase): - """Process Avalon URIs into their full path equivalents. - - """ - - _parameters = None - _param_prefix = 'avalonurioutputprocessor_' - _parms = { - "use_publish_paths": _param_prefix + "use_publish_paths" - } - - def __init__(self): - """ There is only one object of each output processor class that is - ever created in a Houdini session. Therefore be very careful - about what data gets put in this object. - """ - self._use_publish_paths = False - self._cache = dict() - - def displayName(self): - return 'Avalon URI Output Processor' - - def parameters(self): - - if not self._parameters: - parameters = hou.ParmTemplateGroup() - use_publish_path = hou.ToggleParmTemplate( - name=self._parms["use_publish_paths"], - label='Resolve Reference paths to publish paths', - default_value=False, - help=("When enabled any paths for Layers, References or " - "Payloads are resolved to published master versions.\n" - "This is usually only used by the publishing pipeline, " - "but can be used for testing too.")) - parameters.append(use_publish_path) - self._parameters = parameters.asDialogScript() - - return self._parameters - - def beginSave(self, config_node, t): - parm = self._parms["use_publish_paths"] - self._use_publish_paths = config_node.parm(parm).evalAtTime(t) - self._cache.clear() - - def endSave(self): - self._use_publish_paths = None - self._cache.clear() - - def processAsset(self, - asset_path, - asset_path_for_save, - referencing_layer_path, - asset_is_layer, - for_save): - """ - Args: - asset_path (str): The incoming file path you want to alter or not. - asset_path_for_save (bool): Whether the current path is a - referenced path in the USD file. When True, return the path - you want inside USD file. - referencing_layer_path (str): ??? - asset_is_layer (bool): Whether this asset is a USD layer file. - If this is False, the asset is something else (for example, - a texture or volume file). - for_save (bool): Whether the asset path is for a file to be saved - out. If so, then return actual written filepath. - - Returns: - The refactored asset path. - - """ - - # Retrieve from cache if this query occurred before (optimization) - cache_key = (asset_path, asset_path_for_save, asset_is_layer, for_save) - if cache_key in self._cache: - return self._cache[cache_key] - - relative_template = "{asset}_{subset}.{ext}" - uri_data = usdlib.parse_avalon_uri(asset_path) - if uri_data: - - if for_save: - # Set save output path to a relative path so other - # processors can potentially manage it easily? - path = relative_template.format(**uri_data) - - print("Avalon URI Resolver: %s -> %s" % (asset_path, path)) - self._cache[cache_key] = path - return path - - if self._use_publish_paths: - # Resolve to an Avalon published asset for embedded paths - path = self._get_usd_master_path(**uri_data) - else: - path = relative_template.format(**uri_data) - - print("Avalon URI Resolver: %s -> %s" % (asset_path, path)) - self._cache[cache_key] = path - return path - - self._cache[cache_key] = asset_path - return asset_path - - def _get_usd_master_path(self, - asset, - subset, - ext): - """Get the filepath for a .usd file of a subset. - - This will return the path to an unversioned master file generated by - `usd_master_file.py`. - - """ - - PROJECT = get_current_project_name() - anatomy = Anatomy(PROJECT) - asset_doc = get_asset_by_name(PROJECT, asset) - if not asset_doc: - raise RuntimeError("Invalid asset name: '%s'" % asset) - - template_obj = anatomy.templates_obj["publish"]["path"] - path = template_obj.format_strict({ - "project": PROJECT, - "asset": asset_doc["name"], - "subset": subset, - "representation": ext, - "version": 0 # stub version zero - }) - - # Remove the version folder - subset_folder = os.path.dirname(os.path.dirname(path)) - master_folder = os.path.join(subset_folder, "master") - fname = "{0}.{1}".format(subset, ext) - - return os.path.join(master_folder, fname).replace("\\", "/") - - -output_processor = AvalonURIOutputProcessor() - - -def usdOutputProcessor(): - return output_processor diff --git a/openpype/hosts/houdini/vendor/husdoutputprocessors/stagingdir_processor.py b/openpype/hosts/houdini/vendor/husdoutputprocessors/stagingdir_processor.py deleted file mode 100644 index d8e36d5aa8..0000000000 --- a/openpype/hosts/houdini/vendor/husdoutputprocessors/stagingdir_processor.py +++ /dev/null @@ -1,90 +0,0 @@ -import hou -import husdoutputprocessors.base as base -import os - - -class StagingDirOutputProcessor(base.OutputProcessorBase): - """Output all USD Rop file nodes into the Staging Directory - - Ignore any folders and paths set in the Configured Layers - and USD Rop node, just take the filename and save into a - single directory. - - """ - theParameters = None - parameter_prefix = "stagingdiroutputprocessor_" - stagingdir_parm_name = parameter_prefix + "stagingDir" - - def __init__(self): - self.staging_dir = None - - def displayName(self): - return 'StagingDir Output Processor' - - def parameters(self): - if not self.theParameters: - parameters = hou.ParmTemplateGroup() - rootdirparm = hou.StringParmTemplate( - self.stagingdir_parm_name, - 'Staging Directory', 1, - string_type=hou.stringParmType.FileReference, - file_type=hou.fileType.Directory - ) - parameters.append(rootdirparm) - self.theParameters = parameters.asDialogScript() - return self.theParameters - - def beginSave(self, config_node, t): - - # Use the Root Directory parameter if it is set. - root_dir_parm = config_node.parm(self.stagingdir_parm_name) - if root_dir_parm: - self.staging_dir = root_dir_parm.evalAtTime(t) - - if not self.staging_dir: - out_file_parm = config_node.parm('lopoutput') - if out_file_parm: - self.staging_dir = out_file_parm.evalAtTime(t) - if self.staging_dir: - (self.staging_dir, filename) = os.path.split(self.staging_dir) - - def endSave(self): - self.staging_dir = None - - def processAsset(self, asset_path, - asset_path_for_save, - referencing_layer_path, - asset_is_layer, - for_save): - """ - Args: - asset_path (str): The incoming file path you want to alter or not. - asset_path_for_save (bool): Whether the current path is a - referenced path in the USD file. When True, return the path - you want inside USD file. - referencing_layer_path (str): ??? - asset_is_layer (bool): Whether this asset is a USD layer file. - If this is False, the asset is something else (for example, - a texture or volume file). - for_save (bool): Whether the asset path is for a file to be saved - out. If so, then return actual written filepath. - - Returns: - The refactored asset path. - - """ - - # Treat save paths as being relative to the output path. - if for_save and self.staging_dir: - # Whenever we're processing a Save Path make sure to - # resolve it to the Staging Directory - filename = os.path.basename(asset_path) - return os.path.join(self.staging_dir, filename) - - return asset_path - - -output_processor = StagingDirOutputProcessor() -def usdOutputProcessor(): - return output_processor - From 1e4005f4454efa4ea78f3bb14c0f96de400b8734 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 16:01:44 +0800 Subject: [PATCH 253/690] add AYON settings support and finalize the settings --- .../hosts/max/plugins/create/create_review.py | 2 +- server_addon/max/server/settings/main.py | 8 ++ .../max/server/settings/preview_animation.py | 92 +++++++++++++++++++ server_addon/max/server/version.py | 2 +- 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 server_addon/max/server/settings/preview_animation.py diff --git a/openpype/hosts/max/plugins/create/create_review.py b/openpype/hosts/max/plugins/create/create_review.py index ed0359ebd7..7aeea39b64 100644 --- a/openpype/hosts/max/plugins/create/create_review.py +++ b/openpype/hosts/max/plugins/create/create_review.py @@ -35,9 +35,9 @@ class CreateReview(plugin.MaxCreator): cls.visual_style = settings.get("visual_style", cls.visual_style) cls.viewport_preset = settings.get( "viewport_preset", cls.viewport_preset) - cls.vp_texture = settings.get("vp_texture", cls.vp_texture) cls.anti_aliasing = settings.get( "anti_aliasing", cls.anti_aliasing) + cls.vp_texture = settings.get("vp_texture", cls.vp_texture) def create(self, subset_name, instance_data, pre_create_data): # Transfer settings from pre create to instance diff --git a/server_addon/max/server/settings/main.py b/server_addon/max/server/settings/main.py index 7f4561cbb1..0280fcebb9 100644 --- a/server_addon/max/server/settings/main.py +++ b/server_addon/max/server/settings/main.py @@ -4,6 +4,9 @@ from .imageio import ImageIOSettings from .render_settings import ( RenderSettingsModel, DEFAULT_RENDER_SETTINGS ) +from .preview_animation import ( + PreviewAnimationModel, DEFAULT_PREVIEW_ANIMATION_SETTINGS +) from .publishers import ( PublishersModel, DEFAULT_PUBLISH_SETTINGS ) @@ -29,6 +32,10 @@ class MaxSettings(BaseSettingsModel): default_factory=RenderSettingsModel, title="Render Settings" ) + PreviewAnimation: PreviewAnimationModel = Field( + default_factory=PreviewAnimationModel, + title="Preview Animation" + ) PointCloud: PointCloudSettings = Field( default_factory=PointCloudSettings, title="Point Cloud" @@ -40,6 +47,7 @@ class MaxSettings(BaseSettingsModel): DEFAULT_VALUES = { "RenderSettings": DEFAULT_RENDER_SETTINGS, + "PreviewAnimation": DEFAULT_PREVIEW_ANIMATION_SETTINGS, "PointCloud": { "attribute": [ {"name": "Age", "value": "age"}, diff --git a/server_addon/max/server/settings/preview_animation.py b/server_addon/max/server/settings/preview_animation.py new file mode 100644 index 0000000000..2496e8e548 --- /dev/null +++ b/server_addon/max/server/settings/preview_animation.py @@ -0,0 +1,92 @@ +from pydantic import Field + +from ayon_server.settings import BaseSettingsModel + + +def image_format_enum(): + """Return enumerator for image output formats.""" + return [ + {"label": "exr", "value": "exr"}, + {"label": "jpg", "value": "jpg"}, + {"label": "png", "value": "png"}, + {"label": "tga", "value": "tga"} + ] + + +def visual_style_enum(): + """Return enumerator for viewport visual style.""" + return [ + {"label": "Realistic", "value": "Realistic"}, + {"label": "Shaded", "value": "Shaded"}, + {"label": "Facets", "value": "Facets"}, + {"label": "ConsistentColors", + "value": "ConsistentColors"}, + {"label": "Wireframe", "value": "Wireframe"}, + {"label": "BoundingBox", "value": "BoundingBox"}, + {"label": "Ink", "value": "Ink"}, + {"label": "ColorInk", "value": "ColorInk"}, + {"label": "Acrylic", "value": "Acrylic"}, + {"label": "Tech", "value": "Tech"}, + {"label": "Graphite", "value": "Graphite"}, + {"label": "ColorPencil", "value": "ColorPencil"}, + {"label": "Pastel", "value": "Pastel"}, + {"label": "Clay", "value": "Clay"}, + {"label": "ModelAssist", "value": "ModelAssist"} + ] + +def visual_preset_enum(): + """Return enumerator for viewport visual preset.""" + return [ + {"label": "Quality", "value": "Quality"}, + {"label": "Standard", "value": "Standard"}, + {"label": "Performance", "value": "Performance"}, + {"label": "DXMode", "value": "DXMode"}, + {"label": "Customize", "value": "Customize"}, + ] + + +def anti_aliasing_enum(): + """Return enumerator for viewport anti-aliasing.""" + return [ + {"label": "None", "value": "None"}, + {"label": "2X", "value": "2X"}, + {"label": "4X", "value": "4X"}, + {"label": "8X", "value": "8X"} + ] + + +class PreviewAnimationModel(BaseSettingsModel): + review_width: int = Field(1920, title="Review Width") + review_height: int = Field(1080, title="Review Height") + percentSize: float = Field(100.0, title="Percent of Output") + keep_images: bool = Field(False, title="Keep Image Sequences") + image_format: str = Field( + enum_resolver=image_format_enum, + title="Image Format Options" + ) + visual_style: str = Field( + enum_resolver=visual_style_enum, + title="Preference" + ) + viewport_preset: str = Field( + enum_resolver=visual_preset_enum, + title="Pre-View Preset" + ) + anti_aliasing: str = Field( + enum_resolver=anti_aliasing_enum, + title="Anti-aliasing Quality" + ) + vp_texture: bool = Field(True, title="Viewport Texture") + + +DEFAULT_PREVIEW_ANIMATION_SETTINGS = { + "review_width": 1920, + "review_height": 1080, + "percentSize": 100.0, + "keep_images": False, + "image_format": "png", + "visual_style": "Realistic", + "viewport_preset": "Quality", + "anti_aliasing": "None", + "vp_texture": True +} diff --git a/server_addon/max/server/version.py b/server_addon/max/server/version.py index 3dc1f76bc6..485f44ac21 100644 --- a/server_addon/max/server/version.py +++ b/server_addon/max/server/version.py @@ -1 +1 @@ -__version__ = "0.1.0" +__version__ = "0.1.1" From 2728379bbc0810155447cae35c01c65341ec12bd Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 16:04:39 +0800 Subject: [PATCH 254/690] hound --- server_addon/max/server/settings/preview_animation.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server_addon/max/server/settings/preview_animation.py b/server_addon/max/server/settings/preview_animation.py index 2496e8e548..759ce78291 100644 --- a/server_addon/max/server/settings/preview_animation.py +++ b/server_addon/max/server/settings/preview_animation.py @@ -34,6 +34,7 @@ def visual_style_enum(): {"label": "ModelAssist", "value": "ModelAssist"} ] + def visual_preset_enum(): """Return enumerator for viewport visual preset.""" return [ From 8fb7266ff8f0ea9c3b3f387ca120280093993294 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 11:18:09 +0200 Subject: [PATCH 255/690] Add CollectAssetHandles and modify associated files --- openpype/hosts/houdini/api/lib.py | 20 +-- .../plugins/publish/collect_arnold_rop.py | 2 +- .../plugins/publish/collect_asset_handles.py | 125 ++++++++++++++++++ .../houdini/plugins/publish/collect_frames.py | 10 +- .../plugins/publish/collect_karma_rop.py | 2 +- .../plugins/publish/collect_mantra_rop.py | 2 +- .../plugins/publish/collect_redshift_rop.py | 2 +- .../publish/collect_rop_frame_range.py | 79 +---------- .../plugins/publish/collect_vray_rop.py | 2 +- .../plugins/publish/validate_frame_range.py | 2 +- .../defaults/project_settings/houdini.json | 2 +- .../schemas/schema_houdini_publish.json | 4 +- .../houdini/server/settings/publish.py | 2 +- 13 files changed, 151 insertions(+), 103 deletions(-) create mode 100644 openpype/hosts/houdini/plugins/publish/collect_asset_handles.py diff --git a/openpype/hosts/houdini/api/lib.py b/openpype/hosts/houdini/api/lib.py index ac375c56d6..c6722fb1bb 100644 --- a/openpype/hosts/houdini/api/lib.py +++ b/openpype/hosts/houdini/api/lib.py @@ -569,9 +569,9 @@ def get_template_from_value(key, value): return parm -def get_frame_data(node, handle_start=0, handle_end=0, log=None): - """Get the frame data: start frame, end frame, steps, - start frame with start handle and end frame with end handle. +def get_frame_data(node, log=None): + """Get the frame data: `frameStartHandle`, `frameEndHandle` + and `byFrameStep`. This function uses Houdini node's `trange`, `t1, `t2` and `t3` parameters as the source of truth for the full inclusive frame @@ -579,20 +579,17 @@ def get_frame_data(node, handle_start=0, handle_end=0, log=None): range including the handles. The non-inclusive frame start and frame end without handles - are computed by subtracting the handles from the inclusive + can be computed by subtracting the handles from the inclusive frame range. Args: node (hou.Node): ROP node to retrieve frame range from, the frame range is assumed to be the frame range *including* the start and end handles. - handle_start (int): Start handles. - handle_end (int): End handles. - log (logging.Logger): Logger to log to. Returns: - dict: frame data for start, end, steps, - start with handle and end with handle + dict: frame data for `frameStartHandle`, `frameEndHandle` + and `byFrameStep`. """ @@ -623,11 +620,6 @@ def get_frame_data(node, handle_start=0, handle_end=0, log=None): data["frameEndHandle"] = int(node.evalParm("f2")) data["byFrameStep"] = node.evalParm("f3") - data["handleStart"] = handle_start - data["handleEnd"] = handle_end - data["frameStart"] = data["frameStartHandle"] + data["handleStart"] - data["frameEnd"] = data["frameEndHandle"] - data["handleEnd"] - return data diff --git a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py index 420a8324fe..d95f763826 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_arnold_rop.py @@ -22,7 +22,7 @@ class CollectArnoldROPRenderProducts(pyblish.api.InstancePlugin): label = "Arnold ROP Render Products" # This specific order value is used so that # this plugin runs after CollectFrames - order = pyblish.api.CollectorOrder + 0.49999 + order = pyblish.api.CollectorOrder + 0.11 hosts = ["houdini"] families = ["arnold_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py new file mode 100644 index 0000000000..5c11948608 --- /dev/null +++ b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- +"""Collector plugin for frames data on ROP instances.""" +import hou # noqa +import pyblish.api +from openpype.lib import BoolDef +from openpype.pipeline import OpenPypePyblishPluginMixin + + +class CollectAssetHandles(pyblish.api.InstancePlugin, + OpenPypePyblishPluginMixin): + """Apply asset handles. + + If instance does not have: + - frameStart + - frameEnd + - handleStart + - handleEnd + But it does have: + - frameStartHandle + - frameEndHandle + + Then we will retrieve the asset's handles to compute + the exclusive frame range and actual handle ranges. + """ + + hosts = ["houdini"] + + # This specific order value is used so that + # this plugin runs after CollectAnatomyInstanceData + order = pyblish.api.CollectorOrder + 0.499 + + label = "Collect Asset Handles" + use_asset_handles = True + + + def process(self, instance): + # Only process instances without already existing handles data + # but that do have frameStartHandle and frameEndHandle defined + # like the data collected from CollectRopFrameRange + if "frameStartHandle" not in instance.data: + return + if "frameEndHandle" not in instance.data: + return + + has_existing_data = { + "handleStart", + "handleEnd", + "frameStart", + "frameEnd" + }.issubset(instance.data) + if has_existing_data: + return + + attr_values = self.get_attr_values_from_data(instance.data) + if attr_values.get("use_handles", self.use_asset_handles): + asset_data = instance.data["assetEntity"]["data"] + handle_start = asset_data.get("handleStart", 0) + handle_end = asset_data.get("handleEnd", 0) + else: + handle_start = 0 + handle_end = 0 + + frame_start = instance.data["frameStartHandle"] + handle_start + frame_end = instance.data["frameEndHandle"] - handle_end + + instance.data.update({ + "handleStart": handle_start, + "handleEnd": handle_end, + "frameStart": frame_start, + "frameEnd": frame_end + }) + + # Log debug message about the collected frame range + if attr_values.get("use_handles", self.use_asset_handles): + self.log.debug( + "Full Frame range with Handles " + "[{frame_start_handle} - {frame_end_handle}]" + .format( + frame_start_handle=instance.data["frameStartHandle"], + frame_end_handle=instance.data["frameEndHandle"] + ) + ) + else: + self.log.debug( + "Use handles is deactivated for this instance, " + "start and end handles are set to 0." + ) + + # Log collected frame range to the user + message = "Frame range [{frame_start} - {frame_end}]".format( + frame_start=frame_start, + frame_end=frame_end + ) + if handle_start or handle_end: + message += " with handles [{handle_start}]-[{handle_end}]".format( + handle_start=handle_start, + handle_end=handle_end + ) + self.log.info(message) + + if instance.data.get("byFrameStep", 1.0) != 1.0: + self.log.info( + "Frame steps {}".format(instance.data["byFrameStep"])) + + # Add frame range to label if the instance has a frame range. + label = instance.data.get("label", instance.data["name"]) + instance.data["label"] = ( + "{label} [{frame_start} - {frame_end}]" + .format( + label=label, + frame_start=frame_start, + frame_end=frame_end + ) + ) + + @classmethod + def get_attribute_defs(cls): + return [ + BoolDef("use_handles", + tooltip="Disable this if you want the publisher to" + " ignore start and end handles specified in the" + " asset data for this publish instance", + default=cls.use_asset_handles, + label="Use asset handles") + ] diff --git a/openpype/hosts/houdini/plugins/publish/collect_frames.py b/openpype/hosts/houdini/plugins/publish/collect_frames.py index 79cfcc6139..f6f538f5a5 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_frames.py +++ b/openpype/hosts/houdini/plugins/publish/collect_frames.py @@ -13,7 +13,7 @@ class CollectFrames(pyblish.api.InstancePlugin): # This specific order value is used so that # this plugin runs after CollectRopFrameRange - order = pyblish.api.CollectorOrder + 0.4999 + order = pyblish.api.CollectorOrder + 0.1 label = "Collect Frames" families = ["vdbcache", "imagesequence", "ass", "redshiftproxy", "review", "bgeo"] @@ -22,8 +22,8 @@ class CollectFrames(pyblish.api.InstancePlugin): ropnode = hou.node(instance.data["instance_node"]) - start_frame = instance.data.get("frameStart", None) - end_frame = instance.data.get("frameEnd", None) + start_frame = instance.data.get("frameStartHandle", None) + end_frame = instance.data.get("frameEndHandle", None) output_parm = lib.get_output_parameter(ropnode) if start_frame is not None: @@ -53,7 +53,7 @@ class CollectFrames(pyblish.api.InstancePlugin): # Check if frames are bigger than 1 (file collection) # override the result if end_frame - start_frame > 0: - result = self.create_file_list( + result = self.create_file_list(self, match, int(start_frame), int(end_frame) ) @@ -62,7 +62,7 @@ class CollectFrames(pyblish.api.InstancePlugin): instance.data.update({"frames": result}) @staticmethod - def create_file_list(match, start_frame, end_frame): + def create_file_list(self,match, start_frame, end_frame): """Collect files based on frame range and `regex.match` Args: diff --git a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py index a477529df9..dac350a6ef 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_karma_rop.py @@ -26,7 +26,7 @@ class CollectKarmaROPRenderProducts(pyblish.api.InstancePlugin): label = "Karma ROP Render Products" # This specific order value is used so that # this plugin runs after CollectFrames - order = pyblish.api.CollectorOrder + 0.49999 + order = pyblish.api.CollectorOrder + 0.11 hosts = ["houdini"] families = ["karma_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py index 9f0ae8d33c..a3e7927807 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_mantra_rop.py @@ -26,7 +26,7 @@ class CollectMantraROPRenderProducts(pyblish.api.InstancePlugin): label = "Mantra ROP Render Products" # This specific order value is used so that # this plugin runs after CollectFrames - order = pyblish.api.CollectorOrder + 0.49999 + order = pyblish.api.CollectorOrder + 0.11 hosts = ["houdini"] families = ["mantra_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py index 0bd7b41641..0acddab011 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_redshift_rop.py @@ -26,7 +26,7 @@ class CollectRedshiftROPRenderProducts(pyblish.api.InstancePlugin): label = "Redshift ROP Render Products" # This specific order value is used so that # this plugin runs after CollectFrames - order = pyblish.api.CollectorOrder + 0.49999 + order = pyblish.api.CollectorOrder + 0.11 hosts = ["houdini"] families = ["redshift_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py b/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py index 186244fedd..1e6bc3b16e 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/collect_rop_frame_range.py @@ -2,22 +2,15 @@ """Collector plugin for frames data on ROP instances.""" import hou # noqa import pyblish.api -from openpype.lib import BoolDef from openpype.hosts.houdini.api import lib -from openpype.pipeline import OpenPypePyblishPluginMixin -class CollectRopFrameRange(pyblish.api.InstancePlugin, - OpenPypePyblishPluginMixin): - +class CollectRopFrameRange(pyblish.api.InstancePlugin): """Collect all frames which would be saved from the ROP nodes""" hosts = ["houdini"] - # This specific order value is used so that - # this plugin runs after CollectAnatomyInstanceData - order = pyblish.api.CollectorOrder + 0.499 + order = pyblish.api.CollectorOrder label = "Collect RopNode Frame Range" - use_asset_handles = True def process(self, instance): @@ -30,78 +23,16 @@ class CollectRopFrameRange(pyblish.api.InstancePlugin, return ropnode = hou.node(node_path) - - attr_values = self.get_attr_values_from_data(instance.data) - - if attr_values.get("use_handles", self.use_asset_handles): - asset_data = instance.data["assetEntity"]["data"] - handle_start = asset_data.get("handleStart", 0) - handle_end = asset_data.get("handleEnd", 0) - else: - handle_start = 0 - handle_end = 0 - frame_data = lib.get_frame_data( - ropnode, handle_start, handle_end, self.log + ropnode, self.log ) if not frame_data: return # Log debug message about the collected frame range - frame_start = frame_data["frameStart"] - frame_end = frame_data["frameEnd"] - - if attr_values.get("use_handles", self.use_asset_handles): - self.log.debug( - "Full Frame range with Handles " - "[{frame_start_handle} - {frame_end_handle}]" - .format( - frame_start_handle=frame_data["frameStartHandle"], - frame_end_handle=frame_data["frameEndHandle"] - ) - ) - else: - self.log.debug( - "Use handles is deactivated for this instance, " - "start and end handles are set to 0." - ) - - # Log collected frame range to the user - message = "Frame range [{frame_start} - {frame_end}]".format( - frame_start=frame_start, - frame_end=frame_end + self.log.debug( + "Collected frame_data: {}".format(frame_data) ) - if handle_start or handle_end: - message += " with handles [{handle_start}]-[{handle_end}]".format( - handle_start=handle_start, - handle_end=handle_end - ) - self.log.info(message) - - if frame_data.get("byFrameStep", 1.0) != 1.0: - self.log.info("Frame steps {}".format(frame_data["byFrameStep"])) instance.data.update(frame_data) - - # Add frame range to label if the instance has a frame range. - label = instance.data.get("label", instance.data["name"]) - instance.data["label"] = ( - "{label} [{frame_start} - {frame_end}]" - .format( - label=label, - frame_start=frame_start, - frame_end=frame_end - ) - ) - - @classmethod - def get_attribute_defs(cls): - return [ - BoolDef("use_handles", - tooltip="Disable this if you want the publisher to" - " ignore start and end handles specified in the" - " asset data for this publish instance", - default=cls.use_asset_handles, - label="Use asset handles") - ] diff --git a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py index 519c12aede..64de2079cd 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py +++ b/openpype/hosts/houdini/plugins/publish/collect_vray_rop.py @@ -26,7 +26,7 @@ class CollectVrayROPRenderProducts(pyblish.api.InstancePlugin): label = "VRay ROP Render Products" # This specific order value is used so that # this plugin runs after CollectFrames - order = pyblish.api.CollectorOrder + 0.49999 + order = pyblish.api.CollectorOrder + 0.11 hosts = ["houdini"] families = ["vray_rop"] diff --git a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py index 6a66f3de9f..b49cfae901 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_frame_range.py +++ b/openpype/hosts/houdini/plugins/publish/validate_frame_range.py @@ -89,7 +89,7 @@ class ValidateFrameRange(pyblish.api.InstancePlugin): .format(instance)) return - created_instance.publish_attributes["CollectRopFrameRange"]["use_handles"] = False # noqa + created_instance.publish_attributes["CollectAssetHandles"]["use_handles"] = False # noqa create_context.save_changes() cls.log.debug("use asset handles is turned off for '{}'" diff --git a/openpype/settings/defaults/project_settings/houdini.json b/openpype/settings/defaults/project_settings/houdini.json index 87983620ec..0dd8443e44 100644 --- a/openpype/settings/defaults/project_settings/houdini.json +++ b/openpype/settings/defaults/project_settings/houdini.json @@ -137,7 +137,7 @@ } }, "publish": { - "CollectRopFrameRange": { + "CollectAssetHandles": { "use_asset_handles": true }, "ValidateContainers": { diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json index 0de9f21c9f..324cfd8d58 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_houdini_publish.json @@ -11,8 +11,8 @@ { "type": "dict", "collapsible": true, - "key": "CollectRopFrameRange", - "label": "Collect Rop Frame Range", + "key": "CollectAssetHandles", + "label": "Collect Asset Handles", "children": [ { "type": "label", diff --git a/server_addon/houdini/server/settings/publish.py b/server_addon/houdini/server/settings/publish.py index 6615e34ca5..342bf957c1 100644 --- a/server_addon/houdini/server/settings/publish.py +++ b/server_addon/houdini/server/settings/publish.py @@ -3,7 +3,7 @@ from ayon_server.settings import BaseSettingsModel # Publish Plugins -class CollectRopFrameRangeModel(BaseSettingsModel): +class CollectAssetHandlesModel(BaseSettingsModel): """Collect Frame Range Disable this if you want the publisher to ignore start and end handles specified in the From 38d71e7c73ef5716b2964c867fe81d1b26656aed Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 11:19:08 +0200 Subject: [PATCH 256/690] Bump Houdini addon version --- server_addon/houdini/server/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/houdini/server/version.py b/server_addon/houdini/server/version.py index 6cd38b7465..c49a95c357 100644 --- a/server_addon/houdini/server/version.py +++ b/server_addon/houdini/server/version.py @@ -1 +1 @@ -__version__ = "0.2.7" +__version__ = "0.2.8" From 3d74095521a45337d764a70eaf794fa7f98dc226 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 11:21:10 +0200 Subject: [PATCH 257/690] Resolve Hound and Remove debug code --- .../hosts/houdini/plugins/publish/collect_asset_handles.py | 1 - openpype/hosts/houdini/plugins/publish/collect_frames.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py index 5c11948608..6474d64765 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py +++ b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py @@ -32,7 +32,6 @@ class CollectAssetHandles(pyblish.api.InstancePlugin, label = "Collect Asset Handles" use_asset_handles = True - def process(self, instance): # Only process instances without already existing handles data # but that do have frameStartHandle and frameEndHandle defined diff --git a/openpype/hosts/houdini/plugins/publish/collect_frames.py b/openpype/hosts/houdini/plugins/publish/collect_frames.py index f6f538f5a5..cdef642174 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_frames.py +++ b/openpype/hosts/houdini/plugins/publish/collect_frames.py @@ -53,7 +53,7 @@ class CollectFrames(pyblish.api.InstancePlugin): # Check if frames are bigger than 1 (file collection) # override the result if end_frame - start_frame > 0: - result = self.create_file_list(self, + result = self.create_file_list( match, int(start_frame), int(end_frame) ) @@ -62,7 +62,7 @@ class CollectFrames(pyblish.api.InstancePlugin): instance.data.update({"frames": result}) @staticmethod - def create_file_list(self,match, start_frame, end_frame): + def create_file_list(match, start_frame, end_frame): """Collect files based on frame range and `regex.match` Args: From 382ad931c670adbdd52fdf8996bb1d4115d37744 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 3 Nov 2023 14:13:08 +0100 Subject: [PATCH 258/690] resolve: frame duration and handles operation --- openpype/hosts/resolve/api/plugin.py | 53 ++++++++++++++++------------ 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 5c4a92df89..0f6f4d14bd 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -405,26 +405,41 @@ class ClipLoader: self.active_bin ) _clip_property = media_pool_item.GetClipProperty + source_in = int(_clip_property("Start")) + source_out = int(_clip_property("End")) + source_duration = int(_clip_property("Frames")) - # get handles + # get version data frame data from db + frame_start = self.data["versionData"].get("frameStart") + frame_end = self.data["versionData"].get("frameEnd") handle_start = self.data["versionData"].get("handleStart") handle_end = self.data["versionData"].get("handleEnd") - if handle_start is None: - handle_start = int(self.data["assetData"]["handleStart"]) - if handle_end is None: - handle_end = int(self.data["assetData"]["handleEnd"]) - # check frame duration from versionData or assetData - frame_start = self.data["versionData"].get("frameStart") - if frame_start is None: - frame_start = self.data["assetData"]["frameStart"] + # check if source duration is shorter than db frame duration + source_with_handles = True + # make sure all frame data is available + if ( + frame_start is None or + frame_end is None or + handle_start is None or + handle_end is None + ): + # if not then rather assume that source has no handles + source_with_handles = False + else: + # calculate db frame duration + db_frame_duration = ( + # include handles + int(handle_start) + int(handle_end) + + # include frame duration + (int(frame_end) - int(frame_start) + 1) + ) - # check frame duration from versionData or assetData - frame_end = self.data["versionData"].get("frameEnd") - if frame_end is None: - frame_end = self.data["assetData"]["frameEnd"] - - db_frame_duration = int(frame_end) - int(frame_start) + 1 + # compare source duration with db frame duration + # and assume that source has no handles if source duration + # is shorter than db frame duration + if source_duration < db_frame_duration: + source_with_handles = False # get timeline in timeline_start = self.active_timeline.GetStartFrame() @@ -436,14 +451,6 @@ class ClipLoader: timeline_in = int( timeline_start + self.data["assetData"]["clipIn"]) - source_in = int(_clip_property("Start")) - source_out = int(_clip_property("End")) - source_duration = int(_clip_property("Frames")) - - # check if source duration is shorter than db frame duration - source_with_handles = True - if source_duration < db_frame_duration: - source_with_handles = False # only exclude handles if source has no handles or # if user wants to load without handles From 69bf065851a7b82db1779a72022abf941d5c56bd Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 15:41:37 +0200 Subject: [PATCH 259/690] BigRoy's Comment - Update label --- .../hosts/houdini/plugins/publish/collect_asset_handles.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py index 6474d64765..67a281639d 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py +++ b/openpype/hosts/houdini/plugins/publish/collect_asset_handles.py @@ -104,11 +104,11 @@ class CollectAssetHandles(pyblish.api.InstancePlugin, # Add frame range to label if the instance has a frame range. label = instance.data.get("label", instance.data["name"]) instance.data["label"] = ( - "{label} [{frame_start} - {frame_end}]" + "{label} [{frame_start_handle} - {frame_end_handle}]" .format( label=label, - frame_start=frame_start, - frame_end=frame_end + frame_start_handle=instance.data["frameStartHandle"], + frame_end_handle=instance.data["frameEndHandle"] ) ) From 2d3ae5a0d346a95586abde0a11632291e8c83467 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 22:02:13 +0800 Subject: [PATCH 260/690] supports checking the required plugins with families type * --- .../plugins/publish/validate_loaded_plugin.py | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index dc82c7ed65..d6f849a57e 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -16,7 +16,11 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, InstancePlugin): """Validates if the specific plugin is loaded in 3ds max. Studio Admin(s) can add the plugins they want to check in validation - via studio defined project settings""" + via studio defined project settings + If families = ["*"], all the required plugins would be validated + If families + + """ order = ValidatorOrder hosts = ["max"] @@ -48,15 +52,17 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, } for families, plugin in required_plugins.items(): - families_list = families.split(",") - excluded_families = [family for family in families_list - if instance.data["family"] != family - and family != "_"] - if excluded_families: - self.log.debug("The {} instance is not part of {}.".format( - instance.data["family"], excluded_families - )) - return + # Out of for loop build the instance family lookup + instance_families = {instance.data["family"]} + instance_families.update(instance.data.get("families", [])) + self.log.debug(f"{instance_families}") + # In the for loop check whether any family matches + match_families = {fam.strip() for fam in families.split(",") if fam.strip()} + self.log.debug(f"match_families: {match_families}") + has_match = "*" in match_families or match_families.intersection( + instance_families) or families == "_" + if not has_match: + continue if not plugin: return @@ -66,7 +72,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if plugin_index is None: invalid.append( - f"Plugin {plugin} not exists in 3dsMax Plugin List." + f"Plugin {plugin} does not exist in 3dsMax Plugin List." ) continue @@ -82,12 +88,12 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, "- {}".format(invalid) for invalid in invalid_plugins ) report = ( - "Required plugins fails to load.\n\n" + "Required plugins are not loaded.\n\n" f"{bullet_point_invalid_statement}\n\n" "You can use repair action to load the plugin." ) raise PublishValidationError( - report, title="Required Plugins unloaded") + report, title="Missing Required Plugins") @classmethod def repair(cls, instance): From e61d03556a1a7d915a6cd421c6a0ec45d40c8481 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 22:03:00 +0800 Subject: [PATCH 261/690] hound --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index d6f849a57e..e58685cc4d 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -57,7 +57,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, instance_families.update(instance.data.get("families", [])) self.log.debug(f"{instance_families}") # In the for loop check whether any family matches - match_families = {fam.strip() for fam in families.split(",") if fam.strip()} + match_families = {fam.strip() for fam in + families.split(",") if fam.strip()} self.log.debug(f"match_families: {match_families}") has_match = "*" in match_families or match_families.intersection( instance_families) or families == "_" From 6e9c3b227815e7e8cbd158a8110549b2f095443e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 3 Nov 2023 15:06:59 +0100 Subject: [PATCH 262/690] deadline: settings are not blocking extension input --- server_addon/deadline/server/settings/publish_plugins.py | 2 +- server_addon/deadline/server/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/deadline/server/settings/publish_plugins.py b/server_addon/deadline/server/settings/publish_plugins.py index 8d48695a9c..54b7ff57c1 100644 --- a/server_addon/deadline/server/settings/publish_plugins.py +++ b/server_addon/deadline/server/settings/publish_plugins.py @@ -267,7 +267,7 @@ class ProcessSubmittedJobOnFarmModel(BaseSettingsModel): title="Reviewable products filter", ) - @validator("aov_filter", "skip_integration_repre_list") + @validator("aov_filter") def validate_unique_names(cls, value): ensure_unique_names(value) return value diff --git a/server_addon/deadline/server/version.py b/server_addon/deadline/server/version.py index b3f4756216..ae7362549b 100644 --- a/server_addon/deadline/server/version.py +++ b/server_addon/deadline/server/version.py @@ -1 +1 @@ -__version__ = "0.1.2" +__version__ = "0.1.3" From 44a0b0e6284a73180dccdef244fe92c5761caaf0 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 22:42:44 +0800 Subject: [PATCH 263/690] make sure the aspect ratio correct --- openpype/hosts/max/api/preview_animation.py | 51 +++++++++++---------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index 0754fa61c4..d6becd499e 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -166,13 +166,16 @@ def _render_preview_animation_max_2024( def _render_preview_animation_max_pre_2024( - filepath, startFrame, endFrame, percentSize, ext): + filepath, startFrame, endFrame, + width, height, percentSize, ext): """Render viewport animation by creating bitmaps ***For 3dsMax Version <2024 Args: filepath (str): filepath without frame numbers and extension startFrame (int): start frame endFrame (int): end frame + width (int): render resolution width + height (int): render resolution height percentSize (float): render resolution multiplier by 100 e.g. 100.0 is 1x, 50.0 is 0.5x, 150.0 is 1.5x ext (str): image extension @@ -182,9 +185,8 @@ def _render_preview_animation_max_pre_2024( # get the screenshot percent = percentSize / 100.0 - res_width = int(round(rt.renderWidth * percent)) - res_height = int(round(rt.renderHeight * percent)) - viewportRatio = float(res_width / res_height) + res_width = int(round(width * percent)) + res_height = int(round(height * percent)) frame_template = "{}.{{:04}}.{}".format(filepath, ext) frame_template.replace("\\", "/") files = [] @@ -196,10 +198,11 @@ def _render_preview_animation_max_pre_2024( res_width, res_height, filename=filepath ) dib = rt.gw.getViewportDib() - dib_width = float(dib.width) - dib_height = float(dib.height) + dib_width = rt.renderWidth + dib_height = rt.renderHeight # aspect ratio - renderRatio = rt.getRendImageAspect() + viewportRatio = dib_width /dib_height + renderRatio = float(res_width / res_height) if viewportRatio <= renderRatio: heightCrop = (dib_width / renderRatio) topEdge = int((dib_height - heightCrop) / 2.0) @@ -263,22 +266,24 @@ def render_preview_animation( viewport_options = viewport_options_for_preview_animation() with play_preview_when_done(False): with viewport_layout_and_camera(camera): - with render_resolution(width, height): - if int(get_max_version()) < 2024: - with viewport_preference_setting( - viewport_options["general_viewport"], - viewport_options["nitrous_manager"], - viewport_options["nitrous_viewport"], - viewport_options["vp_btn_mgr"] - ): - return _render_preview_animation_max_pre_2024( - filepath, - start_frame, - end_frame, - percentSize, - ext - ) - else: + if int(get_max_version()) < 2024: + with viewport_preference_setting( + viewport_options["general_viewport"], + viewport_options["nitrous_manager"], + viewport_options["nitrous_viewport"], + viewport_options["vp_btn_mgr"] + ): + return _render_preview_animation_max_pre_2024( + filepath, + start_frame, + end_frame, + width, + height, + percentSize, + ext + ) + else: + with render_resolution(width, height): return _render_preview_animation_max_2024( filepath, start_frame, From 1132d1c9f3eb7d512b548988e717b16563dde119 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 15:43:33 +0100 Subject: [PATCH 264/690] avoid double slashes in context title path --- openpype/host/host.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/host/host.py b/openpype/host/host.py index 630fb873a8..afe06d1f55 100644 --- a/openpype/host/host.py +++ b/openpype/host/host.py @@ -170,7 +170,7 @@ class HostBase(object): if project_name: items.append(project_name) if asset_name: - items.append(asset_name) + items.append(asset_name.lstrip("/")) if task_name: items.append(task_name) if items: From 01c965eb9cb701eee833cb735dcec0daf4f6f61a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Fri, 3 Nov 2023 22:43:34 +0800 Subject: [PATCH 265/690] hound --- openpype/hosts/max/api/preview_animation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index d6becd499e..bd0fee3658 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -201,7 +201,7 @@ def _render_preview_animation_max_pre_2024( dib_width = rt.renderWidth dib_height = rt.renderHeight # aspect ratio - viewportRatio = dib_width /dib_height + viewportRatio = dib_width / dib_height renderRatio = float(res_width / res_height) if viewportRatio <= renderRatio: heightCrop = (dib_width / renderRatio) From e5e278201b359772e51ae7dafae188753de06a3e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Fri, 3 Nov 2023 16:18:04 +0100 Subject: [PATCH 266/690] better code explanation --- openpype/hosts/resolve/api/plugin.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 0f6f4d14bd..09c5a69d73 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -415,6 +415,19 @@ class ClipLoader: handle_start = self.data["versionData"].get("handleStart") handle_end = self.data["versionData"].get("handleEnd") + """ + There are cases where representation could be published without + handles if the "Extract review output tags" is set to "no_handles". + This would result in a shorter source duration compared to the + db frame-range. In such cases, we need to assume that the source + has no handles. + + To address this, we should compare the duration of the source + frame with the db frame-range. The duration of the db frame-range + should be calculated from the version data. If, for any reason, + the frame data is missing in the version data, we should again + assume that the source has no handles. + """ # check if source duration is shorter than db frame duration source_with_handles = True # make sure all frame data is available @@ -771,7 +784,7 @@ class PublishClip: # increasing steps by index of rename iteration self.count_steps *= self.rename_index - hierarchy_formatting_data = dict() + hierarchy_formatting_data = {} _data = self.timeline_item_default_data.copy() if self.ui_inputs: # adding tag metadata from ui @@ -867,7 +880,7 @@ class PublishClip: def _convert_to_entity(self, key): """ Converting input key to key with type. """ # convert to entity type - entity_type = self.types.get(key, None) + entity_type = self.types.get(key) assert entity_type, "Missing entity type for `{}`".format( key From 49154c0750ab45ffeb7bd413ab99b79a6f6aadef Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 16:45:12 +0100 Subject: [PATCH 267/690] fix create multishot layout --- .../maya/plugins/create/create_multishot_layout.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/create/create_multishot_layout.py b/openpype/hosts/maya/plugins/create/create_multishot_layout.py index 0b027c02ea..7cd3fdbd17 100644 --- a/openpype/hosts/maya/plugins/create/create_multishot_layout.py +++ b/openpype/hosts/maya/plugins/create/create_multishot_layout.py @@ -45,10 +45,14 @@ class CreateMultishotLayout(plugin.MayaCreator): above is done. """ - current_folder = get_folder_by_name( - project_name=get_current_project_name(), - folder_name=get_current_asset_name(), - ) + project_name = get_current_project_name() + folder_path = get_current_asset_name() + if "/" in folder_path: + current_folder = get_folder_by_path(project_name, folder_path) + else: + current_folder = get_folder_by_name( + project_name, folder_name=folder_path + ) current_path_parts = current_folder["path"].split("/") From 9154dbab05ec7f5b921874b5d523720df7c9409a Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 15:45:15 +0000 Subject: [PATCH 268/690] Fix loading of blend layout --- openpype/hosts/blender/plugins/load/load_blend.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/load/load_blend.py b/openpype/hosts/blender/plugins/load/load_blend.py index 25d6568889..3d6b634916 100644 --- a/openpype/hosts/blender/plugins/load/load_blend.py +++ b/openpype/hosts/blender/plugins/load/load_blend.py @@ -32,7 +32,7 @@ class BlendLoader(plugin.AssetLoader): empties = [obj for obj in objects if obj.type == 'EMPTY'] for empty in empties: - if empty.get(AVALON_PROPERTY): + if empty.get(AVALON_PROPERTY) and empty.parent is None: return empty return None @@ -90,6 +90,7 @@ class BlendLoader(plugin.AssetLoader): members.append(data) container = self._get_asset_container(data_to.objects) + print(container) assert container, "No asset group found" container.name = group_name @@ -100,8 +101,11 @@ class BlendLoader(plugin.AssetLoader): # Link all the container children to the collection for obj in container.children_recursive: + print(obj) bpy.context.scene.collection.objects.link(obj) + print("") + # Remove the library from the blend file library = bpy.data.libraries.get(bpy.path.basename(libpath)) bpy.data.libraries.remove(library) From dbd1fcb98912616d03c456718baf9b3f2e65a03c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 17:03:54 +0100 Subject: [PATCH 269/690] make sure all QThread objects are always removed from python memory --- .../ayon_utils/widgets/folders_widget.py | 3 +- .../ayon_utils/widgets/projects_widget.py | 13 +++-- .../tools/ayon_utils/widgets/tasks_widget.py | 49 ++++++++++--------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/openpype/tools/ayon_utils/widgets/folders_widget.py b/openpype/tools/ayon_utils/widgets/folders_widget.py index 322553c51c..b72a992858 100644 --- a/openpype/tools/ayon_utils/widgets/folders_widget.py +++ b/openpype/tools/ayon_utils/widgets/folders_widget.py @@ -104,8 +104,8 @@ class FoldersModel(QtGui.QStandardItemModel): if not project_name: self._last_project_name = project_name - self._current_refresh_thread = None self._fill_items({}) + self._current_refresh_thread = None return self._is_refreshing = True @@ -152,6 +152,7 @@ class FoldersModel(QtGui.QStandardItemModel): return self._fill_items(thread.get_result()) + self._current_refresh_thread = None def _fill_item_data(self, item, folder_item): """ diff --git a/openpype/tools/ayon_utils/widgets/projects_widget.py b/openpype/tools/ayon_utils/widgets/projects_widget.py index be18cfe3ed..05347faca4 100644 --- a/openpype/tools/ayon_utils/widgets/projects_widget.py +++ b/openpype/tools/ayon_utils/widgets/projects_widget.py @@ -35,12 +35,11 @@ class ProjectsModel(QtGui.QStandardItemModel): self._selected_project = None - self._is_refreshing = False self._refresh_thread = None @property def is_refreshing(self): - return self._is_refreshing + return self._refresh_thread is not None def refresh(self): self._refresh() @@ -169,15 +168,16 @@ class ProjectsModel(QtGui.QStandardItemModel): return self._select_item def _refresh(self): - if self._is_refreshing: + if self._refresh_thread is not None: return - self._is_refreshing = True + refresh_thread = RefreshThread( "projects", self._query_project_items ) refresh_thread.refresh_finished.connect(self._refresh_finished) - refresh_thread.start() + self._refresh_thread = refresh_thread + refresh_thread.start() def _query_project_items(self): return self._controller.get_project_items() @@ -185,11 +185,10 @@ class ProjectsModel(QtGui.QStandardItemModel): def _refresh_finished(self): # TODO check if failed result = self._refresh_thread.get_result() - self._refresh_thread = None self._fill_items(result) - self._is_refreshing = False + self._refresh_thread = None self.refreshed.emit() def _fill_items(self, project_items): diff --git a/openpype/tools/ayon_utils/widgets/tasks_widget.py b/openpype/tools/ayon_utils/widgets/tasks_widget.py index d01b3a7917..a6375c6ae6 100644 --- a/openpype/tools/ayon_utils/widgets/tasks_widget.py +++ b/openpype/tools/ayon_utils/widgets/tasks_widget.py @@ -185,28 +185,7 @@ class TasksModel(QtGui.QStandardItemModel): thread.refresh_finished.connect(self._on_refresh_thread) thread.start() - def _on_refresh_thread(self, thread_id): - """Callback when refresh thread is finished. - - Technically can be running multiple refresh threads at the same time, - to avoid using values from wrong thread, we check if thread id is - current refresh thread id. - - Tasks are stored by name, so if a folder has same task name as - previously selected folder it keeps the selection. - - Args: - thread_id (str): Thread id. - """ - - # Make sure to remove thread from '_refresh_threads' dict - thread = self._refresh_threads.pop(thread_id) - if ( - self._current_refresh_thread is None - or thread_id != self._current_refresh_thread.id - ): - return - + def _fill_data_from_thread(self, thread): task_items = thread.get_result() # Task items are refreshed if task_items is None: @@ -247,7 +226,33 @@ class TasksModel(QtGui.QStandardItemModel): if new_items: root_item.appendRows(new_items) + def _on_refresh_thread(self, thread_id): + """Callback when refresh thread is finished. + + Technically can be running multiple refresh threads at the same time, + to avoid using values from wrong thread, we check if thread id is + current refresh thread id. + + Tasks are stored by name, so if a folder has same task name as + previously selected folder it keeps the selection. + + Args: + thread_id (str): Thread id. + """ + + # Make sure to remove thread from '_refresh_threads' dict + thread = self._refresh_threads.pop(thread_id) + if ( + self._current_refresh_thread is None + or thread_id != self._current_refresh_thread.id + ): + return + + self._fill_data_from_thread(thread) + + root_item = self.invisibleRootItem() self._has_content = root_item.rowCount() > 0 + self._current_refresh_thread = None self._is_refreshing = False self.refreshed.emit() From 10aea1088a68f49218255e4988febe4bc1f0f462 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Fri, 3 Nov 2023 17:06:44 +0100 Subject: [PATCH 270/690] Add collect workfile to blender host --- .../plugins/publish/collect_workfile.py | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 openpype/hosts/blender/plugins/publish/collect_workfile.py diff --git a/openpype/hosts/blender/plugins/publish/collect_workfile.py b/openpype/hosts/blender/plugins/publish/collect_workfile.py new file mode 100644 index 0000000000..e431405e80 --- /dev/null +++ b/openpype/hosts/blender/plugins/publish/collect_workfile.py @@ -0,0 +1,38 @@ +from pathlib import Path + +import bpy +from pyblish.api import InstancePlugin, CollectorOrder + + +class CollectWorkfile(InstancePlugin): + """Inject workfile data into its instance.""" + + order = CollectorOrder + label = "Collect Workfile" + hosts = ["blender"] + families = ["workfile"] + + def process(self, instance): + """Process collector.""" + + context = instance.context + filepath = Path(context.data["currentFile"]) + ext = filepath.suffix + + instance.data.update( + { + "setMembers": [filepath.as_posix()], + "frameStart": context.data.get("frameStart", 1), + "frameEnd": context.data.get("frameEnd", 1), + "handleStart": context.data.get("handleStart", 1), + "handledEnd": context.data.get("handleEnd", 1), + "representations": [ + { + "name": ext.lstrip("."), + "ext": ext, + "files": filepath.name, # TODO resources + "stagingDir": filepath.parent, + } + ], + } + ) From f18d0d9f8f36fcdc7193aaea5588db391fc5acec Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 18:09:48 +0200 Subject: [PATCH 271/690] include full frame range in representation dictionary --- openpype/hosts/houdini/plugins/publish/extract_ass.py | 4 ++-- openpype/hosts/houdini/plugins/publish/extract_bgeo.py | 4 ++-- openpype/hosts/houdini/plugins/publish/extract_composite.py | 4 ++-- openpype/hosts/houdini/plugins/publish/extract_fbx.py | 6 +++--- openpype/hosts/houdini/plugins/publish/extract_opengl.py | 4 ++-- .../hosts/houdini/plugins/publish/extract_redshift_proxy.py | 6 +++--- openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py | 4 ++-- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/extract_ass.py b/openpype/hosts/houdini/plugins/publish/extract_ass.py index 0d246625ba..be60217055 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_ass.py +++ b/openpype/hosts/houdini/plugins/publish/extract_ass.py @@ -56,7 +56,7 @@ class ExtractAss(publish.Extractor): 'ext': ext, "files": files, "stagingDir": staging_dir, - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"], + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"], } instance.data["representations"].append(representation) diff --git a/openpype/hosts/houdini/plugins/publish/extract_bgeo.py b/openpype/hosts/houdini/plugins/publish/extract_bgeo.py index c9625ec880..d13141b426 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_bgeo.py +++ b/openpype/hosts/houdini/plugins/publish/extract_bgeo.py @@ -47,7 +47,7 @@ class ExtractBGEO(publish.Extractor): "ext": ext.lstrip("."), "files": output, "stagingDir": staging_dir, - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"] + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"] } instance.data["representations"].append(representation) diff --git a/openpype/hosts/houdini/plugins/publish/extract_composite.py b/openpype/hosts/houdini/plugins/publish/extract_composite.py index 7a1ab36b93..11cf83a46d 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_composite.py +++ b/openpype/hosts/houdini/plugins/publish/extract_composite.py @@ -41,8 +41,8 @@ class ExtractComposite(publish.Extractor): "ext": ext, "files": output, "stagingDir": staging_dir, - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"], + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"], } from pprint import pformat diff --git a/openpype/hosts/houdini/plugins/publish/extract_fbx.py b/openpype/hosts/houdini/plugins/publish/extract_fbx.py index 7993b3352f..1be61ecce1 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_fbx.py +++ b/openpype/hosts/houdini/plugins/publish/extract_fbx.py @@ -40,9 +40,9 @@ class ExtractFBX(publish.Extractor): } # A single frame may also be rendered without start/end frame. - if "frameStart" in instance.data and "frameEnd" in instance.data: - representation["frameStart"] = instance.data["frameStart"] - representation["frameEnd"] = instance.data["frameEnd"] + if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: + representation["frameStart"] = instance.data["frameStartHandle"] + representation["frameEnd"] = instance.data["frameEndHandle"] # set value type for 'representations' key to list if "representations" not in instance.data: diff --git a/openpype/hosts/houdini/plugins/publish/extract_opengl.py b/openpype/hosts/houdini/plugins/publish/extract_opengl.py index 6c36dec5f5..38808089ac 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_opengl.py +++ b/openpype/hosts/houdini/plugins/publish/extract_opengl.py @@ -39,8 +39,8 @@ class ExtractOpenGL(publish.Extractor): "ext": instance.data["imageFormat"], "files": output, "stagingDir": staging_dir, - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"], + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"], "tags": tags, "preview": True, "camera_name": instance.data.get("review_camera") diff --git a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py index 1d99ac665c..18cbd5712e 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py +++ b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py @@ -44,8 +44,8 @@ class ExtractRedshiftProxy(publish.Extractor): } # A single frame may also be rendered without start/end frame. - if "frameStart" in instance.data and "frameEnd" in instance.data: - representation["frameStart"] = instance.data["frameStart"] - representation["frameEnd"] = instance.data["frameEnd"] + if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: + representation["frameStart"] = instance.data["frameStartHandle"] + representation["frameEnd"] = instance.data["frameEndHandle"] instance.data["representations"].append(representation) diff --git a/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py b/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py index 4bca758f08..89af8e1756 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py +++ b/openpype/hosts/houdini/plugins/publish/extract_vdb_cache.py @@ -40,7 +40,7 @@ class ExtractVDBCache(publish.Extractor): "ext": "vdb", "files": output, "stagingDir": staging_dir, - "frameStart": instance.data["frameStart"], - "frameEnd": instance.data["frameEnd"], + "frameStart": instance.data["frameStartHandle"], + "frameEnd": instance.data["frameEndHandle"], } instance.data["representations"].append(representation) From 821b478830f2f75f733d82374bd06195db01e9d8 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 16:50:11 +0000 Subject: [PATCH 272/690] Get the selection when creating the instance --- .../plugins/create/create_blendScene.py | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index 96e63924d3..970be157b9 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -15,6 +15,8 @@ class CreateBlendScene(plugin.Creator): family = "blendScene" icon = "cubes" + maintain_selection = False + def process(self): """ Run the creator on Blender main thread""" mti = ops.MainThreadItem(self._process) @@ -38,4 +40,29 @@ class CreateBlendScene(plugin.Creator): self.data['task'] = get_current_task_name() lib.imprint(asset_group, self.data) + try: + area = next( + area for area in bpy.context.window.screen.areas + if area.type == 'OUTLINER') + region = next( + region for region in area.regions + if region.type == 'WINDOW') + except StopIteration as e: + raise RuntimeError("Could not find outliner. An outliner space " + "must be in the main Blender window.") from e + + with bpy.context.temp_override( + window=bpy.context.window, + area=area, + region=region, + screen=bpy.context.window.screen + ): + ids = bpy.context.selected_ids + + for id in ids: + if isinstance(id, bpy.types.Collection): + asset_group.children.link(id) + elif isinstance(id, bpy.types.Object): + asset_group.objects.link(id) + return asset_group From b5ebe86b1482d5790296283323e96aab060dbad6 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 16:51:21 +0000 Subject: [PATCH 273/690] Hound fixes --- openpype/hosts/blender/plugins/create/create_blendScene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index 970be157b9..791e741ca7 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -41,7 +41,7 @@ class CreateBlendScene(plugin.Creator): lib.imprint(asset_group, self.data) try: - area = next( + area = next( area for area in bpy.context.window.screen.areas if area.type == 'OUTLINER') region = next( From e6d13db010609fabe648e43a9745f94e2c355a14 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 17:27:25 +0000 Subject: [PATCH 274/690] Keeps the transform when updating --- openpype/hosts/blender/plugins/load/load_blendscene.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py index fe7afb3119..34030d9d84 100644 --- a/openpype/hosts/blender/plugins/load/load_blendscene.py +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -136,13 +136,18 @@ class BlendSceneLoader(plugin.AssetLoader): f"The asset is not loaded: {container['objectName']}" ) + # Get the parents of the members of the asset group, so we can + # re-link them after the update. + # Also gets the transform for each object to reapply after the update. collection_parents = {} + member_transforms = {} members = asset_group.get(AVALON_PROPERTY).get("members", []) loaded_collections = {c for c in bpy.data.collections if c in members} loaded_collections.add(bpy.data.collections.get(AVALON_CONTAINERS)) for member in members: if isinstance(member, bpy.types.Object): member_parents = set(member.users_collection) + member_transforms[member.name] = member.matrix_basis.copy() elif isinstance(member, bpy.types.Collection): member_parents = { c for c in bpy.data.collections if c.user_of_id(member)} @@ -167,6 +172,9 @@ class BlendSceneLoader(plugin.AssetLoader): parent.objects.link(member) elif isinstance(member, bpy.types.Collection): parent.children.link(member) + if (member.name in member_transforms and + isinstance(member, bpy.types.Object)): + member.matrix_basis = member_transforms[member.name] avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) avalon_container.children.link(asset_group) From 4a9f1e7d785298b4df94a1a61bc983cdc73c37b9 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 17:29:12 +0000 Subject: [PATCH 275/690] Hound fixes --- openpype/hosts/blender/plugins/load/load_blendscene.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py index 34030d9d84..28dcf4fc70 100644 --- a/openpype/hosts/blender/plugins/load/load_blendscene.py +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -174,7 +174,7 @@ class BlendSceneLoader(plugin.AssetLoader): parent.children.link(member) if (member.name in member_transforms and isinstance(member, bpy.types.Object)): - member.matrix_basis = member_transforms[member.name] + member.matrix_basis = member_transforms[member.name] avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) avalon_container.children.link(asset_group) From 8f4d490af25ad8765c6f7ae056a57e00b97a228f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Fri, 3 Nov 2023 17:30:25 +0000 Subject: [PATCH 276/690] Hound fixes --- openpype/hosts/blender/plugins/load/load_blendscene.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py index 28dcf4fc70..b1b2c3ba79 100644 --- a/openpype/hosts/blender/plugins/load/load_blendscene.py +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -172,9 +172,10 @@ class BlendSceneLoader(plugin.AssetLoader): parent.objects.link(member) elif isinstance(member, bpy.types.Collection): parent.children.link(member) - if (member.name in member_transforms and - isinstance(member, bpy.types.Object)): - member.matrix_basis = member_transforms[member.name] + if member.name in member_transforms and isinstance( + member, bpy.types.Object + ): + member.matrix_basis = member_transforms[member.name] avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) avalon_container.children.link(asset_group) From 2a19d5cc548e55bd526f24a70494717fbe5f23c7 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 18:57:15 +0100 Subject: [PATCH 277/690] fix default type of projects model cache --- openpype/tools/ayon_utils/models/projects.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/tools/ayon_utils/models/projects.py b/openpype/tools/ayon_utils/models/projects.py index 4ad53fbbfa..383f676c64 100644 --- a/openpype/tools/ayon_utils/models/projects.py +++ b/openpype/tools/ayon_utils/models/projects.py @@ -87,7 +87,7 @@ def _get_project_items_from_entitiy(projects): class ProjectsModel(object): def __init__(self, controller): - self._projects_cache = CacheItem(default_factory=dict) + self._projects_cache = CacheItem(default_factory=list) self._project_items_by_name = {} self._projects_by_name = {} From 3bffe3b31b3b367e4a24f0446d2b217e3623ecbe Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 18:58:29 +0100 Subject: [PATCH 278/690] renamed 'ProjectsModel' to 'ProjectsQtModel' --- openpype/tools/ayon_launcher/ui/projects_widget.py | 4 ++-- openpype/tools/ayon_utils/widgets/__init__.py | 4 ++-- openpype/tools/ayon_utils/widgets/projects_widget.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/tools/ayon_launcher/ui/projects_widget.py b/openpype/tools/ayon_launcher/ui/projects_widget.py index 7dbaec5147..31c36719a6 100644 --- a/openpype/tools/ayon_launcher/ui/projects_widget.py +++ b/openpype/tools/ayon_launcher/ui/projects_widget.py @@ -3,7 +3,7 @@ from qtpy import QtWidgets, QtCore from openpype.tools.flickcharm import FlickCharm from openpype.tools.utils import PlaceholderLineEdit, RefreshButton from openpype.tools.ayon_utils.widgets import ( - ProjectsModel, + ProjectsQtModel, ProjectSortFilterProxy, ) from openpype.tools.ayon_utils.models import PROJECTS_MODEL_SENDER @@ -95,7 +95,7 @@ class ProjectsWidget(QtWidgets.QWidget): projects_view.setSelectionMode(QtWidgets.QListView.NoSelection) flick = FlickCharm(parent=self) flick.activateOn(projects_view) - projects_model = ProjectsModel(controller) + projects_model = ProjectsQtModel(controller) projects_proxy_model = ProjectSortFilterProxy() projects_proxy_model.setSourceModel(projects_model) diff --git a/openpype/tools/ayon_utils/widgets/__init__.py b/openpype/tools/ayon_utils/widgets/__init__.py index 432a249a73..1ef7dfe482 100644 --- a/openpype/tools/ayon_utils/widgets/__init__.py +++ b/openpype/tools/ayon_utils/widgets/__init__.py @@ -1,7 +1,7 @@ from .projects_widget import ( # ProjectsWidget, ProjectsCombobox, - ProjectsModel, + ProjectsQtModel, ProjectSortFilterProxy, ) @@ -25,7 +25,7 @@ from .utils import ( __all__ = ( # "ProjectsWidget", "ProjectsCombobox", - "ProjectsModel", + "ProjectsQtModel", "ProjectSortFilterProxy", "FoldersWidget", diff --git a/openpype/tools/ayon_utils/widgets/projects_widget.py b/openpype/tools/ayon_utils/widgets/projects_widget.py index 05347faca4..9f0f839281 100644 --- a/openpype/tools/ayon_utils/widgets/projects_widget.py +++ b/openpype/tools/ayon_utils/widgets/projects_widget.py @@ -10,11 +10,11 @@ PROJECT_IS_CURRENT_ROLE = QtCore.Qt.UserRole + 4 LIBRARY_PROJECT_SEPARATOR_ROLE = QtCore.Qt.UserRole + 5 -class ProjectsModel(QtGui.QStandardItemModel): +class ProjectsQtModel(QtGui.QStandardItemModel): refreshed = QtCore.Signal() def __init__(self, controller): - super(ProjectsModel, self).__init__() + super(ProjectsQtModel, self).__init__() self._controller = controller self._project_items = {} @@ -402,7 +402,7 @@ class ProjectsCombobox(QtWidgets.QWidget): projects_combobox = QtWidgets.QComboBox(self) combobox_delegate = QtWidgets.QStyledItemDelegate(projects_combobox) projects_combobox.setItemDelegate(combobox_delegate) - projects_model = ProjectsModel(controller) + projects_model = ProjectsQtModel(controller) projects_proxy_model = ProjectSortFilterProxy() projects_proxy_model.setSourceModel(projects_model) projects_combobox.setModel(projects_proxy_model) From 264e3cac79b863c5eb45841860da7789a13e714f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 18:59:02 +0100 Subject: [PATCH 279/690] renamed other qt models to contain 'Qt' --- openpype/tools/ayon_loader/ui/folders_widget.py | 4 ++-- openpype/tools/ayon_utils/widgets/__init__.py | 8 ++++---- openpype/tools/ayon_utils/widgets/folders_widget.py | 6 +++--- openpype/tools/ayon_utils/widgets/tasks_widget.py | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openpype/tools/ayon_loader/ui/folders_widget.py b/openpype/tools/ayon_loader/ui/folders_widget.py index 53351f76d9..eaaf7ca617 100644 --- a/openpype/tools/ayon_loader/ui/folders_widget.py +++ b/openpype/tools/ayon_loader/ui/folders_widget.py @@ -8,7 +8,7 @@ from openpype.tools.utils import ( from openpype.style import get_objected_colors from openpype.tools.ayon_utils.widgets import ( - FoldersModel, + FoldersQtModel, FOLDERS_MODEL_SENDER_NAME, ) from openpype.tools.ayon_utils.widgets.folders_widget import FOLDER_ID_ROLE @@ -182,7 +182,7 @@ class UnderlinesFolderDelegate(QtWidgets.QItemDelegate): painter.restore() -class LoaderFoldersModel(FoldersModel): +class LoaderFoldersModel(FoldersQtModel): def __init__(self, *args, **kwargs): super(LoaderFoldersModel, self).__init__(*args, **kwargs) diff --git a/openpype/tools/ayon_utils/widgets/__init__.py b/openpype/tools/ayon_utils/widgets/__init__.py index 1ef7dfe482..f58de17c4a 100644 --- a/openpype/tools/ayon_utils/widgets/__init__.py +++ b/openpype/tools/ayon_utils/widgets/__init__.py @@ -7,13 +7,13 @@ from .projects_widget import ( from .folders_widget import ( FoldersWidget, - FoldersModel, + FoldersQtModel, FOLDERS_MODEL_SENDER_NAME, ) from .tasks_widget import ( TasksWidget, - TasksModel, + TasksQtModel, TASKS_MODEL_SENDER_NAME, ) from .utils import ( @@ -29,11 +29,11 @@ __all__ = ( "ProjectSortFilterProxy", "FoldersWidget", - "FoldersModel", + "FoldersQtModel", "FOLDERS_MODEL_SENDER_NAME", "TasksWidget", - "TasksModel", + "TasksQtModel", "TASKS_MODEL_SENDER_NAME", "get_qt_icon", diff --git a/openpype/tools/ayon_utils/widgets/folders_widget.py b/openpype/tools/ayon_utils/widgets/folders_widget.py index b72a992858..44323a192c 100644 --- a/openpype/tools/ayon_utils/widgets/folders_widget.py +++ b/openpype/tools/ayon_utils/widgets/folders_widget.py @@ -16,7 +16,7 @@ FOLDER_PATH_ROLE = QtCore.Qt.UserRole + 3 FOLDER_TYPE_ROLE = QtCore.Qt.UserRole + 4 -class FoldersModel(QtGui.QStandardItemModel): +class FoldersQtModel(QtGui.QStandardItemModel): """Folders model which cares about refresh of folders. Args: @@ -26,7 +26,7 @@ class FoldersModel(QtGui.QStandardItemModel): refreshed = QtCore.Signal() def __init__(self, controller): - super(FoldersModel, self).__init__() + super(FoldersQtModel, self).__init__() self._controller = controller self._items_by_id = {} @@ -282,7 +282,7 @@ class FoldersWidget(QtWidgets.QWidget): folders_view = TreeView(self) folders_view.setHeaderHidden(True) - folders_model = FoldersModel(controller) + folders_model = FoldersQtModel(controller) folders_proxy_model = RecursiveSortFilterProxyModel() folders_proxy_model.setSourceModel(folders_model) folders_proxy_model.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) diff --git a/openpype/tools/ayon_utils/widgets/tasks_widget.py b/openpype/tools/ayon_utils/widgets/tasks_widget.py index a6375c6ae6..f27711acdd 100644 --- a/openpype/tools/ayon_utils/widgets/tasks_widget.py +++ b/openpype/tools/ayon_utils/widgets/tasks_widget.py @@ -12,7 +12,7 @@ ITEM_NAME_ROLE = QtCore.Qt.UserRole + 3 TASK_TYPE_ROLE = QtCore.Qt.UserRole + 4 -class TasksModel(QtGui.QStandardItemModel): +class TasksQtModel(QtGui.QStandardItemModel): """Tasks model which cares about refresh of tasks by folder id. Args: @@ -22,7 +22,7 @@ class TasksModel(QtGui.QStandardItemModel): refreshed = QtCore.Signal() def __init__(self, controller): - super(TasksModel, self).__init__() + super(TasksQtModel, self).__init__() self._controller = controller @@ -285,7 +285,7 @@ class TasksModel(QtGui.QStandardItemModel): if section == 0: return "Tasks" - return super(TasksModel, self).headerData( + return super(TasksQtModel, self).headerData( section, orientation, role ) @@ -310,7 +310,7 @@ class TasksWidget(QtWidgets.QWidget): tasks_view = DeselectableTreeView(self) tasks_view.setIndentation(0) - tasks_model = TasksModel(controller) + tasks_model = TasksQtModel(controller) tasks_proxy_model = QtCore.QSortFilterProxyModel() tasks_proxy_model.setSourceModel(tasks_model) tasks_proxy_model.setSortCaseSensitivity(QtCore.Qt.CaseInsensitive) From 86e4bed1514a1506200ac3ca9c51956c95414b2b Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 18:59:52 +0100 Subject: [PATCH 280/690] validate that item on which is clicked is enabled --- openpype/tools/ayon_launcher/ui/projects_widget.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openpype/tools/ayon_launcher/ui/projects_widget.py b/openpype/tools/ayon_launcher/ui/projects_widget.py index 31c36719a6..38c7f62bd5 100644 --- a/openpype/tools/ayon_launcher/ui/projects_widget.py +++ b/openpype/tools/ayon_launcher/ui/projects_widget.py @@ -133,9 +133,14 @@ class ProjectsWidget(QtWidgets.QWidget): return self._projects_model.has_content() def _on_view_clicked(self, index): - if index.isValid(): - project_name = index.data(QtCore.Qt.DisplayRole) - self._controller.set_selected_project(project_name) + if not index.isValid(): + return + model = index.model() + flags = model.flags(index) + if not flags & QtCore.Qt.ItemIsEnabled: + return + project_name = index.data(QtCore.Qt.DisplayRole) + self._controller.set_selected_project(project_name) def _on_project_filter_change(self, text): self._projects_proxy_model.setFilterFixedString(text) From 05748bbb9291424ed82495a63bc581b2437fe772 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 19:00:51 +0100 Subject: [PATCH 281/690] projects model pass sender value --- openpype/tools/ayon_utils/widgets/projects_widget.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/tools/ayon_utils/widgets/projects_widget.py b/openpype/tools/ayon_utils/widgets/projects_widget.py index 9f0f839281..804b7a05ac 100644 --- a/openpype/tools/ayon_utils/widgets/projects_widget.py +++ b/openpype/tools/ayon_utils/widgets/projects_widget.py @@ -180,7 +180,9 @@ class ProjectsQtModel(QtGui.QStandardItemModel): refresh_thread.start() def _query_project_items(self): - return self._controller.get_project_items() + return self._controller.get_project_items( + sender=PROJECTS_MODEL_SENDER + ) def _refresh_finished(self): # TODO check if failed From 42c32f81969399bc900fdfe2900d0da0e8c3edea Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 19:01:26 +0100 Subject: [PATCH 282/690] projects model returns 'None' if is in middle of refreshing --- openpype/tools/ayon_utils/models/projects.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/openpype/tools/ayon_utils/models/projects.py b/openpype/tools/ayon_utils/models/projects.py index 383f676c64..36d53edc24 100644 --- a/openpype/tools/ayon_utils/models/projects.py +++ b/openpype/tools/ayon_utils/models/projects.py @@ -103,8 +103,18 @@ class ProjectsModel(object): self._refresh_projects_cache() def get_project_items(self, sender): + """ + + Args: + sender (str): Name of sender who asked for items. + + Returns: + Union[list[ProjectItem], None]: List of project items, or None + if model is refreshing. + """ + if not self._projects_cache.is_valid: - self._refresh_projects_cache(sender) + return self._refresh_projects_cache(sender) return self._projects_cache.get_data() def get_project_entity(self, project_name): @@ -136,11 +146,12 @@ class ProjectsModel(object): def _refresh_projects_cache(self, sender=None): if self._is_refreshing: - return + return None with self._project_refresh_event_manager(sender): project_items = self._query_projects() self._projects_cache.update_data(project_items) + return self._projects_cache.get_data() def _query_projects(self): projects = ayon_api.get_projects(fields=["name", "active", "library"]) From 5a0b2f69153f71469b60acf78d588c3583493764 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 19:01:40 +0100 Subject: [PATCH 283/690] projects model handle cases when model is refreshing --- openpype/tools/ayon_utils/widgets/projects_widget.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openpype/tools/ayon_utils/widgets/projects_widget.py b/openpype/tools/ayon_utils/widgets/projects_widget.py index 804b7a05ac..2beee29cb9 100644 --- a/openpype/tools/ayon_utils/widgets/projects_widget.py +++ b/openpype/tools/ayon_utils/widgets/projects_widget.py @@ -1,3 +1,5 @@ +import uuid + from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.ayon_utils.models import PROJECTS_MODEL_SENDER @@ -187,11 +189,14 @@ class ProjectsQtModel(QtGui.QStandardItemModel): def _refresh_finished(self): # TODO check if failed result = self._refresh_thread.get_result() - - self._fill_items(result) + if result is not None: + self._fill_items(result) self._refresh_thread = None - self.refreshed.emit() + if result is None: + self._refresh() + else: + self.refreshed.emit() def _fill_items(self, project_items): new_project_names = { From 779cea668862a9354816f5fb9c62bf0d71496951 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 20:04:16 +0200 Subject: [PATCH 284/690] update dictionary keys to be frames with handles --- .../hosts/houdini/plugins/publish/collect_review_data.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/collect_review_data.py b/openpype/hosts/houdini/plugins/publish/collect_review_data.py index 3efb75e66c..9671945b9a 100644 --- a/openpype/hosts/houdini/plugins/publish/collect_review_data.py +++ b/openpype/hosts/houdini/plugins/publish/collect_review_data.py @@ -6,6 +6,8 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): """Collect Review Data.""" label = "Collect Review Data" + # This specific order value is used so that + # this plugin runs after CollectRopFrameRange order = pyblish.api.CollectorOrder + 0.1 hosts = ["houdini"] families = ["review"] @@ -41,8 +43,8 @@ class CollectHoudiniReviewData(pyblish.api.InstancePlugin): return if focal_length_parm.isTimeDependent(): - start = instance.data["frameStart"] - end = instance.data["frameEnd"] + 1 + start = instance.data["frameStartHandle"] + end = instance.data["frameEndHandle"] + 1 focal_length = [ focal_length_parm.evalAsFloatAtFrame(t) for t in range(int(start), int(end)) From 15a52469354238165236ed890d10679e932f4439 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Fri, 3 Nov 2023 20:07:15 +0200 Subject: [PATCH 285/690] Resolve Hound --- openpype/hosts/houdini/plugins/publish/extract_fbx.py | 2 +- .../hosts/houdini/plugins/publish/extract_redshift_proxy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/extract_fbx.py b/openpype/hosts/houdini/plugins/publish/extract_fbx.py index 1be61ecce1..7dc193c6a9 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_fbx.py +++ b/openpype/hosts/houdini/plugins/publish/extract_fbx.py @@ -40,7 +40,7 @@ class ExtractFBX(publish.Extractor): } # A single frame may also be rendered without start/end frame. - if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: + if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: # noqa representation["frameStart"] = instance.data["frameStartHandle"] representation["frameEnd"] = instance.data["frameEndHandle"] diff --git a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py index 18cbd5712e..ef5991924f 100644 --- a/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py +++ b/openpype/hosts/houdini/plugins/publish/extract_redshift_proxy.py @@ -44,7 +44,7 @@ class ExtractRedshiftProxy(publish.Extractor): } # A single frame may also be rendered without start/end frame. - if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: + if "frameStartHandle" in instance.data and "frameEndHandle" in instance.data: # noqa representation["frameStart"] = instance.data["frameStartHandle"] representation["frameEnd"] = instance.data["frameEndHandle"] From d87506f8af15123cdc0d07176dba26bce262a434 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Fri, 3 Nov 2023 19:12:17 +0100 Subject: [PATCH 286/690] removed unused import --- openpype/tools/ayon_utils/widgets/projects_widget.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/openpype/tools/ayon_utils/widgets/projects_widget.py b/openpype/tools/ayon_utils/widgets/projects_widget.py index 2beee29cb9..f98bfcdf8a 100644 --- a/openpype/tools/ayon_utils/widgets/projects_widget.py +++ b/openpype/tools/ayon_utils/widgets/projects_widget.py @@ -1,5 +1,3 @@ -import uuid - from qtpy import QtWidgets, QtCore, QtGui from openpype.tools.ayon_utils.models import PROJECTS_MODEL_SENDER From bd94b8dcc972fe8f954b9b10de46350d1515864c Mon Sep 17 00:00:00 2001 From: Ynbot Date: Sat, 4 Nov 2023 03:25:15 +0000 Subject: [PATCH 287/690] [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 4865fcfb31..c6ebd65e9c 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.17.5-nightly.2" +__version__ = "3.17.5-nightly.3" From 2ab07ec7ede740c13d98e8abeca9c02f73db4182 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 4 Nov 2023 03:25:51 +0000 Subject: [PATCH 288/690] chore(): update bug report / version --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 249da3da0e..7a1fe9d83e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,6 +35,7 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.17.5-nightly.3 - 3.17.5-nightly.2 - 3.17.5-nightly.1 - 3.17.4 @@ -134,7 +135,6 @@ body: - 3.15.1-nightly.5 - 3.15.1-nightly.4 - 3.15.1-nightly.3 - - 3.15.1-nightly.2 validations: required: true - type: dropdown From b079ca8d0f76ede60866dcb26f506189cbfcea9e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 6 Nov 2023 15:41:20 +0800 Subject: [PATCH 289/690] clean up the duplicated variable --- openpype/settings/ayon_settings.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 88fbbd5124..fa73199269 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -649,7 +649,6 @@ def _convert_3dsmax_project_settings(ayon_settings, output): attributes = {} ayon_publish["ValidateAttributes"]["attributes"] = attributes - ayon_publish = ayon_max["publish"] if "ValidateLoadedPlugin" in ayon_publish: family_plugin_mapping = ( ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] From 7b9c6c3b99900dde8ea841a2bfe25ea02f4cbeff Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Mon, 6 Nov 2023 10:30:13 +0000 Subject: [PATCH 290/690] Added validator to verify that the instance is not empty --- .../publish/validate_instance_empty.py | 18 ++++++++++ .../defaults/project_settings/blender.json | 5 +++ .../schemas/schema_blender_publish.json | 16 +++++++++ .../server/settings/publish_plugins.py | 35 ++++++++++++------- server_addon/blender/server/version.py | 2 +- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 openpype/hosts/blender/plugins/publish/validate_instance_empty.py diff --git a/openpype/hosts/blender/plugins/publish/validate_instance_empty.py b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py new file mode 100644 index 0000000000..66d8b45e1e --- /dev/null +++ b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py @@ -0,0 +1,18 @@ +import bpy + +import pyblish.api + + +class ValidateInstanceEmpty(pyblish.api.InstancePlugin): + """Validator to verify that the instance is not empty""" + + order = pyblish.api.ValidatorOrder - 0.01 + hosts = ["blender"] + families = ["blendScene"] + label = "Validate Instance is not Empty" + optional = False + + def process(self, instance): + collection = bpy.data.collections[instance.name] + if not (collection.objects or collection.children): + raise RuntimeError(f"Instance {instance.name} is empty.") diff --git a/openpype/settings/defaults/project_settings/blender.json b/openpype/settings/defaults/project_settings/blender.json index 7fb8c333a6..385e97ef91 100644 --- a/openpype/settings/defaults/project_settings/blender.json +++ b/openpype/settings/defaults/project_settings/blender.json @@ -71,6 +71,11 @@ "optional": false, "active": true }, + "ValidateInstanceEmpty": { + "enabled": true, + "optional": false, + "active": true + }, "ExtractBlend": { "enabled": true, "optional": true, diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json index b84c663e6c..e4f1096223 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_blender_publish.json @@ -79,6 +79,22 @@ } ] }, + { + "type": "collapsible-wrap", + "label": "BlendScene", + "children": [ + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateInstanceEmpty", + "label": "Validate Instance is not Empty" + } + ] + } + ] + }, { "type": "collapsible-wrap", "label": "Render", diff --git a/server_addon/blender/server/settings/publish_plugins.py b/server_addon/blender/server/settings/publish_plugins.py index 27dc0b232f..bb68b40cbb 100644 --- a/server_addon/blender/server/settings/publish_plugins.py +++ b/server_addon/blender/server/settings/publish_plugins.py @@ -61,26 +61,16 @@ class PublishPuginsModel(BaseSettingsModel): ValidateCameraZeroKeyframe: ValidatePluginModel = Field( default_factory=ValidatePluginModel, title="Validate Camera Zero Keyframe", - section="Validators" + section="General Validators" ) ValidateFileSaved: ValidateFileSavedModel = Field( default_factory=ValidateFileSavedModel, title="Validate File Saved", - section="Validators" - ) - ValidateRenderCameraIsSet: ValidatePluginModel = Field( - default_factory=ValidatePluginModel, - title="Validate Render Camera Is Set", - section="Validators" - ) - ValidateDeadlinePublish: ValidatePluginModel = Field( - default_factory=ValidatePluginModel, - title="Validate Render Output for Deadline", - section="Validators" ) ValidateMeshHasUvs: ValidatePluginModel = Field( default_factory=ValidatePluginModel, - title="Validate Mesh Has Uvs" + title="Validate Mesh Has Uvs", + section="Model Validators" ) ValidateMeshNoNegativeScale: ValidatePluginModel = Field( default_factory=ValidatePluginModel, @@ -94,6 +84,20 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=ValidatePluginModel, title="Validate No Colons In Name" ) + ValidateInstanceEmpty: ValidatePluginModel = Field( + default_factory=ValidatePluginModel, + title="Validate Instance is not Empty", + section="BlendScene Validators" + ) + ValidateRenderCameraIsSet: ValidatePluginModel = Field( + default_factory=ValidatePluginModel, + title="Validate Render Camera Is Set", + section="Render Validators" + ) + ValidateDeadlinePublish: ValidatePluginModel = Field( + default_factory=ValidatePluginModel, + title="Validate Render Output for Deadline", + ) ExtractBlend: ExtractBlendModel = Field( default_factory=ExtractBlendModel, title="Extract Blend", @@ -179,6 +183,11 @@ DEFAULT_BLENDER_PUBLISH_SETTINGS = { "optional": False, "active": True }, + "ValidateInstanceEmpty": { + "enabled": True, + "optional": False, + "active": True + }, "ExtractBlend": { "enabled": True, "optional": True, diff --git a/server_addon/blender/server/version.py b/server_addon/blender/server/version.py index ae7362549b..1276d0254f 100644 --- a/server_addon/blender/server/version.py +++ b/server_addon/blender/server/version.py @@ -1 +1 @@ -__version__ = "0.1.3" +__version__ = "0.1.5" From 026fa6567680e4079c20158f16edad466b777999 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 6 Nov 2023 21:19:30 +0800 Subject: [PATCH 291/690] value tweaks on aspect ratio --- openpype/hosts/max/api/preview_animation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/max/api/preview_animation.py b/openpype/hosts/max/api/preview_animation.py index bd0fee3658..bbf05f4ca9 100644 --- a/openpype/hosts/max/api/preview_animation.py +++ b/openpype/hosts/max/api/preview_animation.py @@ -185,8 +185,8 @@ def _render_preview_animation_max_pre_2024( # get the screenshot percent = percentSize / 100.0 - res_width = int(round(width * percent)) - res_height = int(round(height * percent)) + res_width = width * percent + res_height = height * percent frame_template = "{}.{{:04}}.{}".format(filepath, ext) frame_template.replace("\\", "/") files = [] @@ -212,7 +212,7 @@ def _render_preview_animation_max_pre_2024( widthCrop = dib_height * renderRatio leftEdge = int((dib_width - widthCrop) / 2.0) tempImage_bmp = rt.bitmap(widthCrop, dib_height) - src_box_value = rt.Box2(0, leftEdge, widthCrop, dib_height) + src_box_value = rt.Box2(leftEdge, 0, widthCrop, dib_height) rt.pasteBitmap(dib, tempImage_bmp, src_box_value, rt.Point2(0, 0)) # copy the bitmap and close it rt.copy(tempImage_bmp, preview_res) From 8f21d653e079662eef75a435ea97b26d101d7567 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Mon, 6 Nov 2023 21:32:43 +0800 Subject: [PATCH 292/690] use product_types instead of families --- server_addon/core/server/settings/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/core/server/settings/tools.py b/server_addon/core/server/settings/tools.py index d7c7b367b7..0dd9d396ae 100644 --- a/server_addon/core/server/settings/tools.py +++ b/server_addon/core/server/settings/tools.py @@ -489,7 +489,7 @@ DEFAULT_TOOLS_VALUES = { "template_name": "publish_online" }, { - "families": [ + "product_types": [ "tycache" ], "hosts": [ From 1d34d5b1ae48ef69e12d30585b03a9352203f498 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 6 Nov 2023 18:04:08 +0100 Subject: [PATCH 293/690] use "asset" value instead of name from assetEntity --- .../hosts/maya/plugins/publish/validate_instance_in_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py index 4ded57137c..edfb002278 100644 --- a/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py +++ b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py @@ -74,4 +74,4 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin, @staticmethod def get_context_asset(instance): - return instance.context.data["assetEntity"]["name"] + return instance.context.data["asset"] From f2e14e7f4aa4c9d1557e3fdacc05cc564c21d7bb Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 6 Nov 2023 18:05:37 +0100 Subject: [PATCH 294/690] use asset and project from instance and context data --- openpype/hosts/maya/plugins/publish/collect_review.py | 8 ++++---- .../hosts/maya/plugins/publish/validate_model_name.py | 6 ++++-- .../hosts/maya/plugins/publish/validate_shader_name.py | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/collect_review.py b/openpype/hosts/maya/plugins/publish/collect_review.py index 586939a3b8..0930da8f27 100644 --- a/openpype/hosts/maya/plugins/publish/collect_review.py +++ b/openpype/hosts/maya/plugins/publish/collect_review.py @@ -3,7 +3,7 @@ from maya import cmds, mel import pyblish.api from openpype.client import get_subset_by_name -from openpype.pipeline import legacy_io, KnownPublishError +from openpype.pipeline import KnownPublishError from openpype.hosts.maya.api import lib @@ -116,10 +116,10 @@ class CollectReview(pyblish.api.InstancePlugin): instance.data['remove'] = True else: - task = legacy_io.Session["AVALON_TASK"] - legacy_subset_name = task + 'Review' + project_name = instance.context.data["projectName"] asset_doc = instance.context.data['assetEntity'] - project_name = legacy_io.active_project() + task = instance.context.data["task"] + legacy_subset_name = task + 'Review' subset_doc = get_subset_by_name( project_name, legacy_subset_name, diff --git a/openpype/hosts/maya/plugins/publish/validate_model_name.py b/openpype/hosts/maya/plugins/publish/validate_model_name.py index f4c1aa39c7..11f59bb439 100644 --- a/openpype/hosts/maya/plugins/publish/validate_model_name.py +++ b/openpype/hosts/maya/plugins/publish/validate_model_name.py @@ -67,13 +67,15 @@ class ValidateModelName(pyblish.api.InstancePlugin, regex = cls.top_level_regex r = re.compile(regex) m = r.match(top_group) + project_name = instance.context.data["projectName"] + current_asset_name = instance.context.data["asset"] if m is None: cls.log.error("invalid name on: {}".format(top_group)) cls.log.error("name doesn't match regex {}".format(regex)) invalid.append(top_group) else: if "asset" in r.groupindex: - if m.group("asset") != legacy_io.Session["AVALON_ASSET"]: + if m.group("asset") != current_asset_name: cls.log.error("Invalid asset name in top level group.") return top_group if "subset" in r.groupindex: @@ -81,7 +83,7 @@ class ValidateModelName(pyblish.api.InstancePlugin, cls.log.error("Invalid subset name in top level group.") return top_group if "project" in r.groupindex: - if m.group("project") != legacy_io.Session["AVALON_PROJECT"]: + if m.group("project") != project_name: cls.log.error("Invalid project name in top level group.") return top_group diff --git a/openpype/hosts/maya/plugins/publish/validate_shader_name.py b/openpype/hosts/maya/plugins/publish/validate_shader_name.py index 36bb2c1fee..d6486dea7f 100644 --- a/openpype/hosts/maya/plugins/publish/validate_shader_name.py +++ b/openpype/hosts/maya/plugins/publish/validate_shader_name.py @@ -51,7 +51,7 @@ class ValidateShaderName(pyblish.api.InstancePlugin, descendants = cmds.ls(descendants, noIntermediate=True, long=True) shapes = cmds.ls(descendants, type=["nurbsSurface", "mesh"], long=True) - asset_name = instance.data.get("asset", None) + asset_name = instance.data.get("asset") # Check the number of connected shadingEngines per shape regex_compile = re.compile(cls.regex) From b7bec4b4e4fea704b0706013e76ac03de325ebee Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Mon, 6 Nov 2023 18:28:51 +0100 Subject: [PATCH 295/690] use correct label for follow workfile version --- server_addon/core/server/settings/publish_plugins.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/core/server/settings/publish_plugins.py b/server_addon/core/server/settings/publish_plugins.py index 69a759465e..93d8db964d 100644 --- a/server_addon/core/server/settings/publish_plugins.py +++ b/server_addon/core/server/settings/publish_plugins.py @@ -21,7 +21,7 @@ class ValidateBaseModel(BaseSettingsModel): class CollectAnatomyInstanceDataModel(BaseSettingsModel): _isGroup = True follow_workfile_version: bool = Field( - True, title="Collect Anatomy Instance Data" + True, title="Follow workfile version" ) From efa9b8fe4c1b22af0aa561f6ea9132687b703f5e Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 6 Nov 2023 18:39:58 +0100 Subject: [PATCH 296/690] Remove unused `instanceToggled` callbacks (#5862) --- openpype/hosts/aftereffects/api/pipeline.py | 10 ---------- openpype/hosts/nuke/api/pipeline.py | 22 --------------------- openpype/hosts/photoshop/api/pipeline.py | 10 ---------- openpype/hosts/tvpaint/api/pipeline.py | 4 ---- 4 files changed, 46 deletions(-) diff --git a/openpype/hosts/aftereffects/api/pipeline.py b/openpype/hosts/aftereffects/api/pipeline.py index 8fc7a70dd8..e059f7c272 100644 --- a/openpype/hosts/aftereffects/api/pipeline.py +++ b/openpype/hosts/aftereffects/api/pipeline.py @@ -74,11 +74,6 @@ class AfterEffectsHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): register_loader_plugin_path(LOAD_PATH) register_creator_plugin_path(CREATE_PATH) - log.info(PUBLISH_PATH) - - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) register_event_callback("application.launched", application_launch) @@ -186,11 +181,6 @@ def application_launch(): check_inventory() -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle layer visibility on instance toggles.""" - instance[0].Visible = new_value - - def ls(): """Yields containers from active AfterEffects document. diff --git a/openpype/hosts/nuke/api/pipeline.py b/openpype/hosts/nuke/api/pipeline.py index f6ba33f00f..ba4d66ab63 100644 --- a/openpype/hosts/nuke/api/pipeline.py +++ b/openpype/hosts/nuke/api/pipeline.py @@ -129,9 +129,6 @@ class NukeHost( register_event_callback("workio.open_file", check_inventory_versions) register_event_callback("taskChanged", change_context_label) - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled) - _install_menu() # add script menu @@ -402,25 +399,6 @@ def add_shortcuts_from_presets(): log.error(e) -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle node passthrough states on instance toggles.""" - - log.info("instance toggle: {}, old_value: {}, new_value:{} ".format( - instance, old_value, new_value)) - - # Whether instances should be passthrough based on new value - - with viewer_update_and_undo_stop(): - n = instance[0] - try: - n["publish"].value() - except ValueError: - n = add_publish_knob(n) - log.info(" `Publish` knob was added to write node..") - - n["publish"].setValue(new_value) - - def containerise(node, name, namespace, diff --git a/openpype/hosts/photoshop/api/pipeline.py b/openpype/hosts/photoshop/api/pipeline.py index 56ae2a4c25..4e0dbcad06 100644 --- a/openpype/hosts/photoshop/api/pipeline.py +++ b/openpype/hosts/photoshop/api/pipeline.py @@ -48,11 +48,6 @@ class PhotoshopHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): pyblish.api.register_plugin_path(PUBLISH_PATH) register_loader_plugin_path(LOAD_PATH) register_creator_plugin_path(CREATE_PATH) - log.info(PUBLISH_PATH) - - pyblish.api.register_callback( - "instanceToggled", on_pyblish_instance_toggled - ) register_event_callback("application.launched", on_application_launch) @@ -177,11 +172,6 @@ def on_application_launch(): check_inventory() -def on_pyblish_instance_toggled(instance, old_value, new_value): - """Toggle layer visibility on instance toggles.""" - instance[0].Visible = new_value - - def ls(): """Yields containers from active Photoshop document diff --git a/openpype/hosts/tvpaint/api/pipeline.py b/openpype/hosts/tvpaint/api/pipeline.py index a84f196f09..c125da1533 100644 --- a/openpype/hosts/tvpaint/api/pipeline.py +++ b/openpype/hosts/tvpaint/api/pipeline.py @@ -84,10 +84,6 @@ class TVPaintHost(HostBase, IWorkfileHost, ILoadHost, IPublishHost): register_loader_plugin_path(load_dir) register_creator_plugin_path(create_dir) - registered_callbacks = ( - pyblish.api.registered_callbacks().get("instanceToggled") or [] - ) - register_event_callback("application.launched", self.initial_launch) register_event_callback("application.exit", self.application_exit) From 3fdccc886f4d8f785c0d9297264b15a6904d496d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 7 Nov 2023 15:46:12 +0800 Subject: [PATCH 297/690] make sure the extraction would be skipped if there is empty list of animated_skeleton --- openpype/hosts/maya/plugins/publish/extract_fbx_animation.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index 8288bc9329..ad9ca385dc 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -42,6 +42,11 @@ class ExtractFBXAnimation(publish.Extractor): # Export from the rig's namespace so that the exported # FBX does not include the namespace but preserves the node # names as existing in the rig workfile + if not out_members: + self.log.debug( + "Top group of animated skeleton not found...skipping extraction") + return + namespace = get_namespace(out_members[0]) relative_out_members = [ strip_namespace(node, namespace) for node in out_members From 69c33f9c8f560c3c92407ae13f471cba36b9790e Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Tue, 7 Nov 2023 15:52:19 +0800 Subject: [PATCH 298/690] hound --- openpype/hosts/maya/plugins/publish/extract_fbx_animation.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index ad9ca385dc..c6f8029e7d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -44,7 +44,8 @@ class ExtractFBXAnimation(publish.Extractor): # names as existing in the rig workfile if not out_members: self.log.debug( - "Top group of animated skeleton not found...skipping extraction") + "Top group of animated skeleton not found.." + "skipping extraction") return namespace = get_namespace(out_members[0]) From 93101debd87d1d72cbeec69f2131f093f06c27a7 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 7 Nov 2023 10:23:55 +0100 Subject: [PATCH 299/690] collect workfile remove unused import and comment --- openpype/hosts/blender/plugins/publish/collect_workfile.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_workfile.py b/openpype/hosts/blender/plugins/publish/collect_workfile.py index e431405e80..01c033084b 100644 --- a/openpype/hosts/blender/plugins/publish/collect_workfile.py +++ b/openpype/hosts/blender/plugins/publish/collect_workfile.py @@ -1,6 +1,5 @@ from pathlib import Path -import bpy from pyblish.api import InstancePlugin, CollectorOrder @@ -30,7 +29,7 @@ class CollectWorkfile(InstancePlugin): { "name": ext.lstrip("."), "ext": ext, - "files": filepath.name, # TODO resources + "files": filepath.name, "stagingDir": filepath.parent, } ], From 7f5986a683299a10d65789cc9ac86362d97262d4 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 11:43:08 +0100 Subject: [PATCH 300/690] fix maya workfile creator --- openpype/hosts/maya/plugins/create/create_workfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/create/create_workfile.py b/openpype/hosts/maya/plugins/create/create_workfile.py index 7282fc6b8b..198f9c4a36 100644 --- a/openpype/hosts/maya/plugins/create/create_workfile.py +++ b/openpype/hosts/maya/plugins/create/create_workfile.py @@ -72,7 +72,10 @@ class CreateWorkfile(plugin.MayaCreatorBase, AutoCreator): ) asset_name = get_asset_name_identifier(asset_doc) - current_instance["asset"] = asset_name + if AYON_SERVER_ENABLED: + current_instance["folderPath"] = asset_name + else: + current_instance["asset"] = asset_name current_instance["task"] = task_name current_instance["subset"] = subset_name From 1e819a26838570aaf93cf89e23adf5f673413a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Je=C5=BEek?= Date: Tue, 7 Nov 2023 13:28:26 +0100 Subject: [PATCH 301/690] Update openpype/hosts/traypublisher/api/editorial.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> --- openpype/hosts/traypublisher/api/editorial.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/traypublisher/api/editorial.py b/openpype/hosts/traypublisher/api/editorial.py index 2f5e709ffc..ddb369468f 100644 --- a/openpype/hosts/traypublisher/api/editorial.py +++ b/openpype/hosts/traypublisher/api/editorial.py @@ -321,7 +321,8 @@ class ShotMetadataSolver: # generate hierarchy path from parents hierarchy_path = self._create_hierarchy_path(parents) - + if hierarchy_path: + hierarchy_path = f"/{hierarchy_path}" return shot_name, { "hierarchy": hierarchy_path, "folderPath": f"{hierarchy_path}/{shot_name}", From ce413045130184c6da299d1f3a4a441a550a146d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 13:29:15 +0100 Subject: [PATCH 302/690] ignore if passed icon definition is None --- openpype/tools/ayon_utils/widgets/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/tools/ayon_utils/widgets/utils.py b/openpype/tools/ayon_utils/widgets/utils.py index 8bc3b1ea9b..2817b5efc0 100644 --- a/openpype/tools/ayon_utils/widgets/utils.py +++ b/openpype/tools/ayon_utils/widgets/utils.py @@ -54,6 +54,8 @@ class _IconsCache: @classmethod def get_icon(cls, icon_def): + if not icon_def: + return None icon_type = icon_def["type"] cache_key = cls._get_cache_key(icon_def) cache = cls._cache.get(cache_key) From 46761a028f6a6c91815f6b8c7705abf706f48380 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 13:31:04 +0100 Subject: [PATCH 303/690] traypublisher: editorial better handling hierarchy for folder path --- openpype/hosts/traypublisher/api/editorial.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/traypublisher/api/editorial.py b/openpype/hosts/traypublisher/api/editorial.py index ddb369468f..1a83fcecbd 100644 --- a/openpype/hosts/traypublisher/api/editorial.py +++ b/openpype/hosts/traypublisher/api/editorial.py @@ -322,10 +322,13 @@ class ShotMetadataSolver: # generate hierarchy path from parents hierarchy_path = self._create_hierarchy_path(parents) if hierarchy_path: - hierarchy_path = f"/{hierarchy_path}" + folder_path = f"/{hierarchy_path}/{shot_name}" + else: + folder_path = f"/{shot_name}" + return shot_name, { "hierarchy": hierarchy_path, - "folderPath": f"{hierarchy_path}/{shot_name}", + "folderPath": folder_path, "parents": parents, "tasks": tasks } From 62af7138e11cc11509b91ec2f1ee7cc1995fb10b Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 13:38:43 +0100 Subject: [PATCH 304/690] traypublisher: editorial ayon attribute only https://github.com/ynput/OpenPype/pull/5873#discussion_r1384655823 --- .../hosts/traypublisher/plugins/create/create_editorial.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 5dc3893697..59f24a2a2b 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -683,13 +683,15 @@ or updating already created. Publishing will create OTIO file. # create creator attributes creator_attributes = { "asset_name": shot_name, - "Folder path": shot_metadata["folderPath"], "Parent hierarchy path": shot_metadata["hierarchy"], "workfile_start_frame": workfile_start_frame, "fps": fps, "handle_start": int(handle_start), "handle_end": int(handle_end) } + if AYON_SERVER_ENABLED: + creator_attributes["folderPath"] = shot_metadata["folderPath"] + creator_attributes.update(timing_data) # create shared new instance data From bf96b15b90e04b0721af853adeb161707ebd5b8c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 13:50:44 +0100 Subject: [PATCH 305/690] center publisher window on first show --- openpype/tools/publisher/window.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openpype/tools/publisher/window.py b/openpype/tools/publisher/window.py index 312cf1dd5c..2416763c27 100644 --- a/openpype/tools/publisher/window.py +++ b/openpype/tools/publisher/window.py @@ -15,6 +15,7 @@ from openpype.tools.utils import ( MessageOverlayObject, PixmapLabel, ) +from openpype.tools.utils.lib import center_window from .constants import ResetKeySequence from .publish_report_viewer import PublishReportViewerWidget @@ -529,6 +530,7 @@ class PublisherWindow(QtWidgets.QDialog): def _on_first_show(self): self.resize(self.default_width, self.default_height) self.setStyleSheet(style.load_stylesheet()) + center_window(self) self._reset_on_show = self._reset_on_first_show def _on_show_timer(self): From 414df2370346aabbb555212f8123bbcb35817ea2 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Tue, 7 Nov 2023 13:07:26 +0000 Subject: [PATCH 306/690] Introduce app_group flag (#5869) --- openpype/cli.py | 7 +++++-- openpype/pype_commands.py | 5 ++++- tests/conftest.py | 10 ++++++++++ tests/lib/testing_classes.py | 9 ++++++--- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/openpype/cli.py b/openpype/cli.py index 7422f32f13..f0fe550a1f 100644 --- a/openpype/cli.py +++ b/openpype/cli.py @@ -282,6 +282,9 @@ def run(script): "--app_variant", help="Provide specific app variant for test, empty for latest", default=None) +@click.option("--app_group", + help="Provide specific app group for test, empty for default", + default=None) @click.option("-t", "--timeout", help="Provide specific timeout value for test case", @@ -294,11 +297,11 @@ def run(script): help="MongoDB for testing.", default=None) def runtests(folder, mark, pyargs, test_data_folder, persist, app_variant, - timeout, setup_only, mongo_url): + timeout, setup_only, mongo_url, app_group): """Run all automatic tests after proper initialization via start.py""" PypeCommands().run_tests(folder, mark, pyargs, test_data_folder, persist, app_variant, timeout, setup_only, - mongo_url) + mongo_url, app_group) @main.command(help="DEPRECATED - run sync server") diff --git a/openpype/pype_commands.py b/openpype/pype_commands.py index 071ecfffd2..b5828d3dfe 100644 --- a/openpype/pype_commands.py +++ b/openpype/pype_commands.py @@ -214,7 +214,7 @@ class PypeCommands: def run_tests(self, folder, mark, pyargs, test_data_folder, persist, app_variant, timeout, setup_only, - mongo_url): + mongo_url, app_group): """ Runs tests from 'folder' @@ -260,6 +260,9 @@ class PypeCommands: if persist: args.extend(["--persist", persist]) + if app_group: + args.extend(["--app_group", app_group]) + if app_variant: args.extend(["--app_variant", app_variant]) diff --git a/tests/conftest.py b/tests/conftest.py index 6e82c9917d..a862030fff 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,6 +14,11 @@ def pytest_addoption(parser): help="True - keep test_db, test_openpype, outputted test files" ) + parser.addoption( + "--app_group", action="store", default=None, + help="Keep empty to use default application or explicit" + ) + parser.addoption( "--app_variant", action="store", default=None, help="Keep empty to locate latest installed variant or explicit" @@ -45,6 +50,11 @@ def persist(request): return request.config.getoption("--persist") +@pytest.fixture(scope="module") +def app_group(request): + return request.config.getoption("--app_group") + + @pytest.fixture(scope="module") def app_variant(request): return request.config.getoption("--app_variant") diff --git a/tests/lib/testing_classes.py b/tests/lib/testing_classes.py index 277b332e19..e8e338e434 100644 --- a/tests/lib/testing_classes.py +++ b/tests/lib/testing_classes.py @@ -248,19 +248,22 @@ class PublishTest(ModuleUnitTest): SETUP_ONLY = False @pytest.fixture(scope="module") - def app_name(self, app_variant): + def app_name(self, app_variant, app_group): """Returns calculated value for ApplicationManager. Eg.(nuke/12-2)""" from openpype.lib import ApplicationManager app_variant = app_variant or self.APP_VARIANT + app_group = app_group or self.APP_GROUP application_manager = ApplicationManager() if not app_variant: variant = ( application_manager.find_latest_available_variant_for_group( - self.APP_GROUP)) + app_group + ) + ) app_variant = variant.name - yield "{}/{}".format(self.APP_GROUP, app_variant) + yield "{}/{}".format(app_group, app_variant) @pytest.fixture(scope="module") def app_args(self, download_test_data): From 82c3442f6192d2f4e26268a89483e55f4cebfbaa Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 14:46:05 +0100 Subject: [PATCH 307/690] convert 'ValidateAttributes' settings only if are available --- openpype/settings/ayon_settings.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index a31c8a04e0..b56249bbc2 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -641,13 +641,14 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_max["PointCloud"]["attribute"] = new_point_cloud_attribute # --- Publish (START) --- ayon_publish = ayon_max["publish"] - try: - attributes = json.loads( - ayon_publish["ValidateAttributes"]["attributes"] - ) - except ValueError: - attributes = {} - ayon_publish["ValidateAttributes"]["attributes"] = attributes + if "ValidateAttributes" in ayon_publish: + try: + attributes = json.loads( + ayon_publish["ValidateAttributes"]["attributes"] + ) + except ValueError: + attributes = {} + ayon_publish["ValidateAttributes"]["attributes"] = attributes output["max"] = ayon_max From e3c28bd55775ebb0d8b1d412dc7155ba0aa8d152 Mon Sep 17 00:00:00 2001 From: Ynbot Date: Tue, 7 Nov 2023 13:46:43 +0000 Subject: [PATCH 308/690] [Automated] Release --- CHANGELOG.md | 457 ++++++++++++++++++++++++++++++++++++++++++++ openpype/version.py | 2 +- pyproject.toml | 2 +- 3 files changed, 459 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7432b33e24..b3daf581ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,463 @@ # Changelog +## [3.17.5](https://github.com/ynput/OpenPype/tree/3.17.5) + + +[Full Changelog](https://github.com/ynput/OpenPype/compare/3.17.4...3.17.5) + +### **🆕 New features** + + +
+Fusion: Add USD loader #4896 + +Add an OpenPype managed USD loader (`uLoader`) for Fusion. + + +___ + +
+ + +
+Fusion: Resolution validator #5325 + +Added a resolution validator.The code is from my old PR (https://github.com/ynput/OpenPype/pull/4921) that I closed because the PR also contained a frame range validator that no longer is needed. + + +___ + +
+ + +
+Context Selection tool: Refactor Context tool (for AYON) #5766 + +Context selection tool has AYON variant. + + +___ + +
+ + +
+AYON: Use AYON username for user in template data #5842 + +Use ayon username for template data in AYON mode. + + +___ + +
+ + +
+Testing: app_group flag #5869 + +`app_group` command flag. This is for changing which flavour of the host to launch. In the case of Maya, you can launch Maya and MayaPy, but it can be used for the Nuke family as well.Split from #5644 + + +___ + +
+ +### **🚀 Enhancements** + + +
+Enhancement: Fusion fix saver creation + minor Blender/Fusion logging tweaks #5558 + +- Blender change logs to `debug` level in preparation for new publisher artist facing reports (note that it currently still uses the old publisher) +- Fusion: Create Saver fix redeclaration of default_variants +- Fusion: Fix saver being created in incorrect state without saving directly after create +- Fusion: Allow reset frame range on render family +- Fusion: Tweak logging level for artist-facing report + + +___ + +
+ + +
+Resolve: load clip to timeline at set time #5665 + +It is possible to load clip to correct place on timeline. + + +___ + +
+ + +
+Nuke: Optional Deadline workfile dependency. #5732 + +Adds option to add the workfile as dependency for the Deadline job.Think it used to have something like this, but it disappeared. Usecase is for remote workflow where the Nuke script needs to be synced before the job can start. + + +___ + +
+ + +
+Enhancement/houdini rearrange ayon houdini settings files #5748 + +Rearranging Houdini Settings to be more readable, easier to edit, update settings (include all families/product types)This PR is mainly for Ayon Settings to have more organized files. For Openpype, I'll make sure that each Houdini setting in Ayon has an equivalent in Openpype. +- [x] update Ayon settings, fix typos and remove deprecated settings. +- [x] Sync with Openpype +- [x] Test in Openpype +- [x] Test in Ayon + + +___ + +
+ + +
+Chore: updating create ayon addon script #5822 + +Adding developers environment options. + + +___ + +
+ + +
+Max: Implement Validator for Properties/Attributes Value Check #5824 + +Add optional validator which can check if the property attributes are valid in Max + + +___ + +
+ + +
+Nuke: Remove unused 'get_render_path' function #5826 + +Remove unused function `get_render_path` from nuke integration. + + +___ + +
+ + +
+Chore: Limit current context template data function #5845 + +Current implementation of `get_current_context_template_data` does return the same values as base template data function `get_template_data`. + + +___ + +
+ + +
+Max: Make sure Collect Render not ignoring instance asset #5847 + +- Make sure Collect Render is not always using asset from context. +- Make sure Scene version being collected +- Clean up unnecessary uses of code in the collector. + + +___ + +
+ + +
+Ftrack: Events are not processed if project is not available in OpenPype #5853 + +Events that happened on project which is not in OpenPype is not processed. + + +___ + +
+ + +
+Nuke: Add Nuke 11.0 as default setting #5855 + +Found I needed Nuke 11.0 in the default settings to help with unit testing. + + +___ + +
+ + +
+TVPaint: Code cleanup #5857 + +Removed unused import. Use `AYON` label in ayon mode. Removed unused data in publish context `"previous_context"`. + + +___ + +
+ + +
+AYON settings: Use correct label for follow workfile version #5874 + +Follow workfile version label was marked as Collect Anatomy Instance Data label. + + +___ + +
+ +### **🐛 Bug fixes** + + +
+Nuke: Fix workfile template builder so representations get loaded next to each other #5061 + +Refactor when the cleanup of the placeholder happens for the cases where multiple representations are loaded by a single placeholder.The existing code didn't take into account the case where a template placeholder can load multiple representations so it was trying to do the cleanup of the placeholder node and the re-arrangement of the imported nodes too early. I assume this was designed only for the cases where a single representation can load multiple nodes. + + +___ + +
+ + +
+Nuke: Dont update node name on update #5704 + +When updating `Image` containers the code is trying to set the name of the node. This results in a warning message from Nuke shown below;Suggesting to not change the node name when updating. + + +___ + +
+ + +
+UIDefLabel can be unique #5827 + +`UILabelDef` have implemented comparison and uniqueness. + + +___ + +
+ + +
+AYON: Skip kitsu module when creating ayon addons #5828 + +Create AYON packages is skipping kitsu module in creation of modules/addons and kitsu module is not loaded from modules on start. The addon already has it's repository https://github.com/ynput/ayon-kitsu. + + +___ + +
+ + +
+Bugfix: Collect Rendered Files only collecting first instance #5832 + +Collect all instances from the metadata file - don't return on first instance iteration. + + +___ + +
+ + +
+Houdini: set frame range for the created composite ROP #5833 + +Quick bug fix for created composite ROP, set its frame range to the frame range of the playbar. + + +___ + +
+ + +
+Fix registering launcher actions from OpenPypeModules #5843 + +Fix typo `actions_dir` -> `path` to fix register launcher actions fromm OpenPypeModule + + +___ + +
+ + +
+Bugfix in houdini shelves manager and beautify settings #5844 + +This PR fixes the problem in this PR https://github.com/ynput/OpenPype/issues/5457 by using the right function to load a pre-made houdini `.shelf` fileAlso, it beautifies houdini shelves settings to provide better guidance for users which helps with other issue https://github.com/ynput/OpenPype/issues/5458 , Rather adding default shelf and set names, I'll educate users how to use the tool correctly.Users now are able to select between the two options.| OpenPype | Ayon || -- | -- || | | + + +___ + +
+ + +
+Blender: Fix missing Grease Pencils in review #5848 + +Fix Grease Pencil missing in review when isolating objects. + + +___ + +
+ + +
+Blender: Fix Render Settings in Ayon #5849 + +Fix Render Settings in Ayon for Blender. + + +___ + +
+ + +
+Bugfix: houdini tab menu working as expected #5850 + +This PR:Tab menu name changes to Ayon when using ayon get_network_categories is checked in all creator plugins. | Product | Network Category | | -- | -- | | Alembic camera | rop, obj | | Arnold Ass | rop | | Arnold ROP | rop | | Bgeo | rop, sop | | composite sequence | cop2, rop | | hda | obj | | Karma ROP | rop | | Mantra ROP | rop | | ABC | rop, sop | | RS proxy | rop, sop| | RS ROP | rop | | Review | rop | | Static mesh | rop, obj, sop | | USD | lop, rop | | USD Render | rop | | VDB | rop, obj, sop | | V Ray | rop | + + +___ + +
+ + +
+Bigfix: Houdini skip frame_range_validator if node has no 'trange' parameter #5851 + +I faced a bug when publishing HDA instance as it has no `trange` parameter. As this PR title says : skip frame_range_validator if node has no 'trange' parameter + + +___ + +
+ + +
+Bugfix: houdini image sequence loading and missing frames #5852 + +I made this PR in to fix issues mentioned here https://github.com/ynput/OpenPype/pull/5833#issuecomment-1789207727in short: +- image load doesn't work +- publisher only publish one frame + + +___ + +
+ + +
+Nuke: loaders' containers updating as nodes #5854 + +Nuke loaded containers are updating correctly even they have been duplicating of originally loaded nodes. This had previously been removed duplicated nodes. + + +___ + +
+ + +
+deadline: settings are not blocking extension input #5864 + +Settings are not blocking user input. + + +___ + +
+ + +
+Blender: Fix loading of blend layouts #5866 + +Fix a problem with loading blend layouts. + + +___ + +
+ + +
+AYON: Launcher refresh issues #5867 + +Fixed refresh of projects issue in launcher tool. And renamed Qt models to contain `Qt` in their name (it was really hard to find out where were used). It is not possible to click on disabled item in launcher's projects view. + + +___ + +
+ + +
+Fix the Wrong key words for tycache workfile template settings in AYON #5870 + +Fix the wrong key words for the tycache workfile template settings in AYON(i.e. Instead of families, product_types should be used) + + +___ + +
+ + +
+AYON tools: Handle empty icon definition #5876 + +Ignore if passed icon definition is `None`. + + +___ + +
+ +### **🔀 Refactored code** + + +
+Houdini: Remove on instance toggled callback #5860 + +Remove on instance toggled callback which isn't relevant to the new publisher + + +___ + +
+ + +
+Chore: Remove unused `instanceToggled` callbacks #5862 + +The `instanceToggled` callbacks should be irrelevant for new publisher. + + +___ + +
+ + + + ## [3.17.4](https://github.com/ynput/OpenPype/tree/3.17.4) diff --git a/openpype/version.py b/openpype/version.py index c6ebd65e9c..9832c77291 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.17.5-nightly.3" +__version__ = "3.17.5" diff --git a/pyproject.toml b/pyproject.toml index 633dafece1..c6f4880cdd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "OpenPype" -version = "3.17.4" # OpenPype +version = "3.17.5" # OpenPype description = "Open VFX and Animation pipeline with support." authors = ["OpenPype Team "] license = "MIT License" From 246a4af3ef2185b2ad924bd89c8b4f2bd4404678 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 7 Nov 2023 13:47:43 +0000 Subject: [PATCH 309/690] chore(): update bug report / version --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7a1fe9d83e..bdfc2ad46f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,6 +35,7 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.17.5 - 3.17.5-nightly.3 - 3.17.5-nightly.2 - 3.17.5-nightly.1 @@ -134,7 +135,6 @@ body: - 3.15.1-nightly.6 - 3.15.1-nightly.5 - 3.15.1-nightly.4 - - 3.15.1-nightly.3 validations: required: true - type: dropdown From 7aa5b09ef26dd2da96cccb0eb28d79a6e3d20844 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 14:56:46 +0100 Subject: [PATCH 310/690] improving code --- openpype/hosts/traypublisher/api/editorial.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openpype/hosts/traypublisher/api/editorial.py b/openpype/hosts/traypublisher/api/editorial.py index 1a83fcecbd..613f1de768 100644 --- a/openpype/hosts/traypublisher/api/editorial.py +++ b/openpype/hosts/traypublisher/api/editorial.py @@ -53,11 +53,11 @@ class ShotMetadataSolver: try: # format to new shot name return shot_rename_template.format(**data) - except KeyError as _E: + except KeyError as _error: raise CreatorError(( "Make sure all keys in settings are correct:: \n\n" f"From template string {shot_rename_template} > " - f"`{_E}` has no equivalent in \n" + f"`{_error}` has no equivalent in \n" f"{list(data.keys())} input formatting keys!" )) @@ -100,7 +100,7 @@ class ShotMetadataSolver: "at your project settings..." )) - # QUESTION:how to refactory `match[-1]` to some better way? + # QUESTION:how to refactor `match[-1]` to some better way? output_data[token_key] = match[-1] return output_data @@ -130,10 +130,10 @@ class ShotMetadataSolver: parent_token["name"]: parent_token["value"].format(**data) for parent_token in hierarchy_parents } - except KeyError as _E: + except KeyError as _error: raise CreatorError(( "Make sure all keys in settings are correct : \n" - f"`{_E}` has no equivalent in \n{list(data.keys())}" + f"`{_error}` has no equivalent in \n{list(data.keys())}" )) _parent_tokens_type = { @@ -147,10 +147,10 @@ class ShotMetadataSolver: try: parent_name = _parent.format( **_parent_tokens_formatting_data) - except KeyError as _E: + except KeyError as _error: raise CreatorError(( "Make sure all keys in settings are correct : \n\n" - f"`{_E}` from template string " + f"`{_error}` from template string " f"{shot_hierarchy['parents_path']}, " f" has no equivalent in \n" f"{list(_parent_tokens_formatting_data.keys())} parents" From 638c1c65e78cdf4fc9327820a265878f0a5e13a6 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 14:57:44 +0100 Subject: [PATCH 311/690] ayon distributed folder path from create to publish --- .../plugins/create/create_editorial.py | 69 +++++++++++-------- .../plugins/publish/collect_shot_instances.py | 8 ++- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 59f24a2a2b..8c5083bcb2 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -102,14 +102,23 @@ class EditorialShotInstanceCreator(EditorialClipInstanceCreatorBase): label = "Editorial Shot" def get_instance_attr_defs(self): - attr_defs = [ - TextDef( - "asset_name", - label="Asset name", + instance_attributes = [] + if AYON_SERVER_ENABLED: + instance_attributes.append( + TextDef( + "folderPath", + label="Folder path" + ) ) - ] - attr_defs.extend(CLIP_ATTR_DEFS) - return attr_defs + else: + instance_attributes.append( + TextDef( + "shotName", + label="Shot name" + ) + ) + instance_attributes.extend(CLIP_ATTR_DEFS) + return instance_attributes class EditorialPlateInstanceCreator(EditorialClipInstanceCreatorBase): @@ -216,10 +225,7 @@ or updating already created. Publishing will create OTIO file. ] } # Create otio editorial instance - if AYON_SERVER_ENABLED: - asset_name = instance_data.pop("folderPath") - else: - asset_name = instance_data["asset"] + asset_name = instance_data["asset"] asset_doc = get_asset_by_name(self.project_name, asset_name) @@ -671,7 +677,10 @@ or updating already created. Publishing will create OTIO file. } ) - self._validate_name_uniqueness(shot_name) + # It should be validated only in openpype since we are supporting + # publishing to AYON with folder path and uniqueness is not an issue + if not AYON_SERVER_ENABLED: + self._validate_name_uniqueness(shot_name) timing_data = self._get_timing_data( otio_clip, @@ -682,36 +691,42 @@ or updating already created. Publishing will create OTIO file. # create creator attributes creator_attributes = { - "asset_name": shot_name, - "Parent hierarchy path": shot_metadata["hierarchy"], + "workfile_start_frame": workfile_start_frame, "fps": fps, "handle_start": int(handle_start), "handle_end": int(handle_end) } - if AYON_SERVER_ENABLED: - creator_attributes["folderPath"] = shot_metadata["folderPath"] - + # add timing data creator_attributes.update(timing_data) - # create shared new instance data + # create base instance data base_instance_data = { "shotName": shot_name, "variant": variant_name, - - # HACK: just for temporal bug workaround - # TODO: should loockup shot name for update - "asset": parent_asset_name, "task": "", - "newAssetPublishing": True, - - # parent time properties "trackStartFrame": track_start_frame, "timelineOffset": timeline_offset, - # creator_attributes - "creator_attributes": creator_attributes } + # update base instance data with context data + # and also update creator attributes with context data + if AYON_SERVER_ENABLED: + # TODO: this is here just to be able to publish + # to AYON with folder path + creator_attributes["folderPath"] = shot_metadata.pop("folderPath") + base_instance_data["folderPath"] = parent_asset_name + else: + creator_attributes.update({ + "shotName": shot_name, + "Parent hierarchy path": shot_metadata["hierarchy"] + }) + + base_instance_data["asset"] = parent_asset_name + + + # add creator attributes to shared instance data + base_instance_data["creator_attributes"] = creator_attributes # add hierarchy shot metadata base_instance_data.update(shot_metadata) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py index b08397caf7..65dd35782f 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -2,6 +2,8 @@ from pprint import pformat import pyblish.api import opentimelineio as otio +from openpype import AYON_SERVER_ENABLED + class CollectShotInstance(pyblish.api.InstancePlugin): """ Collect shot instances @@ -119,7 +121,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): frame_end = _cr_attrs["frameEnd"] frame_dur = frame_end - frame_start - return { + data = { "fps": float(_cr_attrs["fps"]), "handleStart": _cr_attrs["handle_start"], "handleEnd": _cr_attrs["handle_end"], @@ -132,6 +134,10 @@ class CollectShotInstance(pyblish.api.InstancePlugin): "sourceOut": _cr_attrs["sourceOut"], "workfileFrameStart": workfile_start_frame } + if AYON_SERVER_ENABLED: + data["asset"] = _cr_attrs["asset"] + + return data def _solve_hierarchy_context(self, instance): """ Adding hierarchy data to context shared data. From cf356e7ecd66521f91996024bac4e911a4ce09ac Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Tue, 7 Nov 2023 16:00:50 +0100 Subject: [PATCH 312/690] add create render identifier --- openpype/hosts/blender/plugins/create/create_render.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/create/create_render.py b/openpype/hosts/blender/plugins/create/create_render.py index 45570f3491..e036ae7df3 100644 --- a/openpype/hosts/blender/plugins/create/create_render.py +++ b/openpype/hosts/blender/plugins/create/create_render.py @@ -13,6 +13,7 @@ from openpype.hosts.blender.api.pipeline import ( class CreateRenderlayer(plugin.BaseCreator): """Single baked camera""" + identifier = "io.openpype.creators.blender.render" name = "renderingMain" label = "Render" family = "render" @@ -28,8 +29,7 @@ class CreateRenderlayer(plugin.BaseCreator): bpy.context.scene.collection.children.link(instances) # Create instance object - asset = instance_data.get("asset") - name = plugin.asset_name(asset, subset_name) + name = plugin.asset_name(instance_data.get("asset"), subset_name) asset_group = bpy.data.collections.new(name=name) try: From 44578b2121f1eee9fa6daca3e72dac047f41ebf2 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 16:15:16 +0100 Subject: [PATCH 313/690] traypublisher: editorial collector asset to instance with ayon exception for folderPath --- .../traypublisher/plugins/publish/collect_shot_instances.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py index 65dd35782f..0b7e022658 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -135,7 +135,9 @@ class CollectShotInstance(pyblish.api.InstancePlugin): "workfileFrameStart": workfile_start_frame } if AYON_SERVER_ENABLED: - data["asset"] = _cr_attrs["asset"] + data["asset"] = _cr_attrs["folderPath"] + else: + data["asset"] = _cr_attrs["shotName"] return data From f3370c0229da5ff9c323a7277f8711122b25a4b7 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Tue, 7 Nov 2023 15:21:10 +0000 Subject: [PATCH 314/690] Changed how extractors name the output files --- openpype/hosts/blender/plugins/publish/extract_abc.py | 9 ++++++--- .../blender/plugins/publish/extract_abc_animation.py | 10 +++++++--- .../hosts/blender/plugins/publish/extract_blend.py | 9 ++++++--- .../plugins/publish/extract_blend_animation.py | 9 ++++++--- .../blender/plugins/publish/extract_camera_abc.py | 9 ++++++--- .../blender/plugins/publish/extract_camera_fbx.py | 9 ++++++--- openpype/hosts/blender/plugins/publish/extract_fbx.py | 9 ++++++--- .../blender/plugins/publish/extract_fbx_animation.py | 11 +++++++---- .../hosts/blender/plugins/publish/extract_layout.py | 10 +++++++--- .../blender/plugins/publish/extract_playblast.py | 5 ++++- .../blender/plugins/publish/extract_thumbnail.py | 5 ++++- 11 files changed, 65 insertions(+), 30 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_abc.py b/openpype/hosts/blender/plugins/publish/extract_abc.py index b17d7cc6e4..59035d8f61 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc.py @@ -17,7 +17,10 @@ class ExtractABC(publish.Extractor): def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.abc" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.abc" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -59,8 +62,8 @@ class ExtractABC(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") class ExtractModelABC(ExtractABC): diff --git a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py index 6866b05fea..0ac6f12de5 100644 --- a/openpype/hosts/blender/plugins/publish/extract_abc_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_abc_animation.py @@ -17,7 +17,11 @@ class ExtractAnimationABC(publish.Extractor): def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.abc" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.abc" + filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -66,5 +70,5 @@ class ExtractAnimationABC(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index c8eeef7fd7..0a9fb74f7b 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -17,7 +17,10 @@ class ExtractBlend(publish.Extractor): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.blend" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.blend" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -52,5 +55,5 @@ class ExtractBlend(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py index 661cecce81..3d36ee7ec3 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend_animation.py @@ -17,7 +17,10 @@ class ExtractBlendAnimation(publish.Extractor): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.blend" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.blend" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -50,5 +53,5 @@ class ExtractBlendAnimation(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py index 5916564ac0..b6b38b41ff 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_abc.py @@ -18,7 +18,10 @@ class ExtractCameraABC(publish.Extractor): def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.abc" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.abc" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -64,5 +67,5 @@ class ExtractCameraABC(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py index a541f5b375..be9f178d1b 100644 --- a/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_camera_fbx.py @@ -17,7 +17,10 @@ class ExtractCamera(publish.Extractor): def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.fbx" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.fbx" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -73,5 +76,5 @@ class ExtractCamera(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx.py b/openpype/hosts/blender/plugins/publish/extract_fbx.py index f2ce117dcd..c21dc35ff6 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx.py @@ -18,7 +18,10 @@ class ExtractFBX(publish.Extractor): def process(self, instance): # Define extract output file path stagingdir = self.staging_dir(instance) - filename = f"{instance.name}.fbx" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + filename = f"{instance_name}.fbx" filepath = os.path.join(stagingdir, filename) # Perform extraction @@ -84,5 +87,5 @@ class ExtractFBX(publish.Extractor): } instance.data["representations"].append(representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py index 5fe5931e65..ed4e7ecc6a 100644 --- a/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/blender/plugins/publish/extract_fbx_animation.py @@ -86,7 +86,10 @@ class ExtractAnimationFBX(publish.Extractor): asset_group.select_set(True) armature.select_set(True) - fbx_filename = f"{instance.name}_{armature.name}.fbx" + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + fbx_filename = f"{instance_name}_{armature.name}.fbx" filepath = os.path.join(stagingdir, fbx_filename) override = plugin.create_blender_context( @@ -119,7 +122,7 @@ class ExtractAnimationFBX(publish.Extractor): pair[1].user_clear() bpy.data.actions.remove(pair[1]) - json_filename = f"{instance.name}.json" + json_filename = f"{instance_name}.json" json_path = os.path.join(stagingdir, json_filename) json_dict = { @@ -158,5 +161,5 @@ class ExtractAnimationFBX(publish.Extractor): instance.data["representations"].append(fbx_representation) instance.data["representations"].append(json_representation) - self.log.info("Extracted instance '{}' to: {}".format( - instance.name, fbx_representation)) + self.log.info( + f"Extracted instance '{instance_name}' to: {fbx_representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_layout.py b/openpype/hosts/blender/plugins/publish/extract_layout.py index 05f86b8370..8e820ee84e 100644 --- a/openpype/hosts/blender/plugins/publish/extract_layout.py +++ b/openpype/hosts/blender/plugins/publish/extract_layout.py @@ -212,7 +212,11 @@ class ExtractLayout(publish.Extractor): json_data.append(json_element) - json_filename = "{}.json".format(instance.name) + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + instance_name = f"{asset_name}_{subset}" + json_filename = f"{instance_name}.json" + json_path = os.path.join(stagingdir, json_filename) with open(json_path, "w+") as file: @@ -245,5 +249,5 @@ class ExtractLayout(publish.Extractor): } instance.data["representations"].append(fbx_representation) - self.log.info("Extracted instance '%s' to: %s", - instance.name, json_representation) + self.log.info( + f"Extracted instance '{instance_name}' to: {json_representation}") diff --git a/openpype/hosts/blender/plugins/publish/extract_playblast.py b/openpype/hosts/blender/plugins/publish/extract_playblast.py index b0099cce85..805aacc5f4 100644 --- a/openpype/hosts/blender/plugins/publish/extract_playblast.py +++ b/openpype/hosts/blender/plugins/publish/extract_playblast.py @@ -50,7 +50,10 @@ class ExtractPlayblast(publish.Extractor): # get output path stagingdir = self.staging_dir(instance) - filename = instance.name + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + filename = f"{asset_name}_{subset}" + path = os.path.join(stagingdir, filename) self.log.debug(f"Outputting images to {path}") diff --git a/openpype/hosts/blender/plugins/publish/extract_thumbnail.py b/openpype/hosts/blender/plugins/publish/extract_thumbnail.py index 52e5d98fc4..e8a9c68dd1 100644 --- a/openpype/hosts/blender/plugins/publish/extract_thumbnail.py +++ b/openpype/hosts/blender/plugins/publish/extract_thumbnail.py @@ -27,7 +27,10 @@ class ExtractThumbnail(publish.Extractor): self.log.debug("Extracting capture..") stagingdir = self.staging_dir(instance) - filename = instance.name + asset_name = instance.data["assetEntity"]["name"] + subset = instance.data["subset"] + filename = f"{asset_name}_{subset}" + path = os.path.join(stagingdir, filename) self.log.debug(f"Outputting images to {path}") From f7d76617c0ea5635f9ae8ad0e6a18454da24c2be Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Tue, 7 Nov 2023 15:51:54 +0000 Subject: [PATCH 315/690] Testing: Validate Maya Logs (#5775) * Working version * Improve launched app communication * Move imports to methods. * Update tests/integration/hosts/maya/test_publish_in_maya.py Co-authored-by: Roy Nieterau * Collect errors from process * fix startup scripts arguments * Update openpype/lib/applications.py Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> * Fix application polling * Docstring * Revert stdout and stderr * Revert subprocess.PIPE * Added missed imports If we are moving these because of testing, lets move all of them --------- Co-authored-by: Roy Nieterau Co-authored-by: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Co-authored-by: kalisp --- openpype/hosts/maya/api/lib_rendersettings.py | 6 ++-- .../collect_deadline_server_from_instance.py | 5 ++-- .../publish/submit_blender_deadline.py | 5 ++-- .../publish/submit_houdini_remote_publish.py | 3 +- .../publish/submit_houdini_render_deadline.py | 5 ++-- .../plugins/publish/submit_max_deadline.py | 14 +++++---- .../plugins/publish/submit_maya_deadline.py | 8 ++--- .../submit_maya_remote_publish_deadline.py | 5 ++-- .../plugins/publish/submit_nuke_deadline.py | 5 ++-- .../publish/collect_otio_frame_ranges.py | 18 +++++++----- .../plugins/publish/collect_otio_review.py | 7 +++-- .../publish/collect_otio_subset_resources.py | 17 ++++++----- .../publish/extract_otio_audio_tracks.py | 8 +++-- openpype/plugins/publish/extract_otio_file.py | 5 +++- .../plugins/publish/extract_otio_review.py | 24 ++++++++++----- .../publish/extract_otio_trimming_video.py | 3 +- tests/integration/hosts/maya/lib.py | 7 ++++- .../hosts/maya/test_publish_in_maya.py | 29 +++++++++++++++++++ tests/lib/testing_classes.py | 3 +- 19 files changed, 121 insertions(+), 56 deletions(-) diff --git a/openpype/hosts/maya/api/lib_rendersettings.py b/openpype/hosts/maya/api/lib_rendersettings.py index 42cf29d0a7..20264c2cdf 100644 --- a/openpype/hosts/maya/api/lib_rendersettings.py +++ b/openpype/hosts/maya/api/lib_rendersettings.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- """Class for handling Render Settings.""" -from maya import cmds # noqa -import maya.mel as mel import six import sys @@ -63,6 +61,10 @@ class RenderSettings(object): def set_default_renderer_settings(self, renderer=None): """Set basic settings based on renderer.""" + # Not all hosts can import this module. + from maya import cmds + import maya.mel as mel + if not renderer: renderer = cmds.getAttr( 'defaultRenderGlobals.currentRenderer').lower() diff --git a/openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py b/openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py index 9b4f89c129..1d3dad769f 100644 --- a/openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py +++ b/openpype/modules/deadline/plugins/publish/collect_deadline_server_from_instance.py @@ -5,8 +5,6 @@ This is resolving index of server lists stored in `deadlineServers` instance attribute or using default server if that attribute doesn't exists. """ -from maya import cmds - import pyblish.api from openpype.pipeline.publish import KnownPublishError @@ -44,7 +42,8 @@ class CollectDeadlineServerFromInstance(pyblish.api.InstancePlugin): str: Selected Deadline Webservice URL. """ - + # Not all hosts can import this module. + from maya import cmds deadline_settings = ( render_instance.context.data ["system_settings"] diff --git a/openpype/modules/deadline/plugins/publish/submit_blender_deadline.py b/openpype/modules/deadline/plugins/publish/submit_blender_deadline.py index 4a7497b075..094f2b1821 100644 --- a/openpype/modules/deadline/plugins/publish/submit_blender_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_blender_deadline.py @@ -6,8 +6,6 @@ import getpass import attr from datetime import datetime -import bpy - from openpype.lib import is_running_from_build from openpype.pipeline import legacy_io from openpype.pipeline.farm.tools import iter_expected_files @@ -142,6 +140,9 @@ class BlenderSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): return job_info def get_plugin_info(self): + # Not all hosts can import this module. + import bpy + plugin_info = BlenderPluginInfo( SceneFile=self.scene_path, Version=bpy.app.version_string, diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_remote_publish.py b/openpype/modules/deadline/plugins/publish/submit_houdini_remote_publish.py index 39c0c3afe4..0bee42c4cb 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_remote_publish.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_remote_publish.py @@ -3,7 +3,6 @@ import json from datetime import datetime import requests -import hou import pyblish.api @@ -31,6 +30,8 @@ class HoudiniSubmitPublishDeadline(pyblish.api.ContextPlugin): targets = ["deadline"] def process(self, context): + # Not all hosts can import this module. + import hou # Ensure no errors so far assert all( diff --git a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py index 6f885c578a..abc650204b 100644 --- a/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_houdini_render_deadline.py @@ -1,9 +1,8 @@ -import hou - import os import attr import getpass from datetime import datetime + import pyblish.api from openpype.pipeline import legacy_io @@ -119,6 +118,8 @@ class HoudiniSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline): return job_info def get_plugin_info(self): + # Not all hosts can import this module. + import hou instance = self._instance context = instance.context diff --git a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py index 073da3019a..23d4183132 100644 --- a/openpype/modules/deadline/plugins/publish/submit_max_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_max_deadline.py @@ -1,8 +1,8 @@ import os import getpass import copy - import attr + from openpype.lib import ( TextDef, BoolDef, @@ -15,11 +15,6 @@ from openpype.pipeline import ( from openpype.pipeline.publish.lib import ( replace_with_published_scene_path ) -from openpype.hosts.max.api.lib import ( - get_current_renderer, - get_multipass_setting -) -from openpype.hosts.max.api.lib_rendersettings import RenderSettings from openpype_modules.deadline import abstract_submit_deadline from openpype_modules.deadline.abstract_submit_deadline import DeadlineJobInfo from openpype.lib import is_running_from_build @@ -191,6 +186,13 @@ class MaxSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, self.submit(self.assemble_payload(job_info, plugin_info)) def _use_published_name(self, data, project_settings): + # Not all hosts can import these modules. + from openpype.hosts.max.api.lib import ( + get_current_renderer, + get_multipass_setting + ) + from openpype.hosts.max.api.lib_rendersettings import RenderSettings + instance = self._instance job_info = copy.deepcopy(self.job_info) plugin_info = copy.deepcopy(self.plugin_info) diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py index 7775191b12..7d532923ff 100644 --- a/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_maya_deadline.py @@ -28,8 +28,6 @@ from collections import OrderedDict import attr -from maya import cmds - from openpype.pipeline import ( legacy_io, OpenPypePyblishPluginMixin @@ -246,6 +244,8 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, return job_info def get_plugin_info(self): + # Not all hosts can import this module. + from maya import cmds instance = self._instance context = instance.context @@ -288,7 +288,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, return plugin_payload def process_submission(self): - + from maya import cmds instance = self._instance filepath = self.scene_path # publish if `use_publish` else workfile @@ -675,7 +675,7 @@ class MayaSubmitDeadline(abstract_submit_deadline.AbstractSubmitDeadline, str """ - + from maya import cmds # "vrayscene//_/" vray_settings = cmds.ls(type="VRaySettingsNode") node = vray_settings[0] diff --git a/openpype/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py b/openpype/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py index 0d23f44333..41a2a64ab5 100644 --- a/openpype/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_maya_remote_publish_deadline.py @@ -2,8 +2,6 @@ import os import attr from datetime import datetime -from maya import cmds - from openpype import AYON_SERVER_ENABLED from openpype.pipeline import legacy_io, PublishXmlValidationError from openpype.tests.lib import is_in_tests @@ -127,7 +125,8 @@ class MayaSubmitRemotePublishDeadline( job_info.EnvironmentKeyValue[key] = value def get_plugin_info(self): - + # Not all hosts can import this module. + from maya import cmds scene = self._instance.context.data["currentFile"] plugin_info = MayaPluginInfo() diff --git a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py index 0e57c54959..fb3ab2710d 100644 --- a/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py +++ b/openpype/modules/deadline/plugins/publish/submit_nuke_deadline.py @@ -7,8 +7,6 @@ from datetime import datetime import requests import pyblish.api -import nuke - from openpype import AYON_SERVER_ENABLED from openpype.pipeline import legacy_io from openpype.pipeline.publish import ( @@ -498,6 +496,9 @@ class NukeSubmitDeadline(pyblish.api.InstancePlugin, Returning: list: captured groups list """ + # Not all hosts can import this module. + import nuke + captured_groups = [] for lg_name, list_node_class in self.limit_groups.items(): for node_class in list_node_class: diff --git a/openpype/plugins/publish/collect_otio_frame_ranges.py b/openpype/plugins/publish/collect_otio_frame_ranges.py index 9a68b6e43d..4b130b0e03 100644 --- a/openpype/plugins/publish/collect_otio_frame_ranges.py +++ b/openpype/plugins/publish/collect_otio_frame_ranges.py @@ -5,15 +5,9 @@ Requires: masterLayer -> instance data attribute otioClipRange -> instance data attribute """ -# import os -import opentimelineio as otio -import pyblish.api from pprint import pformat -from openpype.pipeline.editorial import ( - get_media_range_with_retimes, - otio_range_to_frame_range, - otio_range_with_handles -) + +import pyblish.api class CollectOtioFrameRanges(pyblish.api.InstancePlugin): @@ -27,6 +21,14 @@ class CollectOtioFrameRanges(pyblish.api.InstancePlugin): hosts = ["resolve", "hiero", "flame", "traypublisher"] def process(self, instance): + # Not all hosts can import these modules. + import opentimelineio as otio + from openpype.pipeline.editorial import ( + get_media_range_with_retimes, + otio_range_to_frame_range, + otio_range_with_handles + ) + # get basic variables otio_clip = instance.data["otioClip"] workfile_start = instance.data["workfileFrameStart"] diff --git a/openpype/plugins/publish/collect_otio_review.py b/openpype/plugins/publish/collect_otio_review.py index f0157282a1..0e4d596213 100644 --- a/openpype/plugins/publish/collect_otio_review.py +++ b/openpype/plugins/publish/collect_otio_review.py @@ -11,10 +11,10 @@ Provides: instance -> families (adding ["review", "ftrack"]) """ -import opentimelineio as otio -import pyblish.api from pprint import pformat +import pyblish.api + class CollectOtioReview(pyblish.api.InstancePlugin): """Get matching otio track from defined review layer""" @@ -25,6 +25,9 @@ class CollectOtioReview(pyblish.api.InstancePlugin): hosts = ["resolve", "hiero", "flame"] def process(self, instance): + # Not all hosts can import this module. + import opentimelineio as otio + # get basic variables otio_review_clips = [] otio_timeline = instance.context.data["otioTimeline"] diff --git a/openpype/plugins/publish/collect_otio_subset_resources.py b/openpype/plugins/publish/collect_otio_subset_resources.py index f659791d95..739f5bb726 100644 --- a/openpype/plugins/publish/collect_otio_subset_resources.py +++ b/openpype/plugins/publish/collect_otio_subset_resources.py @@ -6,18 +6,15 @@ Provides: instance -> otioReviewClips """ import os + import clique -import opentimelineio as otio import pyblish.api -from openpype.pipeline.editorial import ( - get_media_range_with_retimes, - range_from_frames, - make_sequence_collection -) + from openpype.pipeline.publish import ( get_publish_template_name ) + class CollectOtioSubsetResources(pyblish.api.InstancePlugin): """Get Resources for a subset version""" @@ -26,8 +23,14 @@ class CollectOtioSubsetResources(pyblish.api.InstancePlugin): families = ["clip"] hosts = ["resolve", "hiero", "flame"] - def process(self, instance): + # Not all hosts can import these modules. + import opentimelineio as otio + from openpype.pipeline.editorial import ( + get_media_range_with_retimes, + range_from_frames, + make_sequence_collection + ) if "audio" in instance.data["family"]: return diff --git a/openpype/plugins/publish/extract_otio_audio_tracks.py b/openpype/plugins/publish/extract_otio_audio_tracks.py index 4f17731452..4b73321f02 100644 --- a/openpype/plugins/publish/extract_otio_audio_tracks.py +++ b/openpype/plugins/publish/extract_otio_audio_tracks.py @@ -1,11 +1,12 @@ import os +import tempfile + import pyblish + from openpype.lib import ( get_ffmpeg_tool_args, run_subprocess ) -import tempfile -import opentimelineio as otio class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): @@ -155,6 +156,9 @@ class ExtractOtioAudioTracks(pyblish.api.ContextPlugin): Returns: list: list of audio clip dictionaries """ + # Not all hosts can import this module. + import opentimelineio as otio + output = [] # go trough all audio tracks for otio_track in otio_timeline.tracks: diff --git a/openpype/plugins/publish/extract_otio_file.py b/openpype/plugins/publish/extract_otio_file.py index 1a6a82117d..7f1cac33d7 100644 --- a/openpype/plugins/publish/extract_otio_file.py +++ b/openpype/plugins/publish/extract_otio_file.py @@ -1,6 +1,6 @@ import os + import pyblish.api -import opentimelineio as otio from openpype.pipeline import publish @@ -16,6 +16,9 @@ class ExtractOTIOFile(publish.Extractor): hosts = ["resolve", "hiero", "traypublisher"] def process(self, instance): + # Not all hosts can import this module. + import opentimelineio as otio + if not instance.context.data.get("otioTimeline"): return # create representation data diff --git a/openpype/plugins/publish/extract_otio_review.py b/openpype/plugins/publish/extract_otio_review.py index 699207df8a..ad4c807091 100644 --- a/openpype/plugins/publish/extract_otio_review.py +++ b/openpype/plugins/publish/extract_otio_review.py @@ -15,8 +15,8 @@ Provides: """ import os + import clique -import opentimelineio as otio from pyblish import api from openpype.lib import ( @@ -24,13 +24,6 @@ from openpype.lib import ( run_subprocess, ) from openpype.pipeline import publish -from openpype.pipeline.editorial import ( - otio_range_to_frame_range, - trim_media_range, - range_from_frames, - frames_to_seconds, - make_sequence_collection -) class ExtractOTIOReview(publish.Extractor): @@ -62,6 +55,13 @@ class ExtractOTIOReview(publish.Extractor): output_ext = ".jpg" def process(self, instance): + # Not all hosts can import these modules. + import opentimelineio as otio + from openpype.pipeline.editorial import ( + otio_range_to_frame_range, + make_sequence_collection + ) + # TODO: convert resulting image sequence to mp4 # get otio clip and other time info from instance clip @@ -281,6 +281,12 @@ class ExtractOTIOReview(publish.Extractor): Returns: otio.time.TimeRange: trimmed available range """ + # Not all hosts can import these modules. + from openpype.pipeline.editorial import ( + trim_media_range, + range_from_frames + ) + avl_start = int(avl_range.start_time.value) src_start = int(avl_start + start) avl_durtation = int(avl_range.duration.value) @@ -338,6 +344,8 @@ class ExtractOTIOReview(publish.Extractor): Returns: otio.time.TimeRange: trimmed available range """ + # Not all hosts can import this module. + from openpype.pipeline.editorial import frames_to_seconds # create path and frame start to destination output_path, out_frame_start = self._get_ffmpeg_output() diff --git a/openpype/plugins/publish/extract_otio_trimming_video.py b/openpype/plugins/publish/extract_otio_trimming_video.py index 67ff6c538c..2020fcde93 100644 --- a/openpype/plugins/publish/extract_otio_trimming_video.py +++ b/openpype/plugins/publish/extract_otio_trimming_video.py @@ -15,7 +15,6 @@ from openpype.lib import ( run_subprocess, ) from openpype.pipeline import publish -from openpype.pipeline.editorial import frames_to_seconds class ExtractOTIOTrimmingVideo(publish.Extractor): @@ -75,6 +74,8 @@ class ExtractOTIOTrimmingVideo(publish.Extractor): otio_range (opentime.TimeRange): range to trim to """ + # Not all hosts can import this module. + from openpype.pipeline.editorial import frames_to_seconds # create path to destination output_path = self._get_ffmpeg_output(input_file_path) diff --git a/tests/integration/hosts/maya/lib.py b/tests/integration/hosts/maya/lib.py index f27d516605..04ddb765a4 100644 --- a/tests/integration/hosts/maya/lib.py +++ b/tests/integration/hosts/maya/lib.py @@ -33,7 +33,7 @@ class MayaHostFixtures(HostFixtures): yield dest_path @pytest.fixture(scope="module") - def startup_scripts(self, monkeypatch_session): + def startup_scripts(self, monkeypatch_session, download_test_data): """Points Maya to userSetup file from input data""" startup_path = os.path.join( os.path.dirname(__file__), "input", "startup" @@ -44,6 +44,11 @@ class MayaHostFixtures(HostFixtures): "{}{}{}".format(startup_path, os.pathsep, original_pythonpath) ) + monkeypatch_session.setenv( + "MAYA_CMD_FILE_OUTPUT", + os.path.join(download_test_data, "output.log") + ) + @pytest.fixture(scope="module") def skip_compare_folders(self): yield [] diff --git a/tests/integration/hosts/maya/test_publish_in_maya.py b/tests/integration/hosts/maya/test_publish_in_maya.py index b7ee228aae..be8c74e0b8 100644 --- a/tests/integration/hosts/maya/test_publish_in_maya.py +++ b/tests/integration/hosts/maya/test_publish_in_maya.py @@ -1,3 +1,6 @@ +import re +import os + from tests.lib.assert_classes import DBAssert from tests.integration.hosts.maya.lib import MayaLocalPublishTestClass @@ -35,6 +38,32 @@ class TestPublishInMaya(MayaLocalPublishTestClass): TIMEOUT = 120 # publish timeout + def test_publish( + self, + dbcon, + publish_finished, + download_test_data + ): + """Testing Pyblish and Python logs within Maya.""" + + # All maya output via MAYA_CMD_FILE_OUTPUT env var during test run + logging_path = os.path.join(download_test_data, "output.log") + with open(logging_path, "r") as f: + logging_output = f.read() + + print(("-" * 50) + "LOGGING" + ("-" * 50)) + print(logging_output) + + # Check for pyblish errors. + error_regex = r"pyblish \(ERROR\)((.|\n)*?)((pyblish \())" + matches = re.findall(error_regex, logging_output) + assert not matches, matches[0][0] + + # Check for python errors. + error_regex = r"// Error((.|\n)*)" + matches = re.findall(error_regex, logging_output) + assert not matches, matches[0][0] + def test_db_asserts(self, dbcon, publish_finished): """Host and input data dependent expected results in DB.""" print("test_db_asserts") diff --git a/tests/lib/testing_classes.py b/tests/lib/testing_classes.py index e8e338e434..3b0611e2a0 100644 --- a/tests/lib/testing_classes.py +++ b/tests/lib/testing_classes.py @@ -10,6 +10,7 @@ import glob import platform import requests import re +import time from tests.lib.db_handler import DBHandler from tests.lib.file_handler import RemoteFileHandler @@ -334,7 +335,7 @@ class PublishTest(ModuleUnitTest): print("Creating only setup for test, not launching app") yield False return - import time + time_start = time.time() timeout = timeout or self.TIMEOUT timeout = float(timeout) From 63af150dd8f08b280bb6cb1ebe918dd4025e50a5 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 17:22:02 +0100 Subject: [PATCH 316/690] confirm of instance context changes reset origin of input fields --- openpype/tools/publisher/widgets/widgets.py | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 1bbe73381f..77ebc3f0bb 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -579,6 +579,10 @@ class AssetsField(BaseClickableFrame): """Change to asset names set with last `set_selected_items` call.""" self.set_selected_items(self._origin_value) + def confirm_value(self): + self._origin_value = copy.deepcopy(self._selected_items) + self._has_value_changed = False + class TasksComboboxProxy(QtCore.QSortFilterProxyModel): def __init__(self, *args, **kwargs): @@ -785,6 +789,18 @@ class TasksCombobox(QtWidgets.QComboBox): self._set_is_valid(is_valid) + def confirm_value(self): + new_task_name = self._selected_items[0] + origin_value = copy.deepcopy(self._origin_value) + new_origin_value = [ + (asset_name, new_task_name) + for (asset_name, task_name) in origin_value + ] + + self._origin_value = new_origin_value + self._origin_selection = copy.deepcopy(self._selected_items) + self._has_value_changed = False + def set_selected_items(self, asset_task_combinations=None): """Set items for selected instances. @@ -919,6 +935,10 @@ class VariantInputWidget(PlaceholderLineEdit): """Change text of multiselection.""" self._multiselection_text = text + def confirm_value(self): + self._origin_value = copy.deepcopy(self._current_value) + self._has_value_changed = False + def _set_is_valid(self, valid): if valid == self._is_valid: return @@ -1210,6 +1230,15 @@ class GlobalAttrsWidget(QtWidgets.QWidget): self._set_btns_enabled(False) self._set_btns_visible(invalid_tasks) + if variant_value is not None: + self.variant_input.confirm_value() + + if asset_name is not None: + self.asset_value_widget.confirm_value() + + if task_name is not None: + self.task_value_widget.confirm_value() + self.instance_context_changed.emit() def _on_cancel(self): From e32263916c4856d3d65c4b1c31aeeeaf3047f018 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 17:26:29 +0100 Subject: [PATCH 317/690] traypublisher: label of instances with folder path --- .../traypublisher/plugins/create/create_editorial.py | 12 ++++++++---- .../plugins/publish/collect_shot_instances.py | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 8c5083bcb2..128010cef9 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -606,19 +606,23 @@ or updating already created. Publishing will create OTIO file. Returns: str: label string """ - shot_name = instance_data["shotName"] + if AYON_SERVER_ENABLED: + asset_name = instance_data["creator_attributes"]["folderPath"] + else: + asset_name = instance_data["creator_attributes"]["shotName"] + variant_name = instance_data["variant"] family = preset["family"] - # get variant name from preset or from inharitance + # get variant name from preset or from inheritance _variant_name = preset.get("variant") or variant_name # subset name subset_name = "{}{}".format( family, _variant_name.capitalize() ) - label = "{}_{}".format( - shot_name, + label = "{} {}".format( + asset_name, subset_name ) diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py index 0b7e022658..e00ac64244 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_shot_instances.py @@ -155,7 +155,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): else {} ) - name = instance.data["asset"] + asset_name = instance.data["asset"] # get handles handle_start = int(instance.data["handleStart"]) @@ -177,7 +177,7 @@ class CollectShotInstance(pyblish.api.InstancePlugin): parents = instance.data.get('parents', []) - actual = {name: in_info} + actual = {asset_name: in_info} for parent in reversed(parents): parent_name = parent["entity_name"] From c6d81edc346bf233c65f8c96e69597afcd1f2c6e Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Tue, 7 Nov 2023 17:28:37 +0100 Subject: [PATCH 318/690] ayon settings: trypublisher editorial add task model conversion --- openpype/settings/ayon_settings.py | 6 +++++- .../server/settings/editorial_creators.py | 16 +++++++--------- server_addon/traypublisher/server/version.py | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 5eb68e3972..efad3ee27b 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -1021,10 +1021,14 @@ def _convert_traypublisher_project_settings(ayon_settings, output): item["family"] = item.pop("product_type") shot_add_tasks = ayon_editorial_simple["shot_add_tasks"] + + # TODO: backward compatibility and remove in future if isinstance(shot_add_tasks, dict): shot_add_tasks = [] + + # aggregate shot_add_tasks items new_shot_add_tasks = { - item["name"]: item["task_type"] + item["name"]: {"type": item["task_type"]} for item in shot_add_tasks } ayon_editorial_simple["shot_add_tasks"] = new_shot_add_tasks diff --git a/server_addon/traypublisher/server/settings/editorial_creators.py b/server_addon/traypublisher/server/settings/editorial_creators.py index 4111f22576..ac0ff0afc7 100644 --- a/server_addon/traypublisher/server/settings/editorial_creators.py +++ b/server_addon/traypublisher/server/settings/editorial_creators.py @@ -5,19 +5,17 @@ from ayon_server.settings import BaseSettingsModel, task_types_enum class ClipNameTokenizerItem(BaseSettingsModel): _layout = "expanded" - # TODO was 'dict-modifiable', is list of dicts now, must be fixed in code - name: str = Field("#TODO", title="Tokenizer name") + name: str = Field("", title="Tokenizer name") regex: str = Field("", title="Tokenizer regex") class ShotAddTasksItem(BaseSettingsModel): _layout = "expanded" - # TODO was 'dict-modifiable', is list of dicts now, must be fixed in code name: str = Field('', title="Key") - task_type: list[str] = Field( + task_type: str = Field( title="Task type", - default_factory=list, - enum_resolver=task_types_enum) + enum_resolver=task_types_enum + ) class ShotRenameSubmodel(BaseSettingsModel): @@ -54,7 +52,7 @@ class TokenToParentConvertorItem(BaseSettingsModel): ) -class ShotHierchySubmodel(BaseSettingsModel): +class ShotHierarchySubmodel(BaseSettingsModel): enabled: bool = True parents_path: str = Field( "", @@ -102,9 +100,9 @@ class EditorialSimpleCreatorPlugin(BaseSettingsModel): title="Shot Rename", default_factory=ShotRenameSubmodel ) - shot_hierarchy: ShotHierchySubmodel = Field( + shot_hierarchy: ShotHierarchySubmodel = Field( title="Shot Hierarchy", - default_factory=ShotHierchySubmodel + default_factory=ShotHierarchySubmodel ) shot_add_tasks: list[ShotAddTasksItem] = Field( title="Add tasks to shot", diff --git a/server_addon/traypublisher/server/version.py b/server_addon/traypublisher/server/version.py index df0c92f1e2..e57ad00718 100644 --- a/server_addon/traypublisher/server/version.py +++ b/server_addon/traypublisher/server/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring addon version.""" -__version__ = "0.1.2" +__version__ = "0.1.3" From e4ed21623a57618fa6889750c5cf97ec9cc1872d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 17:35:48 +0100 Subject: [PATCH 319/690] fix task combinations --- openpype/tools/publisher/widgets/widgets.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 77ebc3f0bb..9b31697749 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -789,15 +789,12 @@ class TasksCombobox(QtWidgets.QComboBox): self._set_is_valid(is_valid) - def confirm_value(self): + def confirm_value(self, asset_names): new_task_name = self._selected_items[0] - origin_value = copy.deepcopy(self._origin_value) - new_origin_value = [ + self._origin_value = [ (asset_name, new_task_name) - for (asset_name, task_name) in origin_value + for asset_name in asset_names ] - - self._origin_value = new_origin_value self._origin_selection = copy.deepcopy(self._selected_items) self._has_value_changed = False @@ -1180,6 +1177,7 @@ class GlobalAttrsWidget(QtWidgets.QWidget): subset_names = set() invalid_tasks = False + asset_names = [] for instance in self._current_instances: new_variant_value = instance.get("variant") new_asset_name = instance.get("asset") @@ -1193,6 +1191,7 @@ class GlobalAttrsWidget(QtWidgets.QWidget): if task_name is not None: new_task_name = task_name + asset_names.append(new_asset_name) try: new_subset_name = self._controller.get_subset_name( instance.creator_identifier, @@ -1237,7 +1236,7 @@ class GlobalAttrsWidget(QtWidgets.QWidget): self.asset_value_widget.confirm_value() if task_name is not None: - self.task_value_widget.confirm_value() + self.task_value_widget.confirm_value(asset_names) self.instance_context_changed.emit() From b8ed125569bdfd7c343d08483bfd70431d38f11d Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Tue, 7 Nov 2023 17:44:33 +0100 Subject: [PATCH 320/690] set spacing between buttons --- openpype/tools/publisher/widgets/widgets.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openpype/tools/publisher/widgets/widgets.py b/openpype/tools/publisher/widgets/widgets.py index 9b31697749..6dbeaad821 100644 --- a/openpype/tools/publisher/widgets/widgets.py +++ b/openpype/tools/publisher/widgets/widgets.py @@ -1127,6 +1127,7 @@ class GlobalAttrsWidget(QtWidgets.QWidget): btns_layout = QtWidgets.QHBoxLayout() btns_layout.setContentsMargins(0, 0, 0, 0) btns_layout.addStretch(1) + btns_layout.setSpacing(5) btns_layout.addWidget(submit_btn) btns_layout.addWidget(cancel_btn) From 8c8c083395b77e920254e8dd5d83ad06eb0c636d Mon Sep 17 00:00:00 2001 From: Ynbot Date: Wed, 8 Nov 2023 03:24:51 +0000 Subject: [PATCH 321/690] [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 9832c77291..8500b78966 100644 --- a/openpype/version.py +++ b/openpype/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring Pype version.""" -__version__ = "3.17.5" +__version__ = "3.17.6-nightly.1" From 3cd8fc6a0a8162a73d647f17a66294b0c79b2724 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 8 Nov 2023 03:25:29 +0000 Subject: [PATCH 322/690] chore(): update bug report / version --- .github/ISSUE_TEMPLATE/bug_report.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bdfc2ad46f..5d4db81a77 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -35,6 +35,7 @@ body: label: Version description: What version are you running? Look to OpenPype Tray options: + - 3.17.6-nightly.1 - 3.17.5 - 3.17.5-nightly.3 - 3.17.5-nightly.2 @@ -134,7 +135,6 @@ body: - 3.15.1 - 3.15.1-nightly.6 - 3.15.1-nightly.5 - - 3.15.1-nightly.4 validations: required: true - type: dropdown From cfc54439095140f2b6e2d84adc9ebfa09e96a4d3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 8 Nov 2023 16:35:28 +0800 Subject: [PATCH 323/690] clean up code tweaks for OP settings(not suitable for ayon yet) --- .../plugins/publish/validate_loaded_plugin.py | 82 ++++++++++--------- openpype/settings/ayon_settings.py | 3 + .../schemas/schema_max_publish.json | 10 ++- .../max/server/settings/publishers.py | 5 +- 4 files changed, 59 insertions(+), 41 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index e58685cc4d..8d59bbc120 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -51,34 +51,36 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, get_plugins()) } - for families, plugin in required_plugins.items(): - # Out of for loop build the instance family lookup - instance_families = {instance.data["family"]} - instance_families.update(instance.data.get("families", [])) - self.log.debug(f"{instance_families}") - # In the for loop check whether any family matches + # Build instance families lookup + instance_families = {instance.data["family"]} + instance_families.update(instance.data.get("families", [])) + self.log.debug(f"Checking plug-in validation for instance families: {instance_families}") + for families in required_plugins.keys(): + # Check for matching families match_families = {fam.strip() for fam in families.split(",") if fam.strip()} - self.log.debug(f"match_families: {match_families}") + self.log.debug(f"Plug-in family requirements: {match_families}") has_match = "*" in match_families or match_families.intersection( - instance_families) or families == "_" + instance_families) + if not has_match: continue - if not plugin: - return + plugins = [plugin for plugin in required_plugins[families]["plugins"]] + for plugin in plugins: + if not plugin: + return + plugin_name = plugin.format(**os.environ).lower() + plugin_index = available_plugins.get(plugin_name) - plugin_name = plugin.format(**os.environ).lower() - plugin_index = available_plugins.get(plugin_name) + if plugin_index is None: + invalid.append( + f"Plugin {plugin} does not exist in 3dsMax Plugin List." + ) + continue - if plugin_index is None: - invalid.append( - f"Plugin {plugin} does not exist in 3dsMax Plugin List." - ) - continue - - if not rt.pluginManager.isPluginDllLoaded(plugin_index): - invalid.append(f"Plugin {plugin} not loaded.") + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + invalid.append(f"Plugin {plugin} not loaded.") return invalid @@ -108,25 +110,29 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, ["ValidateLoadedPlugin"] ["family_plugins_mapping"] ) - for families, plugin in required_plugins.items(): - families_list = families.split(",") - excluded_families = [family for family in families_list - if instance.data["family"] != family - and family != "_"] - if excluded_families: - cls.log.debug("The {} instance is not part of {}.".format( - instance.data["family"], excluded_families - )) - continue - if not plugin: + instance_families = {instance.data["family"]} + instance_families.update(instance.data.get("families", [])) + cls.log.debug(f"Checking plug-in validation for instance families: {instance_families}") + for families in required_plugins.keys(): + match_families = {fam.strip() for fam in + families.split(",") if fam.strip()} + cls.log.debug(f"Plug-in family requirements: {match_families}") + has_match = "*" in match_families or match_families.intersection( + instance_families) + + if not has_match: continue - plugin_name = plugin.format(**os.environ).lower() - plugin_index = available_plugins.get(plugin_name) + plugins = [plugin for plugin in required_plugins[families]["plugins"]] + for plugin in plugins: + if not plugin: + return + plugin_name = plugin.format(**os.environ).lower() + plugin_index = available_plugins.get(plugin_name) - if plugin_index is None: - cls.log.warning(f"Can't enable missing plugin: {plugin}") - continue + if plugin_index is None: + cls.log.warning(f"Can't enable missing plugin: {plugin}") + continue - if not rt.pluginManager.isPluginDllLoaded(plugin_index): - rt.pluginManager.loadPluginDll(plugin_index) + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + rt.pluginManager.loadPluginDll(plugin_index) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index fa73199269..0cefd047b1 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -653,6 +653,9 @@ def _convert_3dsmax_project_settings(ayon_settings, output): family_plugin_mapping = ( ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] ) + for item in family_plugin_mapping: + if "product_types" in item: + item["families"] = item.pop("product_types") new_family_plugin_mapping = { item["families"]: item["plugins"] for item in family_plugin_mapping diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json index b48ce20f5d..c44c7525da 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json @@ -72,7 +72,15 @@ "label": "Family Plugins Mapping", "use_label_wrap": true, "object_type": { - "type": "text" + "type": "dict", + "children": [ + { + "key": "plugins", + "label": "plugins", + "type": "list", + "object_type": "text" + } + ] } } ] diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index d23acc6dd7..d7169f8b96 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -29,8 +29,9 @@ class ValidateAttributesModel(BaseSettingsModel): class FamilyPluginsMappingModel(BaseSettingsModel): _layout = "compact" - families: str = Field(title="Families") - plugins: str = Field(title="Plugins") + product_types: str = Field(title="Product Types") + plugins: list[str] = Field( + default_factory=list,title="Plugins") class ValidateLoadedPluginModel(BaseSettingsModel): From 105cf5c116ab755ddc315956b63145d6b511e7db Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 8 Nov 2023 12:31:31 +0200 Subject: [PATCH 324/690] fix a typo in maya ayon settings --- server_addon/maya/server/settings/creators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/creators.py b/server_addon/maya/server/settings/creators.py index 84e873589d..34a54832af 100644 --- a/server_addon/maya/server/settings/creators.py +++ b/server_addon/maya/server/settings/creators.py @@ -27,7 +27,7 @@ class CreateUnrealStaticMeshModel(BaseSettingsModel): default_factory=list, title="Default Products" ) - static_mesh_prefixes: str = Field("S", title="Static Mesh Prefix") + static_mesh_prefix: str = Field("S", title="Static Mesh Prefix") collision_prefixes: list[str] = Field( default_factory=list, title="Collision Prefixes" From 60b775a4f410aec128627a8697004be5a45527cb Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 8 Nov 2023 12:31:49 +0200 Subject: [PATCH 325/690] fix some typos in Houdini ayon settings --- server_addon/houdini/server/settings/create.py | 2 +- server_addon/houdini/server/settings/publish.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/server_addon/houdini/server/settings/create.py b/server_addon/houdini/server/settings/create.py index 81b871e83f..e8db917849 100644 --- a/server_addon/houdini/server/settings/create.py +++ b/server_addon/houdini/server/settings/create.py @@ -26,7 +26,7 @@ class CreateStaticMeshModel(BaseSettingsModel): default_factory=list, title="Default Products" ) - static_mesh_prefixes: str = Field("S", title="Static Mesh Prefix") + static_mesh_prefix: str = Field("S", title="Static Mesh Prefix") collision_prefixes: list[str] = Field( default_factory=list, title="Collision Prefixes" diff --git a/server_addon/houdini/server/settings/publish.py b/server_addon/houdini/server/settings/publish.py index 342bf957c1..92a676b0d0 100644 --- a/server_addon/houdini/server/settings/publish.py +++ b/server_addon/houdini/server/settings/publish.py @@ -33,9 +33,9 @@ class BasicValidateModel(BaseSettingsModel): class PublishPluginsModel(BaseSettingsModel): - CollectRopFrameRange: CollectRopFrameRangeModel = Field( - default_factory=CollectRopFrameRangeModel, - title="Collect Rop Frame Range.", + CollectAssetHandles: CollectAssetHandlesModel = Field( + default_factory=CollectAssetHandlesModel, + title="Collect Asset Handles.", section="Collectors" ) ValidateContainers: BasicValidateModel = Field( @@ -60,7 +60,7 @@ class PublishPluginsModel(BaseSettingsModel): DEFAULT_HOUDINI_PUBLISH_SETTINGS = { - "CollectRopFrameRange": { + "CollectAssetHandles": { "use_asset_handles": True }, "ValidateContainers": { From 4311f4840dd3b39115e5ddd244c025d86df1f1c8 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 8 Nov 2023 12:38:21 +0200 Subject: [PATCH 326/690] bump addon versions --- server_addon/houdini/server/version.py | 2 +- server_addon/maya/server/version.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server_addon/houdini/server/version.py b/server_addon/houdini/server/version.py index c49a95c357..75cf7831c4 100644 --- a/server_addon/houdini/server/version.py +++ b/server_addon/houdini/server/version.py @@ -1 +1 @@ -__version__ = "0.2.8" +__version__ = "0.2.9" diff --git a/server_addon/maya/server/version.py b/server_addon/maya/server/version.py index 90ce344d3e..805897cda3 100644 --- a/server_addon/maya/server/version.py +++ b/server_addon/maya/server/version.py @@ -1,3 +1,3 @@ # -*- coding: utf-8 -*- """Package declaring addon version.""" -__version__ = "0.1.5" +__version__ = "0.1.6" From d15dfaaf849d51c49d9a0e14d5be8f1c6f85ea2d Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 8 Nov 2023 18:47:42 +0800 Subject: [PATCH 327/690] hound & code tweak regarding to OP setting --- .../plugins/publish/validate_loaded_plugin.py | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 8d59bbc120..d348e37abc 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Validator for Loaded Plugin.""" import os -from pyblish.api import InstancePlugin, ValidatorOrder +import pyblish.api from pymxs import runtime as rt from openpype.pipeline.publish import ( @@ -13,7 +13,7 @@ from openpype.hosts.max.api.lib import get_plugins class ValidateLoadedPlugin(OptionalPyblishPluginMixin, - InstancePlugin): + pyblish.api.InstancePlugin): """Validates if the specific plugin is loaded in 3ds max. Studio Admin(s) can add the plugins they want to check in validation via studio defined project settings @@ -22,24 +22,21 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, """ - order = ValidatorOrder + order = pyblish.api.ValidatorOrder hosts = ["max"] label = "Validate Loaded Plugins" optional = True actions = [RepairAction] + family_plugins_mapping = {} + def get_invalid(self, instance): """Plugin entry point.""" if not self.is_active(instance.data): self.log.debug("Skipping Validate Loaded Plugin...") return - required_plugins = ( - instance.context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"] - ["family_plugins_mapping"] - ) - + required_plugins = self.family_plugins_mapping if not required_plugins: return @@ -54,11 +51,12 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, # Build instance families lookup instance_families = {instance.data["family"]} instance_families.update(instance.data.get("families", [])) - self.log.debug(f"Checking plug-in validation for instance families: {instance_families}") - for families in required_plugins.keys(): + self.log.debug("Checking plug-in validation " + f"for instance families: {instance_families}") + for family in required_plugins: # Check for matching families match_families = {fam.strip() for fam in - families.split(",") if fam.strip()} + family.split(",") if fam.strip()} self.log.debug(f"Plug-in family requirements: {match_families}") has_match = "*" in match_families or match_families.intersection( instance_families) @@ -66,7 +64,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not has_match: continue - plugins = [plugin for plugin in required_plugins[families]["plugins"]] + plugins = [plugin for plugin in + required_plugins[family]["plugins"]] for plugin in plugins: if not plugin: return @@ -75,7 +74,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if plugin_index is None: invalid.append( - f"Plugin {plugin} does not exist in 3dsMax Plugin List." + f"Plugin {plugin} does not exist" + " in 3dsMax Plugin List." ) continue @@ -105,17 +105,14 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } - required_plugins = ( - instance.context.data["project_settings"]["max"]["publish"] - ["ValidateLoadedPlugin"] - ["family_plugins_mapping"] - ) + required_plugins = cls.family_plugins_mapping instance_families = {instance.data["family"]} instance_families.update(instance.data.get("families", [])) - cls.log.debug(f"Checking plug-in validation for instance families: {instance_families}") - for families in required_plugins.keys(): + cls.log.debug("Checking plug-in validation " + f"for instance families: {instance_families}") + for family in required_plugins.keys(): match_families = {fam.strip() for fam in - families.split(",") if fam.strip()} + family.split(",") if fam.strip()} cls.log.debug(f"Plug-in family requirements: {match_families}") has_match = "*" in match_families or match_families.intersection( instance_families) @@ -123,7 +120,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not has_match: continue - plugins = [plugin for plugin in required_plugins[families]["plugins"]] + plugins = [plugin for plugin in + required_plugins[family]["plugins"]] for plugin in plugins: if not plugin: return From 1207ef3bbbcfe1b5db9bf0b5107d6e67eb5f6c53 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 12:00:59 +0100 Subject: [PATCH 328/690] autofix folder path on older instances --- openpype/pipeline/create/context.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/openpype/pipeline/create/context.py b/openpype/pipeline/create/context.py index 333ab25f54..e4dcedda2c 100644 --- a/openpype/pipeline/create/context.py +++ b/openpype/pipeline/create/context.py @@ -2255,11 +2255,11 @@ class CreateContext: if task_name: task_names_by_asset_name[asset_name].add(task_name) - asset_names = [ + asset_names = { asset_name for asset_name in task_names_by_asset_name.keys() if asset_name is not None - ] + } fields = {"name", "data.tasks"} if AYON_SERVER_ENABLED: fields |= {"data.parents"} @@ -2270,10 +2270,12 @@ class CreateContext: )) task_names_by_asset_name = {} + asset_docs_by_name = collections.defaultdict(list) for asset_doc in asset_docs: asset_name = get_asset_name_identifier(asset_doc) tasks = asset_doc.get("data", {}).get("tasks") or {} task_names_by_asset_name[asset_name] = set(tasks.keys()) + asset_docs_by_name[asset_doc["name"]].append(asset_doc) for instance in instances: if not instance.has_valid_asset or not instance.has_valid_task: @@ -2281,6 +2283,11 @@ class CreateContext: if AYON_SERVER_ENABLED: asset_name = instance["folderPath"] + if "/" not in asset_name: + asset_docs = asset_docs_by_name.get(asset_name) + if len(asset_docs) == 1: + asset_name = get_asset_name_identifier(asset_docs[0]) + instance["folderPath"] = asset_name else: asset_name = instance["asset"] From d3804564f26b3ba1a3d304195ec42b408c2b3dff Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 12:01:20 +0100 Subject: [PATCH 329/690] do not yield same asset multiple times --- openpype/client/server/entities.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index 9e86dfdd63..becf4abda3 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -232,10 +232,12 @@ def get_assets( else: new_asset_names.add(name) + yielded_ids = set() if folder_paths: for folder in _folders_query( project_name, con, fields, folder_paths=folder_paths, **kwargs ): + yielded_ids.add(folder["id"]) yield convert_v4_folder_to_v3(folder, project_name) if not new_asset_names: @@ -244,7 +246,9 @@ def get_assets( for folder in _folders_query( project_name, con, fields, folder_names=new_asset_names, **kwargs ): - yield convert_v4_folder_to_v3(folder, project_name) + if folder["id"] not in yielded_ids: + yielded_ids.add(folder["id"]) + yield convert_v4_folder_to_v3(folder, project_name) def get_archived_assets( From 2f23b83481de1d7cad5a5139ff0955091e980da0 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 8 Nov 2023 13:38:45 +0100 Subject: [PATCH 330/690] traypublisher: failed validator in editorial not necessary --- .../traypublisher/plugins/publish/validate_frame_ranges.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py b/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py index 09de2d8db2..7a5a3c7fc1 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py @@ -30,12 +30,17 @@ class ValidateFrameRange(OptionalPyblishPluginMixin, if not self.is_active(instance.data): return + # Skip the instance if does not have asset entity in database + asset_doc = instance.data.get("assetEntity") + if not asset_doc: + self.log.warning("No asset data found, skipping.") + return + if (self.skip_timelines_check and any(re.search(pattern, instance.data["task"]) for pattern in self.skip_timelines_check)): self.log.info("Skipping for {} task".format(instance.data["task"])) - asset_doc = instance.data["assetEntity"] asset_data = asset_doc["data"] frame_start = asset_data["frameStart"] frame_end = asset_data["frameEnd"] From 8f1648f87a917538b8ab139f0c1af5286aa19988 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:04:56 +0100 Subject: [PATCH 331/690] duplicated session 3 > session 4 --- openpype/pipeline/schema/session-4.0.json | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 openpype/pipeline/schema/session-4.0.json diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json new file mode 100644 index 0000000000..9f785939e4 --- /dev/null +++ b/openpype/pipeline/schema/session-4.0.json @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + + "title": "openpype:session-3.0", + "description": "The Avalon environment", + + "type": "object", + + "additionalProperties": true, + + "required": [ + "AVALON_PROJECT", + "AVALON_ASSET" + ], + + "properties": { + "AVALON_PROJECTS": { + "description": "Absolute path to root of project directories", + "type": "string", + "example": "/nas/projects" + }, + "AVALON_PROJECT": { + "description": "Name of project", + "type": "string", + "pattern": "^\\w*$", + "example": "Hulk" + }, + "AVALON_ASSET": { + "description": "Name of asset", + "type": "string", + "pattern": "^\\w*$", + "example": "Bruce" + }, + "AVALON_TASK": { + "description": "Name of task", + "type": "string", + "pattern": "^\\w*$", + "example": "modeling" + }, + "AVALON_APP": { + "description": "Name of host", + "type": "string", + "pattern": "^\\w*$", + "example": "maya2016" + }, + "AVALON_DB": { + "description": "Name of database", + "type": "string", + "pattern": "^\\w*$", + "example": "avalon", + "default": "avalon" + }, + "AVALON_LABEL": { + "description": "Nice name of Avalon, used in e.g. graphical user interfaces", + "type": "string", + "example": "Mindbender", + "default": "Avalon" + }, + "AVALON_TIMEOUT": { + "description": "Wherever there is a need for a timeout, this is the default value.", + "type": "string", + "pattern": "^[0-9]*$", + "default": "1000", + "example": "1000" + }, + "AVALON_INSTANCE_ID": { + "description": "Unique identifier for instances in a working file", + "type": "string", + "pattern": "^[\\w.]*$", + "default": "avalon.instance", + "example": "avalon.instance" + }, + "AVALON_CONTAINER_ID": { + "description": "Unique identifier for a loaded representation in a working file", + "type": "string", + "pattern": "^[\\w.]*$", + "default": "avalon.container", + "example": "avalon.container" + } + } +} From e85504b80c5665d6ddf73fa3b98855db7504b18c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:08:03 +0100 Subject: [PATCH 332/690] use new schema in 'legacy_io' --- openpype/pipeline/legacy_io.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/pipeline/legacy_io.py b/openpype/pipeline/legacy_io.py index 60fa035c22..864102dff9 100644 --- a/openpype/pipeline/legacy_io.py +++ b/openpype/pipeline/legacy_io.py @@ -30,7 +30,7 @@ def install(): session = session_data_from_environment(context_keys=True) - session["schema"] = "openpype:session-3.0" + session["schema"] = "openpype:session-4.0" try: schema.validate(session) except schema.ValidationError as e: From 2bc41f53bfa696ff6fe04bd1e840fd85f5fa48ed Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:06:17 +0100 Subject: [PATCH 333/690] chnaged title of schema --- openpype/pipeline/schema/session-4.0.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json index 9f785939e4..dc4791994e 100644 --- a/openpype/pipeline/schema/session-4.0.json +++ b/openpype/pipeline/schema/session-4.0.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-04/schema#", - "title": "openpype:session-3.0", + "title": "openpype:session-4.0", "description": "The Avalon environment", "type": "object", From d3fc80f9055b4c6b5d2e4d95ef6a489db465169c Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:06:35 +0100 Subject: [PATCH 334/690] allow forward slash in AVALON_ASSET --- openpype/pipeline/schema/session-4.0.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json index dc4791994e..9610d8ec64 100644 --- a/openpype/pipeline/schema/session-4.0.json +++ b/openpype/pipeline/schema/session-4.0.json @@ -28,7 +28,7 @@ "AVALON_ASSET": { "description": "Name of asset", "type": "string", - "pattern": "^\\w*$", + "pattern": "^[\\/\\w]*$", "example": "Bruce" }, "AVALON_TASK": { From 3cade9a288db81c4eb6b8684641eafb947b5a183 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:06:50 +0100 Subject: [PATCH 335/690] removed unused keys --- openpype/pipeline/schema/session-4.0.json | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json index 9610d8ec64..54a6323e8f 100644 --- a/openpype/pipeline/schema/session-4.0.json +++ b/openpype/pipeline/schema/session-4.0.json @@ -14,11 +14,6 @@ ], "properties": { - "AVALON_PROJECTS": { - "description": "Absolute path to root of project directories", - "type": "string", - "example": "/nas/projects" - }, "AVALON_PROJECT": { "description": "Name of project", "type": "string", @@ -62,20 +57,6 @@ "pattern": "^[0-9]*$", "default": "1000", "example": "1000" - }, - "AVALON_INSTANCE_ID": { - "description": "Unique identifier for instances in a working file", - "type": "string", - "pattern": "^[\\w.]*$", - "default": "avalon.instance", - "example": "avalon.instance" - }, - "AVALON_CONTAINER_ID": { - "description": "Unique identifier for a loaded representation in a working file", - "type": "string", - "pattern": "^[\\w.]*$", - "default": "avalon.container", - "example": "avalon.container" } } } From e5d3a1aeb0d9d9320eb1b201f73aab3fa383cc65 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:07:06 +0100 Subject: [PATCH 336/690] 'AVALON_ASSET' is not required --- openpype/pipeline/schema/session-4.0.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json index 54a6323e8f..088156af85 100644 --- a/openpype/pipeline/schema/session-4.0.json +++ b/openpype/pipeline/schema/session-4.0.json @@ -9,8 +9,7 @@ "additionalProperties": true, "required": [ - "AVALON_PROJECT", - "AVALON_ASSET" + "AVALON_PROJECT" ], "properties": { From 389b568f6b8f356a9be4ab89496b37fa26706337 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 14:10:06 +0100 Subject: [PATCH 337/690] removed AVALON_PROJECTS --- openpype/pipeline/context_tools.py | 6 +----- openpype/pipeline/mongodb.py | 2 -- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 38c80c87bb..fe46bd1558 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -88,11 +88,7 @@ def registered_root(): root = _registered_root["_"] if root: return root - - root = legacy_io.Session.get("AVALON_PROJECTS") - if root: - return os.path.normpath(root) - return "" + return {} def install_host(host): diff --git a/openpype/pipeline/mongodb.py b/openpype/pipeline/mongodb.py index 41a44c7373..c948983c3d 100644 --- a/openpype/pipeline/mongodb.py +++ b/openpype/pipeline/mongodb.py @@ -62,8 +62,6 @@ def auto_reconnect(func): SESSION_CONTEXT_KEYS = ( - # Root directory of projects on disk - "AVALON_PROJECTS", # Name of current Project "AVALON_PROJECT", # Name of current Asset From eda0afc26052f1ac1d5a6088aed71db94e8c3010 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Wed, 8 Nov 2023 14:27:47 +0100 Subject: [PATCH 338/690] traypublisher: adding exceptions for editorial instances --- .../traypublisher/plugins/create/create_editorial.py | 2 ++ .../plugins/publish/collect_sequence_frame_data.py | 6 ++++++ .../plugins/publish/validate_frame_ranges.py | 8 ++++---- openpype/plugins/publish/collect_resources_path.py | 6 ++++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/traypublisher/plugins/create/create_editorial.py b/openpype/hosts/traypublisher/plugins/create/create_editorial.py index 8640500b18..a2746f115f 100644 --- a/openpype/hosts/traypublisher/plugins/create/create_editorial.py +++ b/openpype/hosts/traypublisher/plugins/create/create_editorial.py @@ -701,6 +701,8 @@ or updating already created. Publishing will create OTIO file. # parent time properties "trackStartFrame": track_start_frame, "timelineOffset": timeline_offset, + "isEditorial": True, + # creator_attributes "creator_attributes": creator_attributes } diff --git a/openpype/hosts/traypublisher/plugins/publish/collect_sequence_frame_data.py b/openpype/hosts/traypublisher/plugins/publish/collect_sequence_frame_data.py index db70d4fe0a..92cedf6b5b 100644 --- a/openpype/hosts/traypublisher/plugins/publish/collect_sequence_frame_data.py +++ b/openpype/hosts/traypublisher/plugins/publish/collect_sequence_frame_data.py @@ -27,6 +27,12 @@ class CollectSequenceFrameData( if not self.is_active(instance.data): return + # editorial would fail since they might not be in database yet + is_editorial = instance.data.get("isEditorial") + if is_editorial: + self.log.debug("Instance is Editorial. Skipping.") + return + frame_data = self.get_frame_data_from_repre_sequence(instance) if not frame_data: diff --git a/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py b/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py index 7a5a3c7fc1..4977a13374 100644 --- a/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py +++ b/openpype/hosts/traypublisher/plugins/publish/validate_frame_ranges.py @@ -30,10 +30,10 @@ class ValidateFrameRange(OptionalPyblishPluginMixin, if not self.is_active(instance.data): return - # Skip the instance if does not have asset entity in database - asset_doc = instance.data.get("assetEntity") - if not asset_doc: - self.log.warning("No asset data found, skipping.") + # editorial would fail since they might not be in database yet + is_editorial = instance.data.get("isEditorial") + if is_editorial: + self.log.debug("Instance is Editorial. Skipping.") return if (self.skip_timelines_check and diff --git a/openpype/plugins/publish/collect_resources_path.py b/openpype/plugins/publish/collect_resources_path.py index cfb4d63c1b..14c13310df 100644 --- a/openpype/plugins/publish/collect_resources_path.py +++ b/openpype/plugins/publish/collect_resources_path.py @@ -68,6 +68,12 @@ class CollectResourcesPath(pyblish.api.InstancePlugin): ] def process(self, instance): + # editorial would fail since they might not be in database yet + is_editorial = instance.data.get("isEditorial") + if is_editorial: + self.log.debug("Instance is Editorial. Skipping.") + return + anatomy = instance.context.data["anatomy"] template_data = copy.deepcopy(instance.data["anatomyData"]) From ea69e9943ec21cbcb0c5094ed6f063dd393cccb8 Mon Sep 17 00:00:00 2001 From: MustafaJafar Date: Wed, 8 Nov 2023 15:56:37 +0200 Subject: [PATCH 339/690] update houdini license validator --- .../validate_houdini_license_category.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py b/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py index f1c52f22c1..e0e06e37c8 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py +++ b/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py @@ -3,30 +3,29 @@ import pyblish.api from openpype.pipeline import PublishValidationError -class ValidateHoudiniCommercialLicense(pyblish.api.InstancePlugin): - """Validate the Houdini instance runs a Commercial license. +class ValidateHoudiniNotApprenticeLicense(pyblish.api.InstancePlugin): + """Validate the Houdini instance runs a non Apprentice license. - When extracting USD files from a non-commercial Houdini license, even with - Houdini Indie license, the resulting files will get "scrambled" with - a license protection and get a special .usdnc or .usdlc suffix. + When extracting USD files from an apprentice Houdini license, + the resulting files will get "scrambled" with a license protection + and get a special .usdnc or .usdlc suffix. This currently breaks the Subset/representation pipeline so we disallow - any publish with those licenses. Only the commercial license is valid. + any publish with apprentice license. """ order = pyblish.api.ValidatorOrder families = ["usd"] hosts = ["houdini"] - label = "Houdini Commercial License" + label = "Houdini Apprentice License" def process(self, instance): import hou - license = hou.licenseCategory() - if license != hou.licenseCategoryType.Commercial: + if hou.isApprentice(): raise PublishValidationError( - ("USD Publishing requires a full Commercial " - "license. You are on: {}").format(license), + ("USD Publishing requires a non apprentice " + "license."), title=self.label) From d410899714cffcf75ab4be154b78af6acd99a601 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 8 Nov 2023 22:05:33 +0800 Subject: [PATCH 340/690] add ayon settings support for validate loaded plugins --- .../plugins/publish/validate_loaded_plugin.py | 11 ++++---- openpype/settings/ayon_settings.py | 19 ++++++-------- .../max/server/settings/publishers.py | 25 +++++++++++++------ 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index d348e37abc..a681dc507f 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -63,12 +63,12 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not has_match: continue - - plugins = [plugin for plugin in - required_plugins[family]["plugins"]] + plugins = [plugin for plugin in required_plugins[family]["plugins"]] for plugin in plugins: if not plugin: return + # make sure the validation applied for + # plugins with different Max version plugin_name = plugin.format(**os.environ).lower() plugin_index = available_plugins.get(plugin_name) @@ -110,7 +110,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, instance_families.update(instance.data.get("families", [])) cls.log.debug("Checking plug-in validation " f"for instance families: {instance_families}") - for family in required_plugins.keys(): + for family in required_plugins: match_families = {fam.strip() for fam in family.split(",") if fam.strip()} cls.log.debug(f"Plug-in family requirements: {match_families}") @@ -120,8 +120,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not has_match: continue - plugins = [plugin for plugin in - required_plugins[family]["plugins"]] + plugins = [plugin for plugin in family["plugins"]] for plugin in plugins: if not plugin: return diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 0cefd047b1..8fd7f990c4 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -650,19 +650,14 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_publish["ValidateAttributes"]["attributes"] = attributes if "ValidateLoadedPlugin" in ayon_publish: - family_plugin_mapping = ( - ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] - ) - for item in family_plugin_mapping: - if "product_types" in item: - item["families"] = item.pop("product_types") - new_family_plugin_mapping = { - item["families"]: item["plugins"] - for item in family_plugin_mapping - } - ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] = ( - new_family_plugin_mapping + new_plugin_mapping = {} + loaded_plugin = ( + ayon_publish["ValidateLoadedPlugin"] ) + for item in loaded_plugin["family_plugins_mapping"]: + name = item.pop("name") + new_plugin_mapping[name] = item + loaded_plugin["family_plugins_mapping"] = new_plugin_mapping output["max"] = ayon_max diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index d7169f8b96..cf482d59d8 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -1,7 +1,7 @@ import json from pydantic import Field, validator -from ayon_server.settings import BaseSettingsModel +from ayon_server.settings import BaseSettingsModel, ensure_unique_names from ayon_server.exceptions import BadRequestException @@ -27,20 +27,31 @@ class ValidateAttributesModel(BaseSettingsModel): return value -class FamilyPluginsMappingModel(BaseSettingsModel): +class FamilyMappingItemModel(BaseSettingsModel): _layout = "compact" - product_types: str = Field(title="Product Types") + name: str = Field("", title="Product type") plugins: list[str] = Field( - default_factory=list,title="Plugins") + default_factory=list, + title="Plugins" + ) class ValidateLoadedPluginModel(BaseSettingsModel): - enabled: bool = Field(title="ValidateLoadedPlugin") + enabled: bool = Field(title="Enabled") optional: bool = Field(title="Optional") - family_plugins_mapping: list[FamilyPluginsMappingModel] = Field( - default_factory=list, title="Family Plugins Mapping" + family_plugins_mapping: list[FamilyMappingItemModel] = ( + Field( + default_factory=list, + title="Family Plugins Mapping" + ) ) + # This is to validate unique names (like in dict) + @validator("family_plugins_mapping") + def validate_unique_outputs(cls, value): + ensure_unique_names(value) + return value + class BasicValidateModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") From 57131a8b40bb6633aaeda75528a58bb3967298b3 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 8 Nov 2023 22:07:36 +0800 Subject: [PATCH 341/690] hound --- openpype/hosts/max/plugins/publish/validate_loaded_plugin.py | 3 ++- server_addon/max/server/settings/publishers.py | 4 +--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index a681dc507f..06486e94a6 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -63,7 +63,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not has_match: continue - plugins = [plugin for plugin in required_plugins[family]["plugins"]] + plugins = [plugin for plugin in + required_plugins[family]["plugins"]] for plugin in plugins: if not plugin: return diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index cf482d59d8..a752d8cb74 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -39,11 +39,9 @@ class FamilyMappingItemModel(BaseSettingsModel): class ValidateLoadedPluginModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") optional: bool = Field(title="Optional") - family_plugins_mapping: list[FamilyMappingItemModel] = ( - Field( + family_plugins_mapping: list[FamilyMappingItemModel] = Field( default_factory=list, title="Family Plugins Mapping" - ) ) # This is to validate unique names (like in dict) From af9718f753b836542aa55a837123caa655beb369 Mon Sep 17 00:00:00 2001 From: Mustafa Taher Date: Wed, 8 Nov 2023 16:25:17 +0200 Subject: [PATCH 342/690] BigRoy's comment - update doc string Co-authored-by: Roy Nieterau --- .../plugins/publish/validate_houdini_license_category.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py b/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py index e0e06e37c8..fd6ad9e3be 100644 --- a/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py +++ b/openpype/hosts/houdini/plugins/publish/validate_houdini_license_category.py @@ -8,7 +8,7 @@ class ValidateHoudiniNotApprenticeLicense(pyblish.api.InstancePlugin): When extracting USD files from an apprentice Houdini license, the resulting files will get "scrambled" with a license protection - and get a special .usdnc or .usdlc suffix. + and get a special .usdnc suffix. This currently breaks the Subset/representation pipeline so we disallow any publish with apprentice license. From 81d054799c5761180baca44dba95a4f00a0f32de Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 8 Nov 2023 15:26:21 +0100 Subject: [PATCH 343/690] Apply suggestions from code review Co-authored-by: Roy Nieterau --- openpype/pipeline/schema/session-4.0.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/pipeline/schema/session-4.0.json b/openpype/pipeline/schema/session-4.0.json index 088156af85..0dab48aa46 100644 --- a/openpype/pipeline/schema/session-4.0.json +++ b/openpype/pipeline/schema/session-4.0.json @@ -35,7 +35,7 @@ "description": "Name of host", "type": "string", "pattern": "^\\w*$", - "example": "maya2016" + "example": "maya" }, "AVALON_DB": { "description": "Name of database", @@ -47,7 +47,7 @@ "AVALON_LABEL": { "description": "Nice name of Avalon, used in e.g. graphical user interfaces", "type": "string", - "example": "Mindbender", + "example": "MyLabel", "default": "Avalon" }, "AVALON_TIMEOUT": { From 1676f37d3aa98633ff9ac8531285b850d7c5ba28 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 16:32:33 +0100 Subject: [PATCH 344/690] change default value of registered root --- openpype/pipeline/context_tools.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index fe46bd1558..33eb335ab9 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -43,7 +43,7 @@ from . import ( _is_installed = False _process_id = None -_registered_root = {"_": ""} +_registered_root = {"_": {}} _registered_host = {"_": None} # Keep modules manager (and it's modules) in memory # - that gives option to register modules' callbacks @@ -85,10 +85,7 @@ def register_root(path): def registered_root(): """Return currently registered root""" - root = _registered_root["_"] - if root: - return root - return {} + return _registered_root["_"] def install_host(host): From 74d0f944afd6ce2e719204c0505981f5fd77d952 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Wed, 8 Nov 2023 15:44:32 +0000 Subject: [PATCH 345/690] Do not pack image if it is already packed --- .../blender/plugins/publish/extract_blend.py | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index c8eeef7fd7..645314e50e 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -28,16 +28,22 @@ class ExtractBlend(publish.Extractor): for obj in instance: data_blocks.add(obj) # Pack used images in the blend files. - if obj.type == 'MESH': - for material_slot in obj.material_slots: - mat = material_slot.material - if mat and mat.use_nodes: - tree = mat.node_tree - if tree.type == 'SHADER': - for node in tree.nodes: - if node.bl_idname == 'ShaderNodeTexImage': - if node.image: - node.image.pack() + if obj.type != 'MESH': + continue + for material_slot in obj.material_slots: + mat = material_slot.material + if not(mat and mat.use_nodes): + continue + tree = mat.node_tree + if tree.type != 'SHADER': + continue + for node in tree.nodes: + if node.bl_idname != 'ShaderNodeTexImage': + continue + # Check if image is not packed already + # and pack it if not. + if node.image and node.image.packed_file is None: + node.image.pack() bpy.data.libraries.write(filepath, data_blocks) From 06856644d160155dee3b378ad2326cd44babf5b9 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Wed, 8 Nov 2023 17:07:48 +0100 Subject: [PATCH 346/690] modify 'registered_root' function docstring --- openpype/pipeline/context_tools.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 33eb335ab9..71f41fd234 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -84,7 +84,21 @@ def register_root(path): def registered_root(): - """Return currently registered root""" + """Return registered roots from current project anatomy. + + Consider this does return roots only for current project and current + platforms, only if host was installer using 'install_host'. + + Deprecated: + Please use project 'Anatomy' to get roots. This function is still used + at current core functions of load logic, but that will change + in future and this function will be removed eventually. Using this + function at new places can cause problems in the future. + + Returns: + dict[str, str]: Root paths. + """ + return _registered_root["_"] From b3649b5c5cd1167acb6de9d63ec3c50263be2408 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 13:29:48 +0800 Subject: [PATCH 347/690] improve debug message & use debug instead of info for artist-facing report --- openpype/hosts/maya/api/fbx.py | 4 ++-- .../hosts/maya/plugins/publish/extract_fbx_animation.py | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/api/fbx.py b/openpype/hosts/maya/api/fbx.py index dbb3578f08..c8f4050bc1 100644 --- a/openpype/hosts/maya/api/fbx.py +++ b/openpype/hosts/maya/api/fbx.py @@ -156,7 +156,7 @@ class FBXExtractor: # Parse export options options = self.default_options options = self.parse_overrides(instance, options) - self.log.info("Export options: {0}".format(options)) + self.log.debug("Export options: {0}".format(options)) # Collect the start and end including handles start = instance.data.get("frameStartHandle") or \ @@ -186,7 +186,7 @@ class FBXExtractor: template = "FBXExport{0} {1}" if key == "UpAxis" else \ "FBXExport{0} -v {1}" # noqa cmd = template.format(key, value) - self.log.info(cmd) + self.log.debug(cmd) mel.eval(cmd) # Never show the UI or generate a log diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index c6f8029e7d..c13d349394 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -43,9 +43,13 @@ class ExtractFBXAnimation(publish.Extractor): # FBX does not include the namespace but preserves the node # names as existing in the rig workfile if not out_members: + skeleton_set = [ + i for i in instance + if i.endswith("skeletonAnim_SET") + ] self.log.debug( - "Top group of animated skeleton not found.." - "skipping extraction") + "Top group of animated skeleton not found in " + "{}.\nSkipping fbx animation extraction".format(skeleton_set)) return namespace = get_namespace(out_members[0]) From ed60c361bab707bdd06d6de8fc09e828ff57c639 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 13:30:31 +0800 Subject: [PATCH 348/690] hound --- openpype/hosts/maya/plugins/publish/extract_fbx_animation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index c13d349394..e88b8b1e16 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -44,8 +44,8 @@ class ExtractFBXAnimation(publish.Extractor): # names as existing in the rig workfile if not out_members: skeleton_set = [ - i for i in instance - if i.endswith("skeletonAnim_SET") + i for i in instance + if i.endswith("skeletonAnim_SET") ] self.log.debug( "Top group of animated skeleton not found in " From 0403af298e795cdc7a206b88485f40bd6e07072b Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 17:21:37 +0800 Subject: [PATCH 349/690] tweaks the codes to use list instead of dict for OP settings --- .../plugins/publish/validate_loaded_plugin.py | 141 +++++++++--------- .../defaults/project_settings/max.json | 2 +- .../schemas/schema_max_publish.json | 10 +- 3 files changed, 77 insertions(+), 76 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 06486e94a6..7450c8f971 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -17,9 +17,6 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, """Validates if the specific plugin is loaded in 3ds max. Studio Admin(s) can add the plugins they want to check in validation via studio defined project settings - If families = ["*"], all the required plugins would be validated - If families - """ order = pyblish.api.ValidatorOrder @@ -30,66 +27,77 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, family_plugins_mapping = {} - def get_invalid(self, instance): + @classmethod + def get_invalid(cls, instance): """Plugin entry point.""" - if not self.is_active(instance.data): - self.log.debug("Skipping Validate Loaded Plugin...") - return - - required_plugins = self.family_plugins_mapping - if not required_plugins: + family_plugins_mapping = cls.family_plugins_mapping + if not family_plugins_mapping: return invalid = [] + # Find all plug-in requirements for current instance + instance_families = {instance.data["family"]} + instance_families.update(instance.data.get("families", [])) + cls.log.debug("Checking plug-in validation " + f"for instance families: {instance_families}") + all_required_plugins = set() + + for mapping in family_plugins_mapping: + # Check for matching families + if not mapping: + return + + match_families = {fam for fam in mapping["families"] if fam.strip()} + has_match = "*" in match_families or match_families.intersection( + instance_families) + + if not has_match: + continue + + cls.log.debug(f"Found plug-in family requirements: {match_families}") + required_plugins = [ + # match lowercase and format with os.environ to allow + # plugin names defined by max version, e.g. {3DSMAX_VERSION} + plugin.format(**os.environ).lower() + for plugin in mapping["plugins"] + # ignore empty fields in settings + if plugin.strip() + ] + + all_required_plugins.update(required_plugins) + + if not all_required_plugins: + # Instance has no plug-in requirements + return # get all DLL loaded plugins in Max and their plugin index available_plugins = { plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } - - # Build instance families lookup - instance_families = {instance.data["family"]} - instance_families.update(instance.data.get("families", [])) - self.log.debug("Checking plug-in validation " - f"for instance families: {instance_families}") - for family in required_plugins: - # Check for matching families - match_families = {fam.strip() for fam in - family.split(",") if fam.strip()} - self.log.debug(f"Plug-in family requirements: {match_families}") - has_match = "*" in match_families or match_families.intersection( - instance_families) - - if not has_match: + # validate the required plug-ins + for plugin in sorted(all_required_plugins): + plugin_index = available_plugins.get(plugin) + if plugin_index is None: + debug_msg = ( + f"Plugin {plugin} does not exist" + " in 3dsMax Plugin List." + ) + invalid.append((plugin, debug_msg)) continue - plugins = [plugin for plugin in - required_plugins[family]["plugins"]] - for plugin in plugins: - if not plugin: - return - # make sure the validation applied for - # plugins with different Max version - plugin_name = plugin.format(**os.environ).lower() - plugin_index = available_plugins.get(plugin_name) - - if plugin_index is None: - invalid.append( - f"Plugin {plugin} does not exist" - " in 3dsMax Plugin List." - ) - continue - - if not rt.pluginManager.isPluginDllLoaded(plugin_index): - invalid.append(f"Plugin {plugin} not loaded.") - + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + debug_msg = f"Plugin {plugin} not loaded." + invalid.append((plugin, debug_msg)) return invalid def process(self, instance): - invalid_plugins = self.get_invalid(instance) - if invalid_plugins: + if not self.is_active(instance.data): + self.log.debug("Skipping Validate Loaded Plugin...") + return + invalid = self.get_invalid(instance) + if invalid: bullet_point_invalid_statement = "\n".join( - "- {}".format(invalid) for invalid in invalid_plugins + "- {}".format(message) for _, message in invalid ) report = ( "Required plugins are not loaded.\n\n" @@ -101,36 +109,23 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, @classmethod def repair(cls, instance): + # get all DLL loaded plugins in Max and their plugin index + invalid = cls.get_invalid(instance) + if not invalid: + return + # get all DLL loaded plugins in Max and their plugin index available_plugins = { plugin_name.lower(): index for index, plugin_name in enumerate( get_plugins()) } - required_plugins = cls.family_plugins_mapping - instance_families = {instance.data["family"]} - instance_families.update(instance.data.get("families", [])) - cls.log.debug("Checking plug-in validation " - f"for instance families: {instance_families}") - for family in required_plugins: - match_families = {fam.strip() for fam in - family.split(",") if fam.strip()} - cls.log.debug(f"Plug-in family requirements: {match_families}") - has_match = "*" in match_families or match_families.intersection( - instance_families) - if not has_match: + for invalid_plugin, _ in invalid: + plugin_index = available_plugins.get(invalid_plugin) + + if plugin_index is None: + cls.log.warning(f"Can't enable missing plugin: {invalid_plugin}") continue - plugins = [plugin for plugin in family["plugins"]] - for plugin in plugins: - if not plugin: - return - plugin_name = plugin.format(**os.environ).lower() - plugin_index = available_plugins.get(plugin_name) - - if plugin_index is None: - cls.log.warning(f"Can't enable missing plugin: {plugin}") - continue - - if not rt.pluginManager.isPluginDllLoaded(plugin_index): - rt.pluginManager.loadPluginDll(plugin_index) + if not rt.pluginManager.isPluginDllLoaded(plugin_index): + rt.pluginManager.loadPluginDll(plugin_index) diff --git a/openpype/settings/defaults/project_settings/max.json b/openpype/settings/defaults/project_settings/max.json index 57927b48c7..92049cdbe9 100644 --- a/openpype/settings/defaults/project_settings/max.json +++ b/openpype/settings/defaults/project_settings/max.json @@ -44,7 +44,7 @@ "ValidateLoadedPlugin": { "enabled": false, "optional": true, - "family_plugins_mapping": {} + "family_plugins_mapping": [] } } } diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json index c44c7525da..c6d37ae993 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_max_publish.json @@ -66,7 +66,7 @@ "label": "Optional" }, { - "type": "dict-modifiable", + "type": "list", "collapsible": true, "key": "family_plugins_mapping", "label": "Family Plugins Mapping", @@ -74,9 +74,15 @@ "object_type": { "type": "dict", "children": [ + { + "key": "families", + "label": "Famiies", + "type": "list", + "object_type": "text" + }, { "key": "plugins", - "label": "plugins", + "label": "Plugins", "type": "list", "object_type": "text" } From f52af5bcc464621066d1db19a29c0e31bb6f7773 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 17:23:11 +0800 Subject: [PATCH 350/690] add the full stop --- openpype/hosts/maya/plugins/publish/extract_fbx_animation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index e88b8b1e16..756158d4f0 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -49,7 +49,7 @@ class ExtractFBXAnimation(publish.Extractor): ] self.log.debug( "Top group of animated skeleton not found in " - "{}.\nSkipping fbx animation extraction".format(skeleton_set)) + "{}.\nSkipping fbx animation extraction.".format(skeleton_set)) return namespace = get_namespace(out_members[0]) From 0d6e728552d0a42c6338b07dd761e981111d6b6e Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 10:42:38 +0000 Subject: [PATCH 351/690] Added function to get collections Also added a flag in old function to get selection to include collections. --- openpype/hosts/blender/api/lib.py | 54 +++++++++++++++++-- .../plugins/create/create_blendScene.py | 30 +++-------- 2 files changed, 58 insertions(+), 26 deletions(-) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index 9bb560c364..2f33fd25ad 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -266,9 +266,57 @@ def read(node: bpy.types.bpy_struct_meta_idprop): return data -def get_selection() -> List[bpy.types.Object]: - """Return the selected objects from the current scene.""" - return [obj for obj in bpy.context.scene.objects if obj.select_get()] +def get_selected_collections(): + """ + Returns a list of the currently selected collections in the outliner. + + Raises: + RuntimeError: If the outliner cannot be found in the main Blender + window. + + Returns: + list: A list of `bpy.types.Collection` objects that are currently + selected in the outliner. + """ + try: + area = next( + area for area in bpy.context.window.screen.areas + if area.type == 'OUTLINER') + region = next( + region for region in area.regions + if region.type == 'WINDOW') + except StopIteration as e: + raise RuntimeError("Could not find outliner. An outliner space " + "must be in the main Blender window.") from e + + with bpy.context.temp_override( + window=bpy.context.window, + area=area, + region=region, + screen=bpy.context.window.screen + ): + ids = bpy.context.selected_ids + + return [id for id in ids if isinstance(id, bpy.types.Collection)] + + +def get_selection(include_collections: bool = False) -> List[bpy.types.Object]: + """ + Returns a list of selected objects in the current Blender scene. + + Args: + include_collections (bool, optional): Whether to include selected + collections in the result. Defaults to False. + + Returns: + List[bpy.types.Object]: A list of selected objects. + """ + selection = [obj for obj in bpy.context.scene.objects if obj.select_get()] + + if include_collections: + selection.extend(get_selected_collections()) + + return selection @contextlib.contextmanager diff --git a/openpype/hosts/blender/plugins/create/create_blendScene.py b/openpype/hosts/blender/plugins/create/create_blendScene.py index 791e741ca7..bb57a16888 100644 --- a/openpype/hosts/blender/plugins/create/create_blendScene.py +++ b/openpype/hosts/blender/plugins/create/create_blendScene.py @@ -40,29 +40,13 @@ class CreateBlendScene(plugin.Creator): self.data['task'] = get_current_task_name() lib.imprint(asset_group, self.data) - try: - area = next( - area for area in bpy.context.window.screen.areas - if area.type == 'OUTLINER') - region = next( - region for region in area.regions - if region.type == 'WINDOW') - except StopIteration as e: - raise RuntimeError("Could not find outliner. An outliner space " - "must be in the main Blender window.") from e + if (self.options or {}).get("useSelection"): + selection = lib.get_selection(include_collections=True) - with bpy.context.temp_override( - window=bpy.context.window, - area=area, - region=region, - screen=bpy.context.window.screen - ): - ids = bpy.context.selected_ids - - for id in ids: - if isinstance(id, bpy.types.Collection): - asset_group.children.link(id) - elif isinstance(id, bpy.types.Object): - asset_group.objects.link(id) + for data in selection: + if isinstance(data, bpy.types.Collection): + asset_group.children.link(data) + elif isinstance(data, bpy.types.Object): + asset_group.objects.link(data) return asset_group From f3de6175bcb1bbbd5105602023be05fac3f717dc Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 10:44:37 +0000 Subject: [PATCH 352/690] Hound fixes --- openpype/hosts/blender/api/lib.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/api/lib.py b/openpype/hosts/blender/api/lib.py index 2f33fd25ad..1f68dd0839 100644 --- a/openpype/hosts/blender/api/lib.py +++ b/openpype/hosts/blender/api/lib.py @@ -287,7 +287,7 @@ def get_selected_collections(): if region.type == 'WINDOW') except StopIteration as e: raise RuntimeError("Could not find outliner. An outliner space " - "must be in the main Blender window.") from e + "must be in the main Blender window.") from e with bpy.context.temp_override( window=bpy.context.window, @@ -311,7 +311,7 @@ def get_selection(include_collections: bool = False) -> List[bpy.types.Object]: Returns: List[bpy.types.Object]: A list of selected objects. """ - selection = [obj for obj in bpy.context.scene.objects if obj.select_get()] + selection = [obj for obj in bpy.context.scene.objects if obj.select_get()] if include_collections: selection.extend(get_selected_collections()) From a023183ca2f24a634b3377fde17ea394ec46a38f Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 11:08:36 +0000 Subject: [PATCH 353/690] Fix potential problem when removing data --- .../blender/plugins/load/load_blendscene.py | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/openpype/hosts/blender/plugins/load/load_blendscene.py b/openpype/hosts/blender/plugins/load/load_blendscene.py index b1b2c3ba79..2c955af9e8 100644 --- a/openpype/hosts/blender/plugins/load/load_blendscene.py +++ b/openpype/hosts/blender/plugins/load/load_blendscene.py @@ -180,7 +180,7 @@ class BlendSceneLoader(plugin.AssetLoader): avalon_container = bpy.data.collections.get(AVALON_CONTAINERS) avalon_container.children.link(asset_group) - # Restore the old data, but reset memebers, as they don't exist anymore + # Restore the old data, but reset members, as they don't exist anymore # This avoids a crash, because the memory addresses of those members # are not valid anymore old_data["members"] = [] @@ -202,22 +202,20 @@ class BlendSceneLoader(plugin.AssetLoader): group_name = container["objectName"] asset_group = bpy.data.collections.get(group_name) - attrs = [ - attr for attr in dir(bpy.data) - if isinstance( - getattr(bpy.data, attr), - bpy.types.bpy_prop_collection - ) - ] + members = set(asset_group.get(AVALON_PROPERTY).get("members", [])) - members = asset_group.get(AVALON_PROPERTY).get("members", []) + if members: + for attr_name in dir(bpy.data): + attr = getattr(bpy.data, attr_name) + if not isinstance(attr, bpy.types.bpy_prop_collection): + continue - for attr in attrs: - for data in getattr(bpy.data, attr): - if data in members: - # Skip the asset group - if data == asset_group: + # ensure to make a list copy because we + # we remove members as we iterate + for data in list(attr): + if data not in members or data == asset_group: continue - getattr(bpy.data, attr).remove(data) + + attr.remove(data) bpy.data.collections.remove(asset_group) From 8a040ad0a4d88b99eca7423e6bea2ea04e183a29 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 12:23:46 +0100 Subject: [PATCH 354/690] pass in variant to 'get_addons_settings' --- openpype/settings/ayon_settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 5eb68e3972..67ef109d8b 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -1497,7 +1497,8 @@ class _AyonSettingsCache: if cls._use_bundles(): value = ayon_api.get_addons_settings( bundle_name=cls._get_bundle_name(), - project_name=project_name + project_name=project_name, + variant=cls._get_variant() ) else: value = ayon_api.get_addons_settings(project_name) From 2c0d1b5c2bd3efb9e0740b0d5324a588533459e1 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 13:56:08 +0100 Subject: [PATCH 355/690] improving the logic for handles operation --- openpype/hosts/resolve/api/plugin.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 09c5a69d73..886615c7aa 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -410,10 +410,16 @@ class ClipLoader: source_duration = int(_clip_property("Frames")) # get version data frame data from db - frame_start = self.data["versionData"].get("frameStart") - frame_end = self.data["versionData"].get("frameEnd") - handle_start = self.data["versionData"].get("handleStart") - handle_end = self.data["versionData"].get("handleEnd") + version_data = self.data["versionData"] + frame_start = version_data.get("frameStart") + frame_end = version_data.get("frameEnd") + + if self.with_handles: + handle_start = version_data.get("handleStart") or 0 + handle_end = version_data.get("handleEnd") or 0 + else: + handle_start = 0 + handle_end = 0 """ There are cases where representation could be published without @@ -434,8 +440,8 @@ class ClipLoader: if ( frame_start is None or frame_end is None or - handle_start is None or - handle_end is None + handle_start is 0 or + handle_end is 0 ): # if not then rather assume that source has no handles source_with_handles = False @@ -464,12 +470,11 @@ class ClipLoader: timeline_in = int( timeline_start + self.data["assetData"]["clipIn"]) - # only exclude handles if source has no handles or # if user wants to load without handles if ( - not self.with_handles - or not source_with_handles + not self.with_handles # set by user + or not source_with_handles # result of source duration check ): source_in += handle_start source_out -= handle_end From a4dbc1958011cb0fbdeef68499797606c5fabc51 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 12:56:34 +0000 Subject: [PATCH 356/690] Changed validator to work with other families as well --- .../plugins/publish/validate_instance_empty.py | 17 +++++++++++++---- .../blender/server/settings/publish_plugins.py | 9 ++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/validate_instance_empty.py b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py index 66d8b45e1e..5abfd6dee8 100644 --- a/openpype/hosts/blender/plugins/publish/validate_instance_empty.py +++ b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py @@ -8,11 +8,20 @@ class ValidateInstanceEmpty(pyblish.api.InstancePlugin): order = pyblish.api.ValidatorOrder - 0.01 hosts = ["blender"] - families = ["blendScene"] + families = ["model", "pointcache", "rig", "camera" "layout", "blendScene"] label = "Validate Instance is not Empty" optional = False def process(self, instance): - collection = bpy.data.collections[instance.name] - if not (collection.objects or collection.children): - raise RuntimeError(f"Instance {instance.name} is empty.") + self.log.debug(instance) + self.log.debug(instance.data) + if instance.data["family"] == "blendScene": + # blendScene instances are collections + collection = bpy.data.collections[instance.name] + if not (collection.objects or collection.children): + raise RuntimeError(f"Instance {instance.name} is empty.") + else: + # All other instances are objects + asset_group = bpy.data.objects[instance.name] + if not asset_group.children: + raise RuntimeError(f"Instance {instance.name} is empty.") diff --git a/server_addon/blender/server/settings/publish_plugins.py b/server_addon/blender/server/settings/publish_plugins.py index bb68b40cbb..1c4ad0c6fd 100644 --- a/server_addon/blender/server/settings/publish_plugins.py +++ b/server_addon/blender/server/settings/publish_plugins.py @@ -67,6 +67,10 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=ValidateFileSavedModel, title="Validate File Saved", ) + ValidateInstanceEmpty: ValidatePluginModel = Field( + default_factory=ValidatePluginModel, + title="Validate Instance is not Empty" + ) ValidateMeshHasUvs: ValidatePluginModel = Field( default_factory=ValidatePluginModel, title="Validate Mesh Has Uvs", @@ -84,11 +88,6 @@ class PublishPuginsModel(BaseSettingsModel): default_factory=ValidatePluginModel, title="Validate No Colons In Name" ) - ValidateInstanceEmpty: ValidatePluginModel = Field( - default_factory=ValidatePluginModel, - title="Validate Instance is not Empty", - section="BlendScene Validators" - ) ValidateRenderCameraIsSet: ValidatePluginModel = Field( default_factory=ValidatePluginModel, title="Validate Render Camera Is Set", From cab0a6a3ee661828d694297d2229721dc0a2b969 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 13:03:46 +0000 Subject: [PATCH 357/690] Improved formatting --- openpype/hosts/blender/plugins/publish/extract_blend.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/extract_blend.py b/openpype/hosts/blender/plugins/publish/extract_blend.py index f29dae7f69..17e574c1be 100644 --- a/openpype/hosts/blender/plugins/publish/extract_blend.py +++ b/openpype/hosts/blender/plugins/publish/extract_blend.py @@ -28,11 +28,13 @@ class ExtractBlend(publish.Extractor): for data in instance: data_blocks.add(data) # Pack used images in the blend files. - if not(isinstance(data, bpy.types.Object) and data.type == 'MESH'): + if not ( + isinstance(data, bpy.types.Object) and data.type == 'MESH' + ): continue for material_slot in data.material_slots: mat = material_slot.material - if not(mat and mat.use_nodes): + if not (mat and mat.use_nodes): continue tree = mat.node_tree if tree.type != 'SHADER': From 12c8d3d2f8d79dbadca22efe8cc691c998def4a1 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 21:17:29 +0800 Subject: [PATCH 358/690] add supports for ayon settings --- openpype/settings/ayon_settings.py | 9 +++------ server_addon/max/server/settings/publishers.py | 11 ++++------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 8fd7f990c4..eb7e3a2d0f 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -650,14 +650,11 @@ def _convert_3dsmax_project_settings(ayon_settings, output): ayon_publish["ValidateAttributes"]["attributes"] = attributes if "ValidateLoadedPlugin" in ayon_publish: - new_plugin_mapping = {} loaded_plugin = ( - ayon_publish["ValidateLoadedPlugin"] + ayon_publish["ValidateLoadedPlugin"]["family_plugins_mapping"] ) - for item in loaded_plugin["family_plugins_mapping"]: - name = item.pop("name") - new_plugin_mapping[name] = item - loaded_plugin["family_plugins_mapping"] = new_plugin_mapping + for item in loaded_plugin: + item["families"] = item.pop("product_types") output["max"] = ayon_max diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index a752d8cb74..eeb6478216 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -29,7 +29,10 @@ class ValidateAttributesModel(BaseSettingsModel): class FamilyMappingItemModel(BaseSettingsModel): _layout = "compact" - name: str = Field("", title="Product type") + product_types: list[str] = Field( + default_factory=list, + title="Product Types" + ) plugins: list[str] = Field( default_factory=list, title="Plugins" @@ -44,12 +47,6 @@ class ValidateLoadedPluginModel(BaseSettingsModel): title="Family Plugins Mapping" ) - # This is to validate unique names (like in dict) - @validator("family_plugins_mapping") - def validate_unique_outputs(cls, value): - ensure_unique_names(value) - return value - class BasicValidateModel(BaseSettingsModel): enabled: bool = Field(title="Enabled") From e0fba84c9293fa6fe7d9ddb5aa5e1783faaa56d7 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 21:17:42 +0800 Subject: [PATCH 359/690] add supports for ayon settings --- server_addon/max/server/settings/publishers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/max/server/settings/publishers.py b/server_addon/max/server/settings/publishers.py index eeb6478216..4b6429250f 100644 --- a/server_addon/max/server/settings/publishers.py +++ b/server_addon/max/server/settings/publishers.py @@ -1,7 +1,7 @@ import json from pydantic import Field, validator -from ayon_server.settings import BaseSettingsModel, ensure_unique_names +from ayon_server.settings import BaseSettingsModel from ayon_server.exceptions import BadRequestException From 25be7762f18518ffacc3f0ac511f647025b6fbb0 Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Thu, 9 Nov 2023 21:19:14 +0800 Subject: [PATCH 360/690] hound --- .../max/plugins/publish/validate_loaded_plugin.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py index 7450c8f971..ea2fee353d 100644 --- a/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py +++ b/openpype/hosts/max/plugins/publish/validate_loaded_plugin.py @@ -39,7 +39,7 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, instance_families = {instance.data["family"]} instance_families.update(instance.data.get("families", [])) cls.log.debug("Checking plug-in validation " - f"for instance families: {instance_families}") + f"for instance families: {instance_families}") all_required_plugins = set() for mapping in family_plugins_mapping: @@ -47,14 +47,16 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, if not mapping: return - match_families = {fam for fam in mapping["families"] if fam.strip()} + match_families = {fam for fam in mapping["families"] + if fam.strip()} has_match = "*" in match_families or match_families.intersection( instance_families) if not has_match: continue - cls.log.debug(f"Found plug-in family requirements: {match_families}") + cls.log.debug( + f"Found plug-in family requirements: {match_families}") required_plugins = [ # match lowercase and format with os.environ to allow # plugin names defined by max version, e.g. {3DSMAX_VERSION} @@ -124,7 +126,8 @@ class ValidateLoadedPlugin(OptionalPyblishPluginMixin, plugin_index = available_plugins.get(invalid_plugin) if plugin_index is None: - cls.log.warning(f"Can't enable missing plugin: {invalid_plugin}") + cls.log.warning( + f"Can't enable missing plugin: {invalid_plugin}") continue if not rt.pluginManager.isPluginDllLoaded(plugin_index): From 1e0f44923909de38a76b58e59588d3c417240a7f Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 14:32:57 +0100 Subject: [PATCH 361/690] implemented 'get_ayon_server_api_connection' to help create connection --- openpype/client/__init__.py | 3 +++ openpype/client/server/utils.py | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/openpype/client/__init__.py b/openpype/client/__init__.py index 7831afd8ad..fe6dc97877 100644 --- a/openpype/client/__init__.py +++ b/openpype/client/__init__.py @@ -1,6 +1,7 @@ from .mongo import ( OpenPypeMongoConnection, ) +from .server.utils import get_ayon_server_api_connection from .entities import ( get_projects, @@ -59,6 +60,8 @@ from .operations import ( __all__ = ( "OpenPypeMongoConnection", + "get_ayon_server_api_connection", + "get_projects", "get_project", "get_whole_project", diff --git a/openpype/client/server/utils.py b/openpype/client/server/utils.py index ed128cfad9..a9dcf539bd 100644 --- a/openpype/client/server/utils.py +++ b/openpype/client/server/utils.py @@ -1,8 +1,33 @@ +import os import uuid +import ayon_api + from openpype.client.operations_base import REMOVED_VALUE +class _GlobalCache: + initialized = False + + +def get_ayon_server_api_connection(): + if _GlobalCache.initialized: + con = ayon_api.get_server_api_connection() + else: + from openpype.lib.local_settings import get_local_site_id + + _GlobalCache.initialized = True + site_id = get_local_site_id() + version = os.getenv("AYON_VERSION") + if ayon_api.is_connection_created(): + con = ayon_api.get_server_api_connection() + con.set_site_id(site_id) + con.set_client_version(version) + else: + con = ayon_api.create_connection(site_id, version) + return con + + def create_entity_id(): return uuid.uuid1().hex From 8e0513fe548b15aed1edcda6f83a38c919758241 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 14:33:19 +0100 Subject: [PATCH 362/690] use 'get_ayon_server_api_connection' in server functions --- openpype/client/server/entities.py | 27 +++++++++++++------------- openpype/client/server/entity_links.py | 14 ++++++------- openpype/client/server/operations.py | 11 +++++------ 3 files changed, 25 insertions(+), 27 deletions(-) diff --git a/openpype/client/server/entities.py b/openpype/client/server/entities.py index 16223d3d91..b41727a797 100644 --- a/openpype/client/server/entities.py +++ b/openpype/client/server/entities.py @@ -1,9 +1,8 @@ import collections -from ayon_api import get_server_api_connection - from openpype.client.mongo.operations import CURRENT_THUMBNAIL_SCHEMA +from .utils import get_ayon_server_api_connection from .openpype_comp import get_folders_with_tasks from .conversion_utils import ( project_fields_v3_to_v4, @@ -37,7 +36,7 @@ def get_projects(active=True, inactive=False, library=None, fields=None): elif inactive: active = False - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = project_fields_v3_to_v4(fields, con) for project in con.get_projects(active, library, fields=fields): yield convert_v4_project_to_v3(project) @@ -45,7 +44,7 @@ def get_projects(active=True, inactive=False, library=None, fields=None): def get_project(project_name, active=True, inactive=False, fields=None): # Skip if both are disabled - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = project_fields_v3_to_v4(fields, con) return convert_v4_project_to_v3( con.get_project(project_name, fields=fields) @@ -66,7 +65,7 @@ def _get_subsets( fields=None ): # Convert fields and add minimum required fields - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = subset_fields_v3_to_v4(fields, con) if fields is not None: for key in ( @@ -102,7 +101,7 @@ def _get_versions( active=None, fields=None ): - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = version_fields_v3_to_v4(fields, con) @@ -198,7 +197,7 @@ def get_assets( if archived: active = None - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = folder_fields_v3_to_v4(fields, con) kwargs = dict( folder_ids=asset_ids, @@ -236,7 +235,7 @@ def get_archived_assets( def get_asset_ids_with_subsets(project_name, asset_ids=None): - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.get_folder_ids_with_products(project_name, asset_ids) @@ -282,7 +281,7 @@ def get_subsets( def get_subset_families(project_name, subset_ids=None): - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.get_product_type_names(project_name, subset_ids) @@ -430,7 +429,7 @@ def get_output_link_versions(project_name, version_id, fields=None): if not version_id: return [] - con = get_server_api_connection() + con = get_ayon_server_api_connection() version_links = con.get_version_links( project_name, version_id, link_direction="out") @@ -446,7 +445,7 @@ def get_output_link_versions(project_name, version_id, fields=None): def version_is_latest(project_name, version_id): - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.version_is_latest(project_name, version_id) @@ -501,7 +500,7 @@ def get_representations( else: active = None - con = get_server_api_connection() + con = get_ayon_server_api_connection() fields = representation_fields_v3_to_v4(fields, con) if fields and active is not None: fields.add("active") @@ -535,7 +534,7 @@ def get_representations_parents(project_name, representations): repre["_id"] for repre in representations } - con = get_server_api_connection() + con = get_ayon_server_api_connection() parents_by_repre_id = con.get_representations_parents(project_name, repre_ids) folder_ids = set() @@ -677,7 +676,7 @@ def get_workfile_info( if not asset_id or not task_name or not filename: return None - con = get_server_api_connection() + con = get_ayon_server_api_connection() task = con.get_task_by_name( project_name, asset_id, task_name, fields=["id", "name", "folderId"] ) diff --git a/openpype/client/server/entity_links.py b/openpype/client/server/entity_links.py index d8395aabe7..368dcdcb9d 100644 --- a/openpype/client/server/entity_links.py +++ b/openpype/client/server/entity_links.py @@ -1,6 +1,4 @@ -import ayon_api -from ayon_api import get_folder_links, get_versions_links - +from .utils import get_ayon_server_api_connection from .entities import get_assets, get_representation_by_id @@ -28,7 +26,8 @@ def get_linked_asset_ids(project_name, asset_doc=None, asset_id=None): if not asset_id: asset_id = asset_doc["_id"] - links = get_folder_links(project_name, asset_id, link_direction="in") + con = get_ayon_server_api_connection() + links = con.get_folder_links(project_name, asset_id, link_direction="in") return [ link["entityId"] for link in links @@ -115,6 +114,7 @@ def get_linked_representation_id( if link_type: link_types = [link_type] + con = get_ayon_server_api_connection() # Store already found version ids to avoid recursion, and also to store # output -> Don't forget to remove 'version_id' at the end!!! linked_version_ids = {version_id} @@ -124,7 +124,7 @@ def get_linked_representation_id( if not versions_to_check: break - links = get_versions_links( + links = con.get_versions_links( project_name, versions_to_check, link_types=link_types, @@ -145,8 +145,8 @@ def get_linked_representation_id( linked_version_ids.remove(version_id) if not linked_version_ids: return [] - - representations = ayon_api.get_representations( + con = get_ayon_server_api_connection() + representations = con.get_representations( project_name, version_ids=linked_version_ids, fields=["id"]) diff --git a/openpype/client/server/operations.py b/openpype/client/server/operations.py index 5b38405c34..eddc1eaf60 100644 --- a/openpype/client/server/operations.py +++ b/openpype/client/server/operations.py @@ -5,7 +5,6 @@ import uuid import datetime from bson.objectid import ObjectId -from ayon_api import get_server_api_connection from openpype.client.operations_base import ( REMOVED_VALUE, @@ -41,7 +40,7 @@ from .conversion_utils import ( convert_update_representation_to_v4, convert_update_workfile_info_to_v4, ) -from .utils import create_entity_id +from .utils import create_entity_id, get_ayon_server_api_connection def _create_or_convert_to_id(entity_id=None): @@ -680,7 +679,7 @@ class OperationsSession(BaseOperationsSession): def __init__(self, con=None, *args, **kwargs): super(OperationsSession, self).__init__(*args, **kwargs) if con is None: - con = get_server_api_connection() + con = get_ayon_server_api_connection() self._con = con self._project_cache = {} self._nested_operations = collections.defaultdict(list) @@ -858,7 +857,7 @@ def create_project( """ if con is None: - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.create_project( project_name, @@ -870,12 +869,12 @@ def create_project( def delete_project(project_name, con=None): if con is None: - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.delete_project(project_name) def create_thumbnail(project_name, src_filepath, thumbnail_id=None, con=None): if con is None: - con = get_server_api_connection() + con = get_ayon_server_api_connection() return con.create_thumbnail(project_name, src_filepath, thumbnail_id) From 14ddd5cb51e8785f27b5be5406b358792bbe6328 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 14:36:42 +0100 Subject: [PATCH 363/690] use 'get_ayon_server_api_connection' in core functions --- openpype/lib/local_settings.py | 6 +++--- openpype/modules/base.py | 10 +++++++--- openpype/pipeline/anatomy.py | 6 +++--- openpype/pipeline/context_tools.py | 6 ++++++ openpype/pipeline/thumbnail.py | 6 ++---- openpype/settings/ayon_settings.py | 28 +++++++++++++++++++--------- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/openpype/lib/local_settings.py b/openpype/lib/local_settings.py index 9b780fd88a..ea42d2f0b5 100644 --- a/openpype/lib/local_settings.py +++ b/openpype/lib/local_settings.py @@ -36,6 +36,7 @@ from openpype.settings import ( ) from openpype.client.mongo import validate_mongo_connection +from openpype.client import get_ayon_server_api_connection _PLACEHOLDER = object() @@ -613,9 +614,8 @@ def get_openpype_username(): """ if AYON_SERVER_ENABLED: - import ayon_api - - return ayon_api.get_user()["name"] + con = get_ayon_server_api_connection() + return con.get_user()["name"] username = os.environ.get("OPENPYPE_USERNAME") if not username: diff --git a/openpype/modules/base.py b/openpype/modules/base.py index 457e29905d..4636906cec 100644 --- a/openpype/modules/base.py +++ b/openpype/modules/base.py @@ -16,9 +16,9 @@ from abc import ABCMeta, abstractmethod import six import appdirs -import ayon_api from openpype import AYON_SERVER_ENABLED +from openpype.client import get_ayon_server_api_connection from openpype.settings import ( get_system_settings, SYSTEM_SETTINGS_KEY, @@ -319,8 +319,11 @@ def load_modules(force=False): def _get_ayon_bundle_data(): + con = get_ayon_server_api_connection() + bundles = con.get_bundles()["bundles"] + bundle_name = os.getenv("AYON_BUNDLE_NAME") - bundles = ayon_api.get_bundles()["bundles"] + return next( ( bundle @@ -345,7 +348,8 @@ def _get_ayon_addons_information(bundle_info): output = [] bundle_addons = bundle_info["addons"] - addons = ayon_api.get_addons_info()["addons"] + con = get_ayon_server_api_connection() + addons = con.get_addons_info()["addons"] for addon in addons: name = addon["name"] versions = addon.get("versions") diff --git a/openpype/pipeline/anatomy.py b/openpype/pipeline/anatomy.py index 029b5cc1ff..0e5ab1d42e 100644 --- a/openpype/pipeline/anatomy.py +++ b/openpype/pipeline/anatomy.py @@ -5,7 +5,6 @@ import platform import collections import numbers -import ayon_api import six import time @@ -16,7 +15,7 @@ from openpype.settings.lib import ( from openpype.settings.constants import ( DEFAULT_PROJECT_KEY ) -from openpype.client import get_project +from openpype.client import get_project, get_ayon_server_api_connection from openpype.lib import Logger, get_local_site_id from openpype.lib.path_templates import ( TemplateUnsolved, @@ -479,7 +478,8 @@ class Anatomy(BaseAnatomy): if AYON_SERVER_ENABLED: if not project_name: return - return ayon_api.get_project_roots_for_site( + con = get_ayon_server_api_connection() + return con.get_project_roots_for_site( project_name, get_local_site_id() ) diff --git a/openpype/pipeline/context_tools.py b/openpype/pipeline/context_tools.py index 5afdb30f7b..034bbc0070 100644 --- a/openpype/pipeline/context_tools.py +++ b/openpype/pipeline/context_tools.py @@ -11,12 +11,14 @@ import pyblish.api from pyblish.lib import MessageHandler import openpype +from openpype import AYON_SERVER_ENABLED from openpype.host import HostBase from openpype.client import ( get_project, get_asset_by_id, get_asset_by_name, version_is_latest, + get_ayon_server_api_connection, ) from openpype.lib.events import emit_event from openpype.modules import load_modules, ModulesManager @@ -105,6 +107,10 @@ def install_host(host): _is_installed = True + # Make sure global AYON connection has set site id and version + if AYON_SERVER_ENABLED: + get_ayon_server_api_connection() + legacy_io.install() modules_manager = _get_modules_manager() diff --git a/openpype/pipeline/thumbnail.py b/openpype/pipeline/thumbnail.py index 63c55d0c19..14fb8b06fc 100644 --- a/openpype/pipeline/thumbnail.py +++ b/openpype/pipeline/thumbnail.py @@ -4,7 +4,7 @@ import logging from openpype import AYON_SERVER_ENABLED from openpype.lib import Logger -from openpype.client import get_project +from openpype.client import get_project, get_ayon_server_api_connection from . import legacy_io from .anatomy import Anatomy from .plugin_discover import ( @@ -153,8 +153,6 @@ class ServerThumbnailResolver(ThumbnailResolver): if not entity_type or not entity_id: return None - import ayon_api - project_name = self.dbcon.active_project() thumbnail_id = thumbnail_entity["_id"] @@ -169,7 +167,7 @@ class ServerThumbnailResolver(ThumbnailResolver): # NOTE Use 'get_server_api_connection' because public function # 'get_thumbnail_by_id' does not return output of 'ServerAPI' # method. - con = ayon_api.get_server_api_connection() + con = get_ayon_server_api_connection() if hasattr(con, "get_thumbnail_by_id"): result = con.get_thumbnail_by_id(thumbnail_id) if result.is_valid: diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 67ef109d8b..745cadfc6e 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -20,7 +20,8 @@ import copy import time import six -import ayon_api + +from openpype.client import get_ayon_server_api_connection def _convert_color(color_value): @@ -1445,7 +1446,8 @@ class _AyonSettingsCache: @classmethod def _use_bundles(cls): if _AyonSettingsCache.use_bundles is None: - major, minor, _, _, _ = ayon_api.get_server_version_tuple() + con = get_ayon_server_api_connection() + major, minor, _, _, _ = con.get_server_version_tuple() use_bundles = True if (major, minor) < (0, 3): use_bundles = False @@ -1462,6 +1464,8 @@ class _AyonSettingsCache: variant = cls._get_dev_mode_settings_variant() elif is_staging_enabled(): variant = "staging" + + # Cache variant _AyonSettingsCache.variant = variant return _AyonSettingsCache.variant @@ -1477,8 +1481,9 @@ class _AyonSettingsCache: str: Name of settings variant. """ - bundles = ayon_api.get_bundles() - user = ayon_api.get_user() + con = get_ayon_server_api_connection() + bundles = con.get_bundles() + user = con.get_user() username = user["name"] for bundle in bundles["bundles"]: if ( @@ -1494,21 +1499,23 @@ class _AyonSettingsCache: def get_value_by_project(cls, project_name): cache_item = _AyonSettingsCache.cache_by_project_name[project_name] if cache_item.is_outdated: + con = get_ayon_server_api_connection() if cls._use_bundles(): - value = ayon_api.get_addons_settings( + value = con.get_addons_settings( bundle_name=cls._get_bundle_name(), project_name=project_name, variant=cls._get_variant() ) else: - value = ayon_api.get_addons_settings(project_name) + value = con.get_addons_settings(project_name) cache_item.update_value(value) return cache_item.get_value() @classmethod def _get_addon_versions_from_bundle(cls): + con = get_ayon_server_api_connection() expected_bundle = cls._get_bundle_name() - bundles = ayon_api.get_bundles()["bundles"] + bundles = con.get_bundles()["bundles"] bundle = next( ( bundle @@ -1528,8 +1535,11 @@ class _AyonSettingsCache: if cls._use_bundles(): addons = cls._get_addon_versions_from_bundle() else: - settings_data = ayon_api.get_addons_settings( - only_values=False, variant=cls._get_variant()) + con = get_ayon_server_api_connection() + settings_data = con.get_addons_settings( + only_values=False, + variant=cls._get_variant() + ) addons = settings_data["versions"] cache_item.update_value(addons) From e23a2b5e09dfb13c5ed1587a450bd5de89b7ef35 Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 14:36:55 +0100 Subject: [PATCH 364/690] set default variant in ayon_settings --- openpype/settings/ayon_settings.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openpype/settings/ayon_settings.py b/openpype/settings/ayon_settings.py index 745cadfc6e..f0b4528802 100644 --- a/openpype/settings/ayon_settings.py +++ b/openpype/settings/ayon_settings.py @@ -1467,6 +1467,10 @@ class _AyonSettingsCache: # Cache variant _AyonSettingsCache.variant = variant + + # Set the variant to global ayon api connection + con = get_ayon_server_api_connection() + con.set_default_settings_variant(variant) return _AyonSettingsCache.variant @classmethod From 6fa92ebc14204c3c723a0b2a1d42ba492d10ff30 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 14:40:33 +0100 Subject: [PATCH 365/690] resolve: clip data should be integer rather then timecode --- openpype/hosts/resolve/api/lib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/hosts/resolve/api/lib.py b/openpype/hosts/resolve/api/lib.py index aef9caca78..3866477c77 100644 --- a/openpype/hosts/resolve/api/lib.py +++ b/openpype/hosts/resolve/api/lib.py @@ -298,7 +298,7 @@ def create_timeline_item( if source_end: clip_data["endFrame"] = source_end if timecode_in: - clip_data["recordFrame"] = timecode_in + clip_data["recordFrame"] = timeline_in # add to timeline media_pool.AppendToTimeline([clip_data]) From 85bad0ae3d6f43732b9087583af2e09de55fed40 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 14:42:30 +0100 Subject: [PATCH 366/690] hound --- openpype/hosts/resolve/api/plugin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 886615c7aa..7cf5913b67 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -440,8 +440,8 @@ class ClipLoader: if ( frame_start is None or frame_end is None or - handle_start is 0 or - handle_end is 0 + handle_start == 0 or + handle_end == 0 ): # if not then rather assume that source has no handles source_with_handles = False @@ -473,8 +473,8 @@ class ClipLoader: # only exclude handles if source has no handles or # if user wants to load without handles if ( - not self.with_handles # set by user - or not source_with_handles # result of source duration check + not self.with_handles # set by user + or not source_with_handles # result of source duration check ): source_in += handle_start source_out -= handle_end From 0b8dde268708594e23d1f305a7bfbd3da99a55d9 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 15:47:14 +0100 Subject: [PATCH 367/690] resolve: creating clips with folder path also converting dict() to {} --- openpype/hosts/resolve/api/plugin.py | 29 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/resolve/api/plugin.py b/openpype/hosts/resolve/api/plugin.py index 49c3b484d2..197f288150 100644 --- a/openpype/hosts/resolve/api/plugin.py +++ b/openpype/hosts/resolve/api/plugin.py @@ -19,7 +19,7 @@ from .menu import load_stylesheet class CreatorWidget(QtWidgets.QDialog): # output items - items = dict() + items = {} def __init__(self, name, info, ui_inputs, parent=None): super(CreatorWidget, self).__init__(parent) @@ -101,7 +101,7 @@ class CreatorWidget(QtWidgets.QDialog): self.close() def value(self, data, new_data=None): - new_data = new_data or dict() + new_data = new_data or {} for k, v in data.items(): new_data[k] = { "target": None, @@ -290,7 +290,7 @@ class Spacer(QtWidgets.QWidget): class ClipLoader: active_bin = None - data = dict() + data = {} def __init__(self, loader_obj, context, **options): """ Initialize object @@ -588,8 +588,8 @@ class PublishClip: Returns: hiero.core.TrackItem: hiero track item object with openpype tag """ - vertical_clip_match = dict() - tag_data = dict() + vertical_clip_match = {} + tag_data = {} types = { "shot": "shot", "folder": "folder", @@ -665,15 +665,23 @@ class PublishClip: new_name = self.tag_data.pop("newClipName") if self.rename: - self.tag_data["asset"] = new_name + self.tag_data["asset_name"] = new_name else: - self.tag_data["asset"] = self.ti_name + self.tag_data["asset_name"] = self.ti_name + # AYON unique identifier + folder_path = "/{}/{}".format( + self.tag_data["hierarchy"], + self.tag_data["asset_name"] + ) + self.tag_data["folder_path"] = folder_path + + # create new name for track item if not lib.pype_marker_workflow: # create compound clip workflow lib.create_compound_clip( self.timeline_item_data, - self.tag_data["asset"], + self.tag_data["asset_name"], self.mp_folder ) @@ -765,7 +773,7 @@ class PublishClip: # increasing steps by index of rename iteration self.count_steps *= self.rename_index - hierarchy_formatting_data = dict() + hierarchy_formatting_data = {} _data = self.timeline_item_default_data.copy() if self.ui_inputs: # adding tag metadata from ui @@ -854,8 +862,7 @@ class PublishClip: "parents": self.parents, "hierarchyData": hierarchy_formatting_data, "subset": self.subset, - "family": self.subset_family, - "families": ["clip"] + "family": self.subset_family } def _convert_to_entity(self, key): From d07898a3286b139c0d48bc14fb16b1417adcd8e5 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 15:47:50 +0100 Subject: [PATCH 368/690] resolve: collect instances with folder path --- .../plugins/publish/precollect_instances.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/resolve/plugins/publish/precollect_instances.py b/openpype/hosts/resolve/plugins/publish/precollect_instances.py index 8ec169ad65..58c1c85276 100644 --- a/openpype/hosts/resolve/plugins/publish/precollect_instances.py +++ b/openpype/hosts/resolve/plugins/publish/precollect_instances.py @@ -9,6 +9,7 @@ from openpype.hosts.resolve.api.lib import ( get_publish_attribute, get_otio_clip_instance_data, ) +from openpype import AYON_SERVER_ENABLED class PrecollectInstances(pyblish.api.ContextPlugin): @@ -29,7 +30,7 @@ class PrecollectInstances(pyblish.api.ContextPlugin): for timeline_item_data in selected_timeline_items: - data = dict() + data = {} timeline_item = timeline_item_data["clip"]["item"] # get pype tag data @@ -60,24 +61,25 @@ class PrecollectInstances(pyblish.api.ContextPlugin): if k not in ("id", "applieswhole", "label") }) - asset = tag_data["asset"] + if AYON_SERVER_ENABLED: + asset = tag_data["folder_path"] + else: + asset = tag_data["asset_name"] + subset = tag_data["subset"] - # insert family into families - family = tag_data["family"] - families = [str(f) for f in tag_data["families"]] - families.insert(0, str(family)) - data.update({ - "name": "{} {} {}".format(asset, subset, families), + "name": "{}_{}".format(asset, subset), + "label": "{} {}".format(asset, subset), "asset": asset, "item": timeline_item, - "families": families, "publish": get_publish_attribute(timeline_item), "fps": context.data["fps"], "handleStart": handle_start, "handleEnd": handle_end, - "newAssetPublishing": True + "newAssetPublishing": True, + "families": ["clip"], + "isEditorial": True }) # otio clip data @@ -135,7 +137,8 @@ class PrecollectInstances(pyblish.api.ContextPlugin): family = "shot" data.update({ - "name": "{} {} {}".format(asset, subset, family), + "name": "{}_{}".format(asset, subset), + "label": "{} {}".format(asset, subset), "subset": subset, "asset": asset, "family": family, From 7cd98fe9033c17b4897208ab7c54bda5e7e53c45 Mon Sep 17 00:00:00 2001 From: Sharkitty Date: Thu, 9 Nov 2023 15:52:36 +0100 Subject: [PATCH 369/690] Remove deprecated code, use avalon instances in basecreator --- openpype/hosts/blender/api/plugin.py | 25 +++++----- .../blender/plugins/create/create_action.py | 25 ---------- .../plugins/create/create_animation.py | 37 -------------- .../blender/plugins/create/create_camera.py | 49 ------------------- .../blender/plugins/create/create_layout.py | 37 -------------- .../blender/plugins/create/create_model.py | 37 -------------- .../plugins/create/create_pointcache.py | 36 -------------- .../blender/plugins/create/create_review.py | 33 ------------- .../blender/plugins/create/create_rig.py | 37 -------------- 9 files changed, 11 insertions(+), 305 deletions(-) diff --git a/openpype/hosts/blender/api/plugin.py b/openpype/hosts/blender/api/plugin.py index 3ddc375670..629cb4dac9 100644 --- a/openpype/hosts/blender/api/plugin.py +++ b/openpype/hosts/blender/api/plugin.py @@ -144,18 +144,6 @@ class BaseCreator(Creator): """Base class for Blender Creator plug-ins.""" defaults = ['Main'] - # Deprecated? - def process(self): - collection = bpy.data.collections.new(name=self.data["subset"]) - bpy.context.scene.collection.children.link(collection) - imprint(collection, self.data) - - if (self.options or {}).get("useSelection"): - for obj in get_selection(): - collection.objects.link(obj) - - return collection - @staticmethod def cache_subsets(shared_data): """Cache instances for Creators shared data. @@ -233,8 +221,17 @@ class BaseCreator(Creator): pre_create_data(dict): Data based on pre creation attributes. Those may affect how creator works. """ - collection = bpy.data.collections.new(name=subset_name) - bpy.context.scene.collection.children.link(collection) + # Get Instance Container or create it if it does not exist + instances = bpy.data.collections.get(AVALON_INSTANCES) + if not instances: + instances = bpy.data.collections.new(name=AVALON_INSTANCES) + bpy.context.scene.collection.children.link(instances) + + # Create instance collection + collection = bpy.data.collections.new( + name=asset_name(instance_data["asset"], subset_name) + ) + instances.children.link(collection) collection[AVALON_PROPERTY] = instance_node = { "name": collection.name, diff --git a/openpype/hosts/blender/plugins/create/create_action.py b/openpype/hosts/blender/plugins/create/create_action.py index 7d00aa1dcb..9267fc0765 100644 --- a/openpype/hosts/blender/plugins/create/create_action.py +++ b/openpype/hosts/blender/plugins/create/create_action.py @@ -59,28 +59,3 @@ class CreateAction(openpype.hosts.blender.api.plugin.BaseCreator): collection.objects.link(empty_obj) return collection - - # Deprecated - def process(self): - - asset = self.data["asset"] - subset = self.data["subset"] - name = openpype.hosts.blender.api.plugin.asset_name(asset, subset) - collection = bpy.data.collections.new(name=name) - bpy.context.scene.collection.children.link(collection) - self.data['task'] = get_current_task_name() - lib.imprint(collection, self.data) - - if (self.options or {}).get("useSelection"): - for obj in lib.get_selection(): - if (obj.animation_data is not None - and obj.animation_data.action is not None): - - empty_obj = bpy.data.objects.new(name=name, - object_data=None) - empty_obj.animation_data_create() - empty_obj.animation_data.action = obj.animation_data.action - empty_obj.animation_data.action.name = name - collection.objects.link(empty_obj) - - return collection diff --git a/openpype/hosts/blender/plugins/create/create_animation.py b/openpype/hosts/blender/plugins/create/create_animation.py index 6cfd054e74..89567061b6 100644 --- a/openpype/hosts/blender/plugins/create/create_animation.py +++ b/openpype/hosts/blender/plugins/create/create_animation.py @@ -75,40 +75,3 @@ class CreateAnimation(plugin.BaseCreator): asset_group.objects.link(obj) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - # name = self.name - # if not name: - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - # asset_group = bpy.data.objects.new(name=name, object_data=None) - # asset_group.empty_display_type = 'SINGLE_ARROW' - asset_group = bpy.data.collections.new(name=name) - instances.children.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - if (self.options or {}).get("useSelection"): - selected = lib.get_selection() - for obj in selected: - asset_group.objects.link(obj) - elif (self.options or {}).get("asset_group"): - obj = (self.options or {}).get("asset_group") - asset_group.objects.link(obj) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_camera.py b/openpype/hosts/blender/plugins/create/create_camera.py index 5d9682e575..125514ae01 100644 --- a/openpype/hosts/blender/plugins/create/create_camera.py +++ b/openpype/hosts/blender/plugins/create/create_camera.py @@ -84,52 +84,3 @@ class CreateCamera(plugin.BaseCreator): bpy.ops.object.parent_set(keep_transform=True) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - print(f"self.data: {self.data}") - lib.imprint(asset_group, self.data) - - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - 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 - bpy.ops.object.parent_set(keep_transform=True) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_layout.py b/openpype/hosts/blender/plugins/create/create_layout.py index ed47b0632f..a6c7053cb2 100644 --- a/openpype/hosts/blender/plugins/create/create_layout.py +++ b/openpype/hosts/blender/plugins/create/create_layout.py @@ -73,40 +73,3 @@ class CreateLayout(plugin.BaseCreator): bpy.ops.object.parent_set(keep_transform=True) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - # Add selected objects to instance - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - bpy.ops.object.parent_set(keep_transform=True) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_model.py b/openpype/hosts/blender/plugins/create/create_model.py index 949fae0f76..8beb8025c4 100644 --- a/openpype/hosts/blender/plugins/create/create_model.py +++ b/openpype/hosts/blender/plugins/create/create_model.py @@ -73,40 +73,3 @@ class CreateModel(plugin.BaseCreator): bpy.ops.object.parent_set(keep_transform=True) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - # Add selected objects to instance - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - bpy.ops.object.parent_set(keep_transform=True) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_pointcache.py b/openpype/hosts/blender/plugins/create/create_pointcache.py index 2ad12caa9c..aa8b297d16 100644 --- a/openpype/hosts/blender/plugins/create/create_pointcache.py +++ b/openpype/hosts/blender/plugins/create/create_pointcache.py @@ -54,39 +54,3 @@ class CreatePointcache(plugin.BaseCreator): objects.extend(obj.children) return collection - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process) - ops.execute_in_main_thread(mti) - - def _process(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - # Add selected objects to instance - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - bpy.ops.object.parent_set(keep_transform=True) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_review.py b/openpype/hosts/blender/plugins/create/create_review.py index e8b893b4c0..13fa3b621f 100644 --- a/openpype/hosts/blender/plugins/create/create_review.py +++ b/openpype/hosts/blender/plugins/create/create_review.py @@ -71,36 +71,3 @@ class CreateReview(plugin.BaseCreator): asset_group.objects.link(obj) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - asset_group = bpy.data.collections.new(name=name) - instances.children.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - if (self.options or {}).get("useSelection"): - selected = lib.get_selection() - for obj in selected: - asset_group.objects.link(obj) - elif (self.options or {}).get("asset_group"): - obj = (self.options or {}).get("asset_group") - asset_group.objects.link(obj) - - return asset_group diff --git a/openpype/hosts/blender/plugins/create/create_rig.py b/openpype/hosts/blender/plugins/create/create_rig.py index 6223e64174..6682162f4b 100644 --- a/openpype/hosts/blender/plugins/create/create_rig.py +++ b/openpype/hosts/blender/plugins/create/create_rig.py @@ -73,40 +73,3 @@ class CreateRig(plugin.BaseCreator): bpy.ops.object.parent_set(keep_transform=True) return asset_group - - # Deprecated - def process(self): - """ Run the creator on Blender main thread""" - mti = ops.MainThreadItem(self._process_legacy) - ops.execute_in_main_thread(mti) - - # Deprecated - def _process_legacy(self): - # Get Instance Container or create it if it does not exist - instances = bpy.data.collections.get(AVALON_INSTANCES) - if not instances: - instances = bpy.data.collections.new(name=AVALON_INSTANCES) - bpy.context.scene.collection.children.link(instances) - - # Create instance object - asset = self.data["asset"] - subset = self.data["subset"] - name = plugin.asset_name(asset, subset) - asset_group = bpy.data.objects.new(name=name, object_data=None) - asset_group.empty_display_type = 'SINGLE_ARROW' - instances.objects.link(asset_group) - self.data['task'] = get_current_task_name() - lib.imprint(asset_group, self.data) - - # Add selected objects to instance - if (self.options or {}).get("useSelection"): - bpy.context.view_layer.objects.active = asset_group - selected = lib.get_selection() - for obj in selected: - if obj.parent in selected: - obj.select_set(False) - continue - selected.append(asset_group) - bpy.ops.object.parent_set(keep_transform=True) - - return asset_group From 42c61fa348ca6036cef594f0f6fe6932b3c41b5a Mon Sep 17 00:00:00 2001 From: Jakub Trllo Date: Thu, 9 Nov 2023 16:22:17 +0100 Subject: [PATCH 370/690] do not check for "/" if asset name is empty --- openpype/pipeline/create/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openpype/pipeline/create/context.py b/openpype/pipeline/create/context.py index e4dcedda2c..f32477dfb7 100644 --- a/openpype/pipeline/create/context.py +++ b/openpype/pipeline/create/context.py @@ -2283,7 +2283,7 @@ class CreateContext: if AYON_SERVER_ENABLED: asset_name = instance["folderPath"] - if "/" not in asset_name: + if asset_name and "/" not in asset_name: asset_docs = asset_docs_by_name.get(asset_name) if len(asset_docs) == 1: asset_name = get_asset_name_identifier(asset_docs[0]) From 573da36d4b12d58ab84110bbc46105be3f4e9e90 Mon Sep 17 00:00:00 2001 From: Jakub Jezek Date: Thu, 9 Nov 2023 16:32:20 +0100 Subject: [PATCH 371/690] workfile instance with support of folder path --- .../plugins/publish/extract_workfile.py | 1 + .../plugins/publish/precollect_workfile.py | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/openpype/hosts/resolve/plugins/publish/extract_workfile.py b/openpype/hosts/resolve/plugins/publish/extract_workfile.py index 535f879b58..db63487405 100644 --- a/openpype/hosts/resolve/plugins/publish/extract_workfile.py +++ b/openpype/hosts/resolve/plugins/publish/extract_workfile.py @@ -26,6 +26,7 @@ class ExtractWorkfile(publish.Extractor): resolve_workfile_ext = ".drp" drp_file_name = name + resolve_workfile_ext + drp_file_path = os.path.normpath( os.path.join(staging_dir, drp_file_name)) diff --git a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py index 39c28e29f5..ccc5fd86ff 100644 --- a/openpype/hosts/resolve/plugins/publish/precollect_workfile.py +++ b/openpype/hosts/resolve/plugins/publish/precollect_workfile.py @@ -3,6 +3,7 @@ from pprint import pformat from openpype import AYON_SERVER_ENABLED from openpype.pipeline import get_current_asset_name + from openpype.hosts.resolve import api as rapi from openpype.hosts.resolve.otio import davinci_export @@ -14,14 +15,12 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): order = pyblish.api.CollectorOrder - 0.5 def process(self, context): - current_asset = get_current_asset_name() - if AYON_SERVER_ENABLED: - # AYON compatibility split name and use last piece - asset_name = current_asset.split("/")[-1] - else: - asset_name = current_asset + current_asset_name = asset_name = get_current_asset_name() - subset = "workfile" + if AYON_SERVER_ENABLED: + asset_name = current_asset_name.split("/")[-1] + + subset = "workfileMain" project = rapi.get_current_project() fps = project.GetSetting("timelineFrameRate") video_tracks = rapi.get_video_track_names() @@ -31,8 +30,9 @@ class PrecollectWorkfile(pyblish.api.ContextPlugin): instance_data = { "name": "{}_{}".format(asset_name, subset), - "asset": current_asset, - "subset": "{}{}".format(asset_name, subset.capitalize()), + "label": "{} {}".format(current_asset_name, subset), + "asset": current_asset_name, + "subset": subset, "item": project, "family": "workfile", "families": [] From a0da4cd17f2a0809eb2d4904a48ec8a5f5c04ab1 Mon Sep 17 00:00:00 2001 From: Simone Barbieri Date: Thu, 9 Nov 2023 15:35:58 +0000 Subject: [PATCH 372/690] Changed how we get instance group in the validator --- .../blender/plugins/publish/collect_instances.py | 4 ++-- .../plugins/publish/validate_instance_empty.py | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/openpype/hosts/blender/plugins/publish/collect_instances.py b/openpype/hosts/blender/plugins/publish/collect_instances.py index ad2ce54147..2d56e5fd7b 100644 --- a/openpype/hosts/blender/plugins/publish/collect_instances.py +++ b/openpype/hosts/blender/plugins/publish/collect_instances.py @@ -1,4 +1,3 @@ -import json from typing import Generator import bpy @@ -50,6 +49,7 @@ class CollectInstances(pyblish.api.ContextPlugin): for group in asset_groups: instance = self.create_instance(context, group) + instance.data["instance_group"] = group members = [] if isinstance(group, bpy.types.Collection): members = list(group.objects) @@ -65,6 +65,6 @@ class CollectInstances(pyblish.api.ContextPlugin): members.append(group) instance[:] = members - self.log.debug(json.dumps(instance.data, indent=4)) + self.log.debug(instance.data) for obj in instance: self.log.debug(obj) diff --git a/openpype/hosts/blender/plugins/publish/validate_instance_empty.py b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py index 5abfd6dee8..3ebc6515d3 100644 --- a/openpype/hosts/blender/plugins/publish/validate_instance_empty.py +++ b/openpype/hosts/blender/plugins/publish/validate_instance_empty.py @@ -13,15 +13,11 @@ class ValidateInstanceEmpty(pyblish.api.InstancePlugin): optional = False def process(self, instance): - self.log.debug(instance) - self.log.debug(instance.data) - if instance.data["family"] == "blendScene": - # blendScene instances are collections - collection = bpy.data.collections[instance.name] - if not (collection.objects or collection.children): + asset_group = instance.data["instance_group"] + + if isinstance(asset_group, bpy.types.Collection): + if not (asset_group.objects or asset_group.children): raise RuntimeError(f"Instance {instance.name} is empty.") - else: - # All other instances are objects - asset_group = bpy.data.objects[instance.name] + elif isinstance(asset_group, bpy.types.Object): if not asset_group.children: raise RuntimeError(f"Instance {instance.name} is empty.") From 9607db50f2fce387860d94bf7563a3e841ac1089 Mon Sep 17 00:00:00 2001 From: Toke Jepsen Date: Thu, 9 Nov 2023 15:58:27 +0000 Subject: [PATCH 373/690] Testing: Ingest expected files and input workfile (#5840) * Ingest input workfile * Ingest input workfile * Ingested expected files, workfile Implemented LocalFileHandler. Test name added to structure to separate files for each test. Removed superfluous `files` to keep other Maya test working * Missing time import * Hound * Skip directories when checking folder structure. * Update tests/lib/testing_classes.py Co-authored-by: Roy Nieterau * Updated integration tests documentation * Ingested test files for Deadline test in maya * Removed unneeded files * Refactored name --------- Co-authored-by: kalisp Co-authored-by: Roy Nieterau --- tests/integration/README.md | 63 +- tests/integration/hosts/maya/lib.py | 31 +- .../maya/test_deadline_publish_in_maya.py | 3 +- .../test_deadline_publish_in_maya/README.md | 17 + ...test_project_test_asset_modelMain_hero.abc | Bin 0 -> 24787 bytes .../test_project_test_asset_modelMain_hero.ma | 1208 +++++++++++++++++ ...test_project_test_asset_modelMain_v001.abc | Bin 0 -> 24787 bytes .../test_project_test_asset_modelMain_v001.ma | 1208 +++++++++++++++++ ..._asset_renderTest_taskMain_beauty_v001.exr | Bin 0 -> 3608096 bytes ..._asset_renderTest_taskMain_beauty_v001.jpg | Bin 0 -> 77035 bytes ...et_renderTest_taskMain_beauty_v001_png.png | Bin 0 -> 563725 bytes ...oject_test_asset_workfileTest_task_v001.ma | 525 +++++++ .../test_project_test_asset_test_task_v001.ma | 525 +++++++ .../test_project_test_asset_test_task_v002.ma | 525 +++++++ .../test_asset/work/test_task/workspace.mel | 10 + .../dumps/avalon_tests/test_project.bson | Bin 0 -> 4899 bytes .../avalon_tests/test_project.metadata.json | 1 + .../input/dumps/openpype_tests/settings.bson | Bin 0 -> 914 bytes .../openpype_tests/settings.metadata.json | 1 + .../input/env_vars/env_var.json | 11 + .../input/startup/userSetup.py | 13 + .../test_project_test_asset_test_task_v001.ma | 525 +++++++ .../hosts/maya/test_publish_in_maya.py | 4 +- ...test_project_test_asset_modelMain_hero.abc | Bin 0 -> 24647 bytes .../test_project_test_asset_modelMain_hero.ma | 1186 ++++++++++++++++ ...test_project_test_asset_modelMain_v001.abc | Bin 0 -> 24647 bytes .../test_project_test_asset_modelMain_v001.ma | 1186 ++++++++++++++++ ...oject_test_asset_workfileTest_task_v001.ma | 476 +++++++ .../Main/renderMain_metadata.json | 275 ++++ .../test_project_test_asset_test_task_v001.ma | 476 +++++++ .../test_project_test_asset_test_task_v002.ma | 480 +++++++ .../test_asset/work/test_task/workspace.mel | 12 + .../dumps/avalon_tests/test_project.bson | Bin 0 -> 4899 bytes .../avalon_tests/test_project.metadata.json | 1 + .../input/dumps/openpype_tests/settings.bson | 0 .../openpype_tests/settings.metadata.json | 1 + .../input/env_vars/env_var.json | 11 + .../input/startup/userSetup.py | 0 .../test_project_test_asset_test_task_v001.ma | 476 +++++++ tests/lib/file_handler.py | 122 +- tests/lib/testing_classes.py | 70 +- 41 files changed, 9346 insertions(+), 96 deletions(-) create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/README.md create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.abc create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.ma create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.abc create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.ma create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/render/renderTest_taskMain_beauty/v001/test_project_test_asset_renderTest_taskMain_beauty_v001.exr create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/render/renderTest_taskMain_beauty/v001/test_project_test_asset_renderTest_taskMain_beauty_v001.jpg create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/render/renderTest_taskMain_beauty/v001/test_project_test_asset_renderTest_taskMain_beauty_v001_png.png create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/workfile/workfileTest_task/v001/test_project_test_asset_workfileTest_task_v001.ma create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/work/test_task/test_project_test_asset_test_task_v001.ma create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/work/test_task/test_project_test_asset_test_task_v002.ma create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/work/test_task/workspace.mel create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/dumps/avalon_tests/test_project.bson create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/dumps/avalon_tests/test_project.metadata.json create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/dumps/openpype_tests/settings.bson create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/dumps/openpype_tests/settings.metadata.json create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/env_vars/env_var.json create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/startup/userSetup.py create mode 100644 tests/integration/hosts/maya/test_deadline_publish_in_maya/input/workfile/test_project_test_asset_test_task_v001.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.abc create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.abc create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/publish/workfile/workfileTest_task/v001/test_project_test_asset_workfileTest_task_v001.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/work/test_task/renders/maya/test_project_test_asset_workfileTest_task_v001/Main/renderMain_metadata.json create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/work/test_task/test_project_test_asset_test_task_v001.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/work/test_task/test_project_test_asset_test_task_v002.ma create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/expected/test_project/test_asset/work/test_task/workspace.mel create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/dumps/avalon_tests/test_project.bson create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/dumps/avalon_tests/test_project.metadata.json create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/dumps/openpype_tests/settings.bson create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/dumps/openpype_tests/settings.metadata.json create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/env_vars/env_var.json rename tests/integration/hosts/maya/{ => test_publish_in_maya}/input/startup/userSetup.py (100%) create mode 100644 tests/integration/hosts/maya/test_publish_in_maya/input/workfile/test_project_test_asset_test_task_v001.ma diff --git a/tests/integration/README.md b/tests/integration/README.md index eef8141127..7b9b7cd706 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -14,23 +14,52 @@ How to run - run in cmd `{OPENPYPE_ROOT}/.venv/Scripts/python.exe {OPENPYPE_ROOT}/start.py runtests {OPENPYPE_ROOT}/tests/integration` - add `hosts/APP_NAME` after integration part to limit only on specific app (eg. `{OPENPYPE_ROOT}/tests/integration/hosts/maya`) - -OR can use built executables + +OR can use built executables `openpype_console runtests {ABS_PATH}/tests/integration` +Command line arguments +---------------------- + - "--mark" - "Run tests marked by", + - "--pyargs" - "Run tests from package", + - "--test_data_folder" - "Unzipped directory path of test file", + - "--persist" - "Persist test DB and published files after test end", + - "--app_variant" - "Provide specific app variant for test, empty for latest", + - "--app_group" - "Provide specific app group for test, empty for default", + - "--timeout" - "Provide specific timeout value for test case", + - "--setup_only" - "Only create dbs, do not run tests", + - "--mongo_url" - "MongoDB for testing.", + +Run Tray for test +----------------- +In case of failed test you might want to run it manually and visually debug what happened. +For that: +- run tests that is failing +- add environment variables (to command line process or your IDE) + - OPENPYPE_DATABASE_NAME = openpype_tests + - AVALON_DB = avalon_tests +- run tray as usual + - `{OPENPYPE_ROOT}/.venv/Scripts/python.exe {OPENPYPE_ROOT}/start.py run tray --debug` + +You should see only test asset and state of databases for that particular use case. + How to check logs/errors from app -------------------------------- -Keep PERSIST to True in the class and check `test_openpype.logs` collection. +Keep PERSIST to True in the class and check `test_openpype.logs` collection. How to create test for publishing from host ------------------------------------------ - Extend PublishTest in `tests/lib/testing_classes.py` - Use `resources\test_data.zip` skeleton file as a template for testing input data -- Put workfile into `test_data.zip/input/workfile` -- If you require other than base DB dumps provide them to `test_data.zip/input/dumps` +- Create subfolder `test_data` with matching name to your test file containing you test class + - (see `tests/integration/hosts/maya/test_publish_in_maya` and `test_publish_in_maya.py`) +- Put this subfolder name into TEST_FILES [(HASH_ID, FILE_NAME, MD5_OPTIONAL)] + - at first position, all others may be "" +- Put workfile into `test_data/input/workfile` +- If you require other than base DB dumps provide them to `test_data/input/dumps` -- (Check commented code in `db_handler.py` how to dump specific DB. Currently all collections will be dumped.) -- Implement `last_workfile_path` -- `startup_scripts` - must contain pointing host to startup script saved into `test_data.zip/input/startup` +- Implement `last_workfile_path` +- `startup_scripts` - must contain pointing host to startup script saved into `test_data/input/startup` -- Script must contain something like (pseudocode) ``` import openpype @@ -39,7 +68,7 @@ from avalon import api, HOST from openpype.api import Logger log = Logger().get_logger(__name__) - + api.install(HOST) log_lines = [] for result in pyblish.util.publish_iter(): @@ -54,18 +83,20 @@ for result in pyblish.util.publish_iter(): EXIT_APP (command to exit host) ``` (Install and publish methods must be triggered only AFTER host app is fully initialized!) -- If you would like add any command line arguments for your host app add it to `test_data.zip/input/app_args/app_args.json` (as a json list) -- Provide any required environment variables to `test_data.zip/input/env_vars/env_vars.json` (as a json dictionary) -- Zip `test_data.zip`, named it with descriptive name, upload it to Google Drive, right click - `Get link`, copy hash id (file must be accessible to anyone with a link!) -- Put this hash id and zip file name into TEST_FILES [(HASH_ID, FILE_NAME, MD5_OPTIONAL)]. If you want to check MD5 of downloaded -file, provide md5 value of zipped file. +- If you would like add any command line arguments for your host app add it to `test_data/input/app_args/app_args.json` (as a json list) +- Provide any required environment variables to `test_data/input/env_vars/env_vars.json` (as a json dictionary) - Implement any assert checks you need in extended class - Run test class manually (via Pycharm or pytest runner (TODO)) - If you want test to visually compare expected files to published one, set PERSIST to True, run test manually -- Locate temporary `publish` subfolder of temporary folder (found in debugging console log) - -- Copy whole folder content into .zip file into `expected` subfolder + -- Copy whole folder content into .zip file into `expected` subfolder -- By default tests are comparing only structure of `expected` and published format (eg. if you want to save space, replace published files with empty files, but with expected names!) -- Zip and upload again, change PERSIST to False - + - Use `TEST_DATA_FOLDER` variable in your class to reuse existing downloaded and unzipped test data (for faster creation of tests) -- Keep `APP_VARIANT` empty if you want to trigger test on latest version of app, or provide explicit value (as '2022' for Photoshop for example) \ No newline at end of file +- Keep `APP_VARIANT` empty if you want to trigger test on latest version of app, or provide explicit value (as '2022' for Photoshop for example) + +For storing test zip files on Google Drive: +- Zip `test_data.zip`, named it with descriptive name, upload it to Google Drive, right click - `Get link`, copy hash id (file must be accessible to anyone with a link!) +- Put this hash id and zip file name into TEST_FILES [(HASH_ID, FILE_NAME, MD5_OPTIONAL)]. If you want to check MD5 of downloaded +file, provide md5 value of zipped file. diff --git a/tests/integration/hosts/maya/lib.py b/tests/integration/hosts/maya/lib.py index 04ddb765a4..ab5bcbbd36 100644 --- a/tests/integration/hosts/maya/lib.py +++ b/tests/integration/hosts/maya/lib.py @@ -16,18 +16,25 @@ class MayaHostFixtures(HostFixtures): Maya expects workfile in proper folder, so copy is done first. """ - src_path = os.path.join(download_test_data, - "input", - "workfile", - "test_project_test_asset_test_task_v001.mb") - dest_folder = os.path.join(output_folder_url, - self.PROJECT, - self.ASSET, - "work", - self.TASK) + src_path = os.path.join( + download_test_data, + "input", + "workfile", + "test_project_test_asset_test_task_v001.ma" + ) + dest_folder = os.path.join( + output_folder_url, + self.PROJECT, + self.ASSET, + "work", + self.TASK + ) + os.makedirs(dest_folder) - dest_path = os.path.join(dest_folder, - "test_project_test_asset_test_task_v001.mb") + + dest_path = os.path.join( + dest_folder, "test_project_test_asset_test_task_v001.ma" + ) shutil.copy(src_path, dest_path) yield dest_path @@ -36,7 +43,7 @@ class MayaHostFixtures(HostFixtures): def startup_scripts(self, monkeypatch_session, download_test_data): """Points Maya to userSetup file from input data""" startup_path = os.path.join( - os.path.dirname(__file__), "input", "startup" + download_test_data, "input", "startup" ) original_pythonpath = os.environ.get("PYTHONPATH") monkeypatch_session.setenv( diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya.py b/tests/integration/hosts/maya/test_deadline_publish_in_maya.py index 9332177944..c2ef342600 100644 --- a/tests/integration/hosts/maya/test_deadline_publish_in_maya.py +++ b/tests/integration/hosts/maya/test_deadline_publish_in_maya.py @@ -24,8 +24,7 @@ class TestDeadlinePublishInMaya(MayaDeadlinePublishTestClass): PERSIST = True TEST_FILES = [ - ("1dDY7CbdFXfRksGVoiuwjhnPoTRCCf5ea", - "test_maya_deadline_publish.zip", "") + ("test_deadline_publish_in_maya", "", "") ] APP_GROUP = "maya" diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/README.md b/tests/integration/hosts/maya/test_deadline_publish_in_maya/README.md new file mode 100644 index 0000000000..929bfcd666 --- /dev/null +++ b/tests/integration/hosts/maya/test_deadline_publish_in_maya/README.md @@ -0,0 +1,17 @@ +Test data +--------- +Each class implementing `TestCase` can provide test file(s) by adding them to +TEST_FILES ('GDRIVE_FILE_ID', 'ACTUAL_FILE_NAME', 'MD5HASH') + +GDRIVE_FILE_ID can be pulled from shareable link from Google Drive app. + +Currently it is expected that test file will be zip file with structure: +- expected - expected files (not implemented yet) +- input + - data - test data (workfiles, images etc) + - dumps - folder for BSOn dumps from (`mongodump`) + - env_vars + env_vars.json - dictionary with environment variables {key:value} + + - sql - sql files to load with `mongoimport` (human readable) + - startup - scripts that should run in the host on its startup diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.abc b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.abc new file mode 100644 index 0000000000000000000000000000000000000000..d9e54259960efb658348c78adaa0f9ae0958083e GIT binary patch literal 24787 zcmeI&X_Oshx%TmdNrpfmjA3jQ0wQK634z`frZ9y;W@HGRq(cHpy6NtO1W?-RsHKX>o`THS{-EiR(k32jw>1~6j4L&+! z@}kAlrgTqTkpE4ewP4Y-83*jYaPs~$W>1?uwQKsq8B?ZC>zY1l(|YUCb={z@`&4ys zab4ScIdY319sYqa6V5;Dy5FC*YWsPe|8g%g7S5d6HD&*<17>v{@GtjrW&Q3Wb$x1^ z3hq7hwyk&D>%D(_;Eb_751#tj*Bo=kPOZHjxOCm#qvzgn$=gSlT%7Q^JEBg0yy3k@ z&n@}rGj^9sE1+QSm#o4PKM^t8EiLFy0Y)4L>h)=i4UiJsN&zd;aX~Gb-Qb zqV!@L^XI0=vnH?oI6ixFM{D=GpTpzNs{34(`DD%k@w|rj$lSBC4YuDs*1WZK;p+Z% z+h2Xx9h;0AEcw$hYY=bwunY-VLFPV8`YfRnG`1l{M`y8G5 zqw4-|jpsGz2NM?C_IgK38(z+RKKcl7BzubHhvCKeps? z+dNo)Uh~&n_;da+-X?x;w!x2Q{%<4P6K`x@!`+#?D%)V6x8b*bQ_o+KeMaS+crDwQ zzh!#tyKu>^c;LdHw-(m@jETRj?(^4~|Es$HBl@oRP{K34a`KeX<%FY_;~`#-Go zs?TNpcgi;H{XV+Se#Mg;?Z0m5&iTVP_l+xghkL#=9JTm2^^IHi_B-d7{K!80mA&%+ z62%|JKZ(C>w!!bp{IwAt7w@6GhToF8e@ewZZ^Li3=Wm^TM&;lcDe6Xyl$7{i)WsBdD#!&n(}{~`Gl?Ym+H^uoX*;ozWr|h_~}KC@8O?3 zb@}k0FPl~J)#El<7nS^{%Vw>6_^HdC1H;=setOv}-ZbY@{Nc8LRkp!TX8!LZd}X|? zvkm@H=5CyAu>CgtR%3o)8*_e_UTlN6N{^$*KYADBGKkWM94X>J4@(*v^Ze3LJ23O5n_ua#; zZ<({pn%?sB;uq!nEdDUwIsOl_4SwdzdF!5z@B{I7%xm~tnfrolgYCEBxBjc1|NZPU zD(C$D%6Wxt%-=pe?)AXmZ^e5*aA|R0-4Fl%y3fC5{$C?=z87!1`g46FbMxI>`u2NC z@=^zr%a?PU z*KgnOTh429a{Vq`!?E+!HrSe`+=lZ#Ypu$D`pUJg`W()D=czfa;rYHT*>`U~UCCan z*SFPJ-&SLNTaEQ?HP*M)Sl?D-eOrz7Z8g@n)mY!M*Lr>V?e%Rn*0{jrDCc*0oGke*64wHO}8wvOAdeQq_b&*gsW@86>F{aZA?e~ZTVZ_)VvEgIjyMdSOoXng+`jql&`yR`oPEzhO; z`>%V_XzyAI$zkBQN-=gvTn|-bS{w?=g-(MAt`>UdH ze^oT@uZqU~RnfS=DjN4!MdSXeXxv|w_e%BsRk`2#{)*qezbYE{S4HFgs%YF_6^;9= z(y#BY%6qH&{;Fu)Ulon}t8%~f{d3W{e=ZvL&*fUz_s>P+{<&z}KNpSr=b~}{Tr}>V zi^lzPx!?N!ncu#DE*kgGMdSXtXxu*+jr-@)ukWABHLdTTi^lzP(YSvu_gnuyDjL6! zipKAwqVfBvX#74Z8o!T<#_yw|@%yM~{5~ogzmLlO*1wPV?cYa5F`?qNP z{w?=gKi?=C&o_$3^NphMe4}VQ-zXZ-H;TsdjiT{qZ<%Kg^QH~8)68%5*! zM$ve_Q8b=!6piN_MdSHK(RjX5G@fr1jprNXe%*8A8n&*gC6|8hPL;EAgKZ8v_uA86 zI_`!u*L?5F_kVf2*xN_#r&M@{$kQqw-Z9!R;$d&)nHdj{k2a2Yc;{%7h=+HHo)hu# zu92r>JiJ@9S;WJ;N1I1HyhpS}#KRrYn23j;8*Lf!@bjXrA|8HzG&bVlJ)^B79^NbR zc#MZ9MB^eJ-aFbh;$fNj<9V8wM}=jEe7tWYH(BBrMsnlf{UW*X@QWh3@$ke*Zah3G zk{b_Cj^xI}QzE(X@YG0dJUlIu8xK#9IwBt4KayKV%`;Nv#=|osx$*FkB#KU!^cH(d`cv@IW?b}DmNZJEs`4#pB~ALhtG)Q z#=|d(2}ax$*FdNNzmb z6UmK-dn38=@P(1wc(^Z;8xQwKa^vBF=-h~hS4MI>x8_x;a^vBPBDwLf%w)w|9j%Gv z#>W>&a^vAkBDwMKrIFlt_@$BDc=%!8xOxKk{b`d zI+7a?zb29!55G2&8xOxOk{b_S7Ril=UmwYkhu;v%jfdYD$&H6)wkYCV9$gX1jgPO4 z24}Tz%ArF5rk{b_yD3Tiwe>jpG4}T<* z8xMapk{b`-63LB+KNiW2hd&<4jfZcIeXzHYR3xr}_|K8tc=)MEZan;#NNzm**GO(W{I^JMJpA`aZan;7k=%Ir=}2xo{7fV_ z9v(Hi%8iFdM{<)T-XM}24{sRBjfZ6>E8a#KZyd>uk2i_r#>3Bv+<17KNNzklE|MD$ZyU*thqsI5 z#>3l3a^vA0BDwMKj*;AWSZ1=~?G%lV1^hZaiE> za^qo{$%;28IyjOWA0HCQjfW47#=~bsa^vBbL~`TdGb6e2@L7@Ec=+r{ZajQWBsU(O zAIXh}&yD29!(EZwcz8i1Hy&OX$&H5>MRMce?nrJtyf~5@51$vwjfZ6>E8dc5X(Ts3 zK0lHh4_^?;jfa;-a^vCUk=%HAMI<*K?uq2a!@ZH*c=*CdZamx<$&H8mBf0VLKqNOF zUKz=ahgU^%pMup5YF0O_S>32+ zb>o`VO=?!3Q?t5h&FW?~tDD!XZc(#3re<}^n$@jpR>#(?Ze6pwP0i}Kn$>Mh z#@5*wTVrEveT}iTHO4-l@d*|sf5r44eDQm&hfaJ|Z~xL?|9Qp(*6`o@cLx7H2L62v z{QDUAzjqAyzWu+fIqA>e(6}qt?sxRlXWy{AZ|~F2`Qs~N&B?FRbzZCMU}IdA_NXV+ zj`+phzTopWcA(E+#C`AO-7_+;^I46QeBIFaR_&EFTbA{@p`o%) zpLSbW?;RN_>ypKfl{H_5h3)Pg8B^AG42>`AlEo9sy8pCkW!+%ZoU-0GGOw)H51mog zrHdDrb;h**vX0JwW9a>=KC9mD8Br@$eU^UqKazR+9O!v+C39`W)%3`W(rB!=cZS&Z^Im&Z^Im&Z^Im&ZAl@sH7;Mv zymH;sOS$f?dfm%D&8yeF?9;ej_g1~`dA(fsR=w_JpXSx;UiN8RuY1|2alP(kpY3C> zy|(S_+P$f5=@aWym8YstRi2eUrmXs`UY}4_eHzPC)u$>?RiCOnReh?}x>x5$``A-u z-OjGvTjhIgsO(d%)_tg6_o1@S%D3)AWuB@$)oR^`>UAHg*L|p7_n~^-hw63re%4(! z`Tbs>yH%~u5q-ATww;}78?`NcVtK0aRIR%z&+7FFW!0y#JXLwB@>J!i%2U;+s!#jM zv9SK!tum_45yyzJ>?^;@(6+{H=@aX-^2U@^pT_c3^{MJp)u*aYRiCOpReh@Ztj~e< z*A`=W)_z&_S^3o(>(khKsBP)9^2d}_pVey<%BoLeeX9CY^{MJp)u*aYRiEBlo>i@` zf%>fdvR22mYfg0xR%=pa*X~Vi%erHIRaj?pQ=7peb(2I_19)& zeb#(+ftQLX!!vQOh`-N%%D8dvK+rtH(WT6fou z{Qr{q%<`;i^&O(m+Apg4@K2?2I{+P1j>h%d_)u*vMReh@RRQ0LKQ`M)c z&-xm?{=2QZhB!W}YqMG%pVhU+xH>+obHiAlsyeF0(R<*i^(P!r>UIs!vs)sy-{fy2j|Udc8VF^l7Y5RiCO})VB1A^{MKUr_ZWZ z_o(`;{j%!QSf8psReh@ZRP|Z;)iqF`)$7$ctWRTos`^yh8S2TnEq&tLZyu!A?7zHc z4wm0h)2B@<>v@Y8m-U{J%j@xb%bNf9zO2^`Jy6!^)1EBr;>DYkpMBc2ZOfXUJ!QRT zWWTZw4INO{#f#^bb=tI(%9^LaWxZ!)Sy_jM*3@JDmG?}3Q}D7M_a^!qEUNz8^Xt!8 zf9C1WcKS14e}hHU-(XSoXI@8Sd;JX-Re$E`&piE^cWzm${>;}1lyj$eiGY{_`dH&49dqkc=^KeJxIW!MHH}Wi+ho2Yuxyr-Ok35s+;XNbIrFnR- z$g^o4o)CFH&BJ>~o>BAgK9T3tJp6)ayNI`M^ukDPvc&sEa^v9_MRMceiILoRcv2)c z9-bV@jfba1a^vBtk=%HAS|m3fo*v1Khxd;0n3a^vB{BDwMK;gQ^U zcy1&&9zG(H8xJ2D$&H7PisZ(_M@Mqw;bS5h^6hx;SB@$f(-Hy&OYog4A+sz`3<)_hT_+<16(BsU&j6UmK-FOKBK!x$*GTk=%Ir z&5;awZ;7sn{>K58oQe zjfZcG4kUa^vCqBDwMKHzK+5@HZnF^1c;) zJCd6$@pmG*@$h$}J0l*xKa$&>HGeNvZan<`NNzm*KqNOF{y`)+9{$frZan0eir>a zlAA2?FCw||@Gm2|@$j!A8S?P2Bf0VLZz8$z@NXlz@$lo3+<5qjNNzm*yGU+4{QF35 zJp5!NHy-{&BsU)ZWAsqO!+(n8_E61#PL&%EKNZQ1hyN1Ejfejl$&H8q7RiwJ_vpVO zxyceg9m$P{pNZtg!=pw&``-=Y(UII_i8qMk#={#%a^vBRBDwMK#*y53c#}wOJp7zU zZalncBsU)3ERq`!Zyw2whqs7i$irhIx$*Fpk=%HAt4MAZ zHy++Sk{b{25y_2*J0iL9@N*-%@$mB^x$*GxBf0VLo{`*mc&|u?yb00Xk=$g7_le}j z!!L;B#>4wYa^v9_Msnlf{UW*X@QWh3@$ke*Zah3Gk{b_Cj^xI}QzE(X@YG0dJUlIu z8xK#9wcp#D+53h{m#>1;3 zx$*Etk=%HAbtE?)UK7cXcX4z{BsW>&OC!1Q@Jl1P@$kzcx$*GJBf0VLU?evlenliV z9)4vcHy(afBsU&@btE?)eoZ7d9)4{kHy(anBsU(uERq`!zdn*155FOj8xOxRk{b_S z9?6Y|uZZNv!&gQ!e%SUu)1~h&ak>ov^K1ci{2Gh zw~gK%R=1083Ohy|H#bL)599Yljt%4YMve>P_eG8g9M}K@h;obXeJ!pyYV92T2ST)JY>(uLjq4g`P8 zPOs|8b$xYJ*T3<)t-t;>!N+z7zU-db|4umUhS6 zdejChS2?=<&8*rP^~XAp2kZK!y6#cGUd_%CSNliQAETpw;lZwN&s%rRo;SVoLz{eb z-S|f*w&%BNI~dPbH=cN2T5JdN$$AeHUQ*6ozZA2o@u;WkJ+k@m51alOO#)^D!gZf0#b1bR>EUDDmxJ!Sq8haZ2^lCIwFDVx0floMaH!R=F* z-hcanci+G1(?6MZ{mZ65*1C4nTmF2@?SJWg-<7Tr)nD(ZO(w2h+|#%Iqkq2MW5=20 zgu!+v)2i{P6YAF=t~;p?mFiN{>}1nFjcVPqqWkbOzx$ESi38vN&7~I}dc&cs)}HgF z=Z<^tHAf8$to>hlXg7EBKlSjbx`$)xdO`hqz5b(q`tY9Lp7F~^Z`$XDSDkss<|~dm zp=a5elLop5mM%PQa9Z7}x1FHA1qEEluoITJ^3 zK5^larOOsM7eDVL+`Qk1?9b=yf3fjqQzrIzE$>~{-R}#=-y5rLMjc<*OX~W~s;*z< z&Cago-&ZI6j{5bP^~ajuwRHZ$%et2@Si11k?!Nw|Ju5ovVaJq-GbirfvCo2)OP39F z%f|Z2I;PB;J$2UX$+KQ?V7YZ~@3N%}({46BwrfpS=1iU3aqxnLhp+DK z=^N-+HD%)Da^hiK1Kp?fEgcx>&cvP-9mg*m=$JaaW6Jc|`_G&`eWvZERujAX7xpdf zE#I+vlkPX&7G_Pl2*Rn|`cQ5aq zG_bt)!YPx_n||@q8IyWe4)m@Zm^9GcKQOY%w~yN@36@WnTmew)9(KK8!8t~H0R zP8I{5Qx43f>ZFCacy=yc)py|16$9OUy?xydfn>TWE%(IjUw_H%9OzrwePD0TqI&zO z__(g+*?d_~*TA%?^9K&-`iJ-bUpAhye&hauzNIV98~0DUU(mDqx$E0oHL&`h+w1Mg z2A%y2mvk@h>ddO^a=!EO*zW!%^H)tduzKl`uKw3| MH=R?xes^8}8yK4hrvLx| literal 0 HcmV?d00001 diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.ma b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.ma new file mode 100644 index 0000000000..9ee588337e --- /dev/null +++ b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/hero/test_project_test_asset_modelMain_hero.ma @@ -0,0 +1,1208 @@ +//Maya ASCII 2020 scene +//Name: modelMain.ma +//Last modified: Mon, Oct 24, 2022 02:57:47 PM +//Codeset: 1252 +requires maya "2020"; +requires "mtoa" "4.1.1"; +currentUnit -l centimeter -a degree -t pal; +fileInfo "application" "maya"; +fileInfo "product" "Maya 2020"; +fileInfo "version" "2020"; +fileInfo "cutIdentifier" "202011110415-b1e20b88e2"; +fileInfo "osv" "Microsoft Windows 10 Technical Preview (Build 19044)\n"; +fileInfo "UUID" "A787A358-4FE7-6E55-0C81-61BFEB0C2726"; +createNode transform -n "model_GRP"; + rename -uid "445FDC20-4A9D-2C5B-C7BD-F98F6E660B5C"; + setAttr ".rlio[0]" 1 yes 0; +createNode transform -n "pSphere1_GEO" -p "model_GRP"; + rename -uid "7445A43F-444F-B2D3-4315-2AA013D2E0B6"; + addAttr -ci true -sn "cbId" -ln "cbId" -dt "string"; + setAttr ".cbId" -type "string" "60df31e2be2b48bd3695c056:302a4c6123a4"; +createNode mesh -n "pSphere1_GEOShape1" -p "pSphere1_GEO"; + rename -uid "7C731260-45C6-339E-07BF-359446B08EA1"; + addAttr -ci true -sn "cbId" -ln "cbId" -dt "string"; + setAttr -k off ".v"; + setAttr ".vir" yes; + setAttr ".vif" yes; + setAttr ".uvst[0].uvsn" -type "string" "map1"; + setAttr -s 439 ".uvst[0].uvsp"; + setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0 0.050000001 0.050000001 0.050000001 + 0.1 0.050000001 0.15000001 0.050000001 0.2 0.050000001 0.25 0.050000001 0.30000001 + 0.050000001 0.35000002 0.050000001 0.40000004 0.050000001 0.45000005 0.050000001 + 0.50000006 0.050000001 0.55000007 0.050000001 0.60000008 0.050000001 0.6500001 0.050000001 + 0.70000011 0.050000001 0.75000012 0.050000001 0.80000013 0.050000001 0.85000014 0.050000001 + 0.90000015 0.050000001 0.95000017 0.050000001 1.000000119209 0.050000001 0 0.1 0.050000001 + 0.1 0.1 0.1 0.15000001 0.1 0.2 0.1 0.25 0.1 0.30000001 0.1 0.35000002 0.1 0.40000004 + 0.1 0.45000005 0.1 0.50000006 0.1 0.55000007 0.1 0.60000008 0.1 0.6500001 0.1 0.70000011 + 0.1 0.75000012 0.1 0.80000013 0.1 0.85000014 0.1 0.90000015 0.1 0.95000017 0.1 1.000000119209 + 0.1 0 0.15000001 0.050000001 0.15000001 0.1 0.15000001 0.15000001 0.15000001 0.2 + 0.15000001 0.25 0.15000001 0.30000001 0.15000001 0.35000002 0.15000001 0.40000004 + 0.15000001 0.45000005 0.15000001 0.50000006 0.15000001 0.55000007 0.15000001 0.60000008 + 0.15000001 0.6500001 0.15000001 0.70000011 0.15000001 0.75000012 0.15000001 0.80000013 + 0.15000001 0.85000014 0.15000001 0.90000015 0.15000001 0.95000017 0.15000001 1.000000119209 + 0.15000001 0 0.2 0.050000001 0.2 0.1 0.2 0.15000001 0.2 0.2 0.2 0.25 0.2 0.30000001 + 0.2 0.35000002 0.2 0.40000004 0.2 0.45000005 0.2 0.50000006 0.2 0.55000007 0.2 0.60000008 + 0.2 0.6500001 0.2 0.70000011 0.2 0.75000012 0.2 0.80000013 0.2 0.85000014 0.2 0.90000015 + 0.2 0.95000017 0.2 1.000000119209 0.2 0 0.25 0.050000001 0.25 0.1 0.25 0.15000001 + 0.25 0.2 0.25 0.25 0.25 0.30000001 0.25 0.35000002 0.25 0.40000004 0.25 0.45000005 + 0.25 0.50000006 0.25 0.55000007 0.25 0.60000008 0.25 0.6500001 0.25 0.70000011 0.25 + 0.75000012 0.25 0.80000013 0.25 0.85000014 0.25 0.90000015 0.25 0.95000017 0.25 1.000000119209 + 0.25 0 0.30000001 0.050000001 0.30000001 0.1 0.30000001 0.15000001 0.30000001 0.2 + 0.30000001 0.25 0.30000001 0.30000001 0.30000001 0.35000002 0.30000001 0.40000004 + 0.30000001 0.45000005 0.30000001 0.50000006 0.30000001 0.55000007 0.30000001 0.60000008 + 0.30000001 0.6500001 0.30000001 0.70000011 0.30000001 0.75000012 0.30000001 0.80000013 + 0.30000001 0.85000014 0.30000001 0.90000015 0.30000001 0.95000017 0.30000001 1.000000119209 + 0.30000001 0 0.35000002 0.050000001 0.35000002 0.1 0.35000002 0.15000001 0.35000002 + 0.2 0.35000002 0.25 0.35000002 0.30000001 0.35000002 0.35000002 0.35000002 0.40000004 + 0.35000002 0.45000005 0.35000002 0.50000006 0.35000002 0.55000007 0.35000002 0.60000008 + 0.35000002 0.6500001 0.35000002 0.70000011 0.35000002 0.75000012 0.35000002 0.80000013 + 0.35000002 0.85000014 0.35000002 0.90000015 0.35000002 0.95000017 0.35000002 1.000000119209 + 0.35000002 0 0.40000004 0.050000001 0.40000004 0.1 0.40000004 0.15000001 0.40000004 + 0.2 0.40000004 0.25 0.40000004 0.30000001 0.40000004 0.35000002 0.40000004 0.40000004 + 0.40000004 0.45000005 0.40000004 0.50000006 0.40000004 0.55000007 0.40000004 0.60000008 + 0.40000004 0.6500001 0.40000004 0.70000011 0.40000004 0.75000012 0.40000004 0.80000013 + 0.40000004 0.85000014 0.40000004 0.90000015 0.40000004 0.95000017 0.40000004 1.000000119209 + 0.40000004 0 0.45000005 0.050000001 0.45000005 0.1 0.45000005 0.15000001 0.45000005 + 0.2 0.45000005 0.25 0.45000005 0.30000001 0.45000005 0.35000002 0.45000005 0.40000004 + 0.45000005 0.45000005 0.45000005 0.50000006 0.45000005 0.55000007 0.45000005 0.60000008 + 0.45000005 0.6500001 0.45000005 0.70000011 0.45000005 0.75000012 0.45000005 0.80000013 + 0.45000005 0.85000014 0.45000005 0.90000015 0.45000005 0.95000017 0.45000005 1.000000119209 + 0.45000005 0 0.50000006 0.050000001 0.50000006 0.1 0.50000006 0.15000001 0.50000006 + 0.2 0.50000006 0.25 0.50000006 0.30000001 0.50000006 0.35000002 0.50000006 0.40000004 + 0.50000006 0.45000005 0.50000006 0.50000006 0.50000006 0.55000007 0.50000006 0.60000008 + 0.50000006 0.6500001 0.50000006 0.70000011 0.50000006 0.75000012 0.50000006 0.80000013 + 0.50000006 0.85000014 0.50000006 0.90000015 0.50000006 0.95000017 0.50000006 1.000000119209 + 0.50000006 0 0.55000007 0.050000001 0.55000007 0.1 0.55000007 0.15000001 0.55000007 + 0.2 0.55000007 0.25 0.55000007 0.30000001 0.55000007 0.35000002 0.55000007 0.40000004 + 0.55000007 0.45000005 0.55000007 0.50000006 0.55000007 0.55000007 0.55000007 0.60000008 + 0.55000007 0.6500001 0.55000007 0.70000011 0.55000007 0.75000012 0.55000007 0.80000013 + 0.55000007 0.85000014 0.55000007 0.90000015 0.55000007 0.95000017 0.55000007 1.000000119209 + 0.55000007 0 0.60000008 0.050000001 0.60000008 0.1 0.60000008 0.15000001 0.60000008 + 0.2 0.60000008 0.25 0.60000008 0.30000001 0.60000008 0.35000002 0.60000008 0.40000004 + 0.60000008 0.45000005 0.60000008 0.50000006 0.60000008 0.55000007 0.60000008 0.60000008 + 0.60000008 0.6500001 0.60000008 0.70000011 0.60000008 0.75000012 0.60000008 0.80000013 + 0.60000008 0.85000014 0.60000008 0.90000015 0.60000008; + setAttr ".uvst[0].uvsp[250:438]" 0.95000017 0.60000008 1.000000119209 0.60000008 + 0 0.6500001 0.050000001 0.6500001 0.1 0.6500001 0.15000001 0.6500001 0.2 0.6500001 + 0.25 0.6500001 0.30000001 0.6500001 0.35000002 0.6500001 0.40000004 0.6500001 0.45000005 + 0.6500001 0.50000006 0.6500001 0.55000007 0.6500001 0.60000008 0.6500001 0.6500001 + 0.6500001 0.70000011 0.6500001 0.75000012 0.6500001 0.80000013 0.6500001 0.85000014 + 0.6500001 0.90000015 0.6500001 0.95000017 0.6500001 1.000000119209 0.6500001 0 0.70000011 + 0.050000001 0.70000011 0.1 0.70000011 0.15000001 0.70000011 0.2 0.70000011 0.25 0.70000011 + 0.30000001 0.70000011 0.35000002 0.70000011 0.40000004 0.70000011 0.45000005 0.70000011 + 0.50000006 0.70000011 0.55000007 0.70000011 0.60000008 0.70000011 0.6500001 0.70000011 + 0.70000011 0.70000011 0.75000012 0.70000011 0.80000013 0.70000011 0.85000014 0.70000011 + 0.90000015 0.70000011 0.95000017 0.70000011 1.000000119209 0.70000011 0 0.75000012 + 0.050000001 0.75000012 0.1 0.75000012 0.15000001 0.75000012 0.2 0.75000012 0.25 0.75000012 + 0.30000001 0.75000012 0.35000002 0.75000012 0.40000004 0.75000012 0.45000005 0.75000012 + 0.50000006 0.75000012 0.55000007 0.75000012 0.60000008 0.75000012 0.6500001 0.75000012 + 0.70000011 0.75000012 0.75000012 0.75000012 0.80000013 0.75000012 0.85000014 0.75000012 + 0.90000015 0.75000012 0.95000017 0.75000012 1.000000119209 0.75000012 0 0.80000013 + 0.050000001 0.80000013 0.1 0.80000013 0.15000001 0.80000013 0.2 0.80000013 0.25 0.80000013 + 0.30000001 0.80000013 0.35000002 0.80000013 0.40000004 0.80000013 0.45000005 0.80000013 + 0.50000006 0.80000013 0.55000007 0.80000013 0.60000008 0.80000013 0.6500001 0.80000013 + 0.70000011 0.80000013 0.75000012 0.80000013 0.80000013 0.80000013 0.85000014 0.80000013 + 0.90000015 0.80000013 0.95000017 0.80000013 1.000000119209 0.80000013 0 0.85000014 + 0.050000001 0.85000014 0.1 0.85000014 0.15000001 0.85000014 0.2 0.85000014 0.25 0.85000014 + 0.30000001 0.85000014 0.35000002 0.85000014 0.40000004 0.85000014 0.45000005 0.85000014 + 0.50000006 0.85000014 0.55000007 0.85000014 0.60000008 0.85000014 0.6500001 0.85000014 + 0.70000011 0.85000014 0.75000012 0.85000014 0.80000013 0.85000014 0.85000014 0.85000014 + 0.90000015 0.85000014 0.95000017 0.85000014 1.000000119209 0.85000014 0 0.90000015 + 0.050000001 0.90000015 0.1 0.90000015 0.15000001 0.90000015 0.2 0.90000015 0.25 0.90000015 + 0.30000001 0.90000015 0.35000002 0.90000015 0.40000004 0.90000015 0.45000005 0.90000015 + 0.50000006 0.90000015 0.55000007 0.90000015 0.60000008 0.90000015 0.6500001 0.90000015 + 0.70000011 0.90000015 0.75000012 0.90000015 0.80000013 0.90000015 0.85000014 0.90000015 + 0.90000015 0.90000015 0.95000017 0.90000015 1.000000119209 0.90000015 0 0.95000017 + 0.050000001 0.95000017 0.1 0.95000017 0.15000001 0.95000017 0.2 0.95000017 0.25 0.95000017 + 0.30000001 0.95000017 0.35000002 0.95000017 0.40000004 0.95000017 0.45000005 0.95000017 + 0.50000006 0.95000017 0.55000007 0.95000017 0.60000008 0.95000017 0.6500001 0.95000017 + 0.70000011 0.95000017 0.75000012 0.95000017 0.80000013 0.95000017 0.85000014 0.95000017 + 0.90000015 0.95000017 0.95000017 0.95000017 1.000000119209 0.95000017 0.025 0 0.075000003 + 0 0.125 0 0.17500001 0 0.22500001 0 0.27500001 0 0.32500002 0 0.375 0 0.42500001 + 0 0.47500002 0 0.52499998 0 0.57499999 0 0.625 0 0.67500001 0 0.72499996 0 0.77499998 + 0 0.82499999 0 0.875 0 0.92500001 0 0.97499996 0 0.025 1 0.075000003 1 0.125 1 0.17500001 + 1 0.22500001 1 0.27500001 1 0.32500002 1 0.375 1 0.42500001 1 0.47500002 1 0.52499998 + 1 0.57499999 1 0.625 1 0.67500001 1 0.72499996 1 0.77499998 1 0.82499999 1 0.875 + 1 0.92500001 1 0.97499996 1; + setAttr ".cuvs" -type "string" "map1"; + setAttr ".dcc" -type "string" "Ambient+Diffuse"; + setAttr ".covm[0]" 0 1 1; + setAttr ".cdvm[0]" 0 1 1; + setAttr -s 382 ".vt"; + setAttr ".vt[0:165]" 0.14877813 -0.98768836 -0.048340943 0.12655823 -0.98768836 -0.091949932 + 0.091949932 -0.98768836 -0.12655823 0.048340935 -0.98768836 -0.14877811 0 -0.98768836 -0.15643455 + -0.048340935 -0.98768836 -0.1487781 -0.091949917 -0.98768836 -0.1265582 -0.12655818 -0.98768836 -0.091949902 + -0.14877807 -0.98768836 -0.048340924 -0.15643452 -0.98768836 0 -0.14877807 -0.98768836 0.048340924 + -0.12655818 -0.98768836 0.091949895 -0.091949895 -0.98768836 0.12655817 -0.048340924 -0.98768836 0.14877805 + -4.6621107e-09 -0.98768836 0.15643449 0.048340909 -0.98768836 0.14877804 0.09194988 -0.98768836 0.12655815 + 0.12655815 -0.98768836 0.091949888 0.14877804 -0.98768836 0.048340913 0.15643448 -0.98768836 0 + 0.29389283 -0.95105654 -0.095491566 0.25000018 -0.95105654 -0.18163574 0.18163574 -0.95105654 -0.25000015 + 0.095491551 -0.95105654 -0.2938928 0 -0.95105654 -0.30901715 -0.095491551 -0.95105654 -0.29389277 + -0.18163571 -0.95105654 -0.25000009 -0.25000009 -0.95105654 -0.18163569 -0.29389271 -0.95105654 -0.095491529 + -0.30901706 -0.95105654 0 -0.29389271 -0.95105654 0.095491529 -0.25000006 -0.95105654 0.18163568 + -0.18163568 -0.95105654 0.25000006 -0.095491529 -0.95105654 0.29389268 -9.2094243e-09 -0.95105654 0.30901703 + 0.095491499 -0.95105654 0.29389265 0.18163563 -0.95105654 0.25000003 0.25 -0.95105654 0.18163565 + 0.29389265 -0.95105654 0.095491506 0.309017 -0.95105654 0 0.43177092 -0.89100653 -0.14029087 + 0.36728629 -0.89100653 -0.2668491 0.2668491 -0.89100653 -0.36728626 0.14029086 -0.89100653 -0.43177086 + 0 -0.89100653 -0.45399073 -0.14029086 -0.89100653 -0.43177083 -0.26684904 -0.89100653 -0.36728618 + -0.36728615 -0.89100653 -0.26684901 -0.43177077 -0.89100653 -0.14029081 -0.45399064 -0.89100653 0 + -0.43177077 -0.89100653 0.14029081 -0.36728612 -0.89100653 0.26684898 -0.26684898 -0.89100653 0.36728612 + -0.14029081 -0.89100653 0.43177071 -1.3529972e-08 -0.89100653 0.45399058 0.14029078 -0.89100653 0.43177068 + 0.26684892 -0.89100653 0.36728609 0.36728606 -0.89100653 0.26684895 0.43177065 -0.89100653 0.1402908 + 0.45399052 -0.89100653 0 0.55901736 -0.809017 -0.18163574 0.47552857 -0.809017 -0.34549171 + 0.34549171 -0.809017 -0.47552854 0.18163572 -0.809017 -0.5590173 0 -0.809017 -0.58778554 + -0.18163572 -0.809017 -0.55901724 -0.34549165 -0.809017 -0.47552842 -0.47552839 -0.809017 -0.34549159 + -0.55901712 -0.809017 -0.18163566 -0.58778536 -0.809017 0 -0.55901712 -0.809017 0.18163566 + -0.47552836 -0.809017 0.34549156 -0.34549156 -0.809017 0.47552833 -0.18163566 -0.809017 0.55901706 + -1.7517365e-08 -0.809017 0.5877853 0.18163562 -0.809017 0.55901706 0.3454915 -0.809017 0.4755283 + 0.47552827 -0.809017 0.34549153 0.559017 -0.809017 0.18163563 0.58778524 -0.809017 0 + 0.67249894 -0.70710677 -0.21850814 0.57206178 -0.70710677 -0.41562718 0.41562718 -0.70710677 -0.57206172 + 0.21850812 -0.70710677 -0.67249888 0 -0.70710677 -0.70710713 -0.21850812 -0.70710677 -0.67249882 + -0.41562709 -0.70710677 -0.5720616 -0.57206154 -0.70710677 -0.41562706 -0.6724987 -0.70710677 -0.21850805 + -0.70710695 -0.70710677 0 -0.6724987 -0.70710677 0.21850805 -0.57206154 -0.70710677 0.415627 + -0.415627 -0.70710677 0.57206148 -0.21850805 -0.70710677 0.67249858 -2.1073424e-08 -0.70710677 0.70710683 + 0.21850799 -0.70710677 0.67249858 0.41562691 -0.70710677 0.57206142 0.57206142 -0.70710677 0.41562697 + 0.67249852 -0.70710677 0.21850802 0.70710677 -0.70710677 0 0.7694214 -0.58778524 -0.25000015 + 0.65450895 -0.58778524 -0.47552854 0.47552854 -0.58778524 -0.65450889 0.25000012 -0.58778524 -0.76942128 + 0 -0.58778524 -0.80901736 -0.25000012 -0.58778524 -0.76942122 -0.47552845 -0.58778524 -0.65450877 + -0.65450871 -0.58778524 -0.47552839 -0.7694211 -0.58778524 -0.25000006 -0.80901718 -0.58778524 0 + -0.7694211 -0.58778524 0.25000006 -0.65450865 -0.58778524 0.47552836 -0.47552836 -0.58778524 0.65450859 + -0.25000006 -0.58778524 0.76942098 -2.4110586e-08 -0.58778524 0.80901712 0.24999999 -0.58778524 0.76942098 + 0.47552827 -0.58778524 0.65450853 0.65450853 -0.58778524 0.4755283 0.76942092 -0.58778524 0.25 + 0.809017 -0.58778524 0 0.8473981 -0.45399052 -0.27533633 0.72083992 -0.45399052 -0.5237208 + 0.5237208 -0.45399052 -0.72083986 0.2753363 -0.45399052 -0.84739798 0 -0.45399052 -0.89100695 + -0.2753363 -0.45399052 -0.84739798 -0.52372068 -0.45399052 -0.72083968 -0.72083962 -0.45399052 -0.52372062 + -0.8473978 -0.45399052 -0.27533621 -0.89100677 -0.45399052 0 -0.8473978 -0.45399052 0.27533621 + -0.72083962 -0.45399052 0.52372062 -0.52372062 -0.45399052 0.72083956 -0.27533621 -0.45399052 0.84739769 + -2.6554064e-08 -0.45399052 0.89100665 0.27533615 -0.45399052 0.84739763 0.5237205 -0.45399052 0.7208395 + 0.72083944 -0.45399052 0.52372056 0.84739757 -0.45399052 0.27533618 0.89100653 -0.45399052 0 + 0.90450913 -0.30901697 -0.2938928 0.7694214 -0.30901697 -0.55901736 0.55901736 -0.30901697 -0.76942134 + 0.29389277 -0.30901697 -0.90450901 0 -0.30901697 -0.95105702 -0.29389277 -0.30901697 -0.90450895 + -0.55901724 -0.30901697 -0.76942122 -0.76942116 -0.30901697 -0.55901718 -0.90450877 -0.30901697 -0.29389271 + -0.95105678 -0.30901697 0 -0.90450877 -0.30901697 0.29389271 -0.7694211 -0.30901697 0.55901712 + -0.55901712 -0.30901697 0.76942104 -0.29389271 -0.30901697 0.90450865 -2.8343694e-08 -0.30901697 0.95105666 + 0.29389262 -0.30901697 0.90450859 0.559017 -0.30901697 0.76942098 0.76942092 -0.30901697 0.55901706 + 0.90450853 -0.30901697 0.29389265 0.95105654 -0.30901697 0 0.93934804 -0.15643437 -0.30521268 + 0.79905719 -0.15643437 -0.580549 0.580549 -0.15643437 -0.79905713 0.30521265 -0.15643437 -0.93934792 + 0 -0.15643437 -0.98768884 -0.30521265 -0.15643437 -0.93934786; + setAttr ".vt[166:331]" -0.58054888 -0.15643437 -0.79905695 -0.79905689 -0.15643437 -0.58054882 + -0.93934768 -0.15643437 -0.30521256 -0.9876886 -0.15643437 0 -0.93934768 -0.15643437 0.30521256 + -0.79905683 -0.15643437 0.58054876 -0.58054876 -0.15643437 0.79905677 -0.30521256 -0.15643437 0.93934757 + -2.9435407e-08 -0.15643437 0.98768848 0.30521247 -0.15643437 0.93934757 0.58054864 -0.15643437 0.79905671 + 0.79905665 -0.15643437 0.5805487 0.93934751 -0.15643437 0.3052125 0.98768836 -0.15643437 0 + 0.95105714 0 -0.30901718 0.80901754 0 -0.5877856 0.5877856 0 -0.80901748 0.30901715 0 -0.95105702 + 0 0 -1.000000476837 -0.30901715 0 -0.95105696 -0.58778548 0 -0.8090173 -0.80901724 0 -0.58778542 + -0.95105678 0 -0.30901706 -1.000000238419 0 0 -0.95105678 0 0.30901706 -0.80901718 0 0.58778536 + -0.58778536 0 0.80901712 -0.30901706 0 0.95105666 -2.9802322e-08 0 1.000000119209 + 0.30901697 0 0.9510566 0.58778524 0 0.80901706 0.809017 0 0.5877853 0.95105654 0 0.309017 + 1 0 0 0.93934804 0.15643437 -0.30521268 0.79905719 0.15643437 -0.580549 0.580549 0.15643437 -0.79905713 + 0.30521265 0.15643437 -0.93934792 0 0.15643437 -0.98768884 -0.30521265 0.15643437 -0.93934786 + -0.58054888 0.15643437 -0.79905695 -0.79905689 0.15643437 -0.58054882 -0.93934768 0.15643437 -0.30521256 + -0.9876886 0.15643437 0 -0.93934768 0.15643437 0.30521256 -0.79905683 0.15643437 0.58054876 + -0.58054876 0.15643437 0.79905677 -0.30521256 0.15643437 0.93934757 -2.9435407e-08 0.15643437 0.98768848 + 0.30521247 0.15643437 0.93934757 0.58054864 0.15643437 0.79905671 0.79905665 0.15643437 0.5805487 + 0.93934751 0.15643437 0.3052125 0.98768836 0.15643437 0 0.90450913 0.30901697 -0.2938928 + 0.7694214 0.30901697 -0.55901736 0.55901736 0.30901697 -0.76942134 0.29389277 0.30901697 -0.90450901 + 0 0.30901697 -0.95105702 -0.29389277 0.30901697 -0.90450895 -0.55901724 0.30901697 -0.76942122 + -0.76942116 0.30901697 -0.55901718 -0.90450877 0.30901697 -0.29389271 -0.95105678 0.30901697 0 + -0.90450877 0.30901697 0.29389271 -0.7694211 0.30901697 0.55901712 -0.55901712 0.30901697 0.76942104 + -0.29389271 0.30901697 0.90450865 -2.8343694e-08 0.30901697 0.95105666 0.29389262 0.30901697 0.90450859 + 0.559017 0.30901697 0.76942098 0.76942092 0.30901697 0.55901706 0.90450853 0.30901697 0.29389265 + 0.95105654 0.30901697 0 0.8473981 0.45399052 -0.27533633 0.72083992 0.45399052 -0.5237208 + 0.5237208 0.45399052 -0.72083986 0.2753363 0.45399052 -0.84739798 0 0.45399052 -0.89100695 + -0.2753363 0.45399052 -0.84739798 -0.52372068 0.45399052 -0.72083968 -0.72083962 0.45399052 -0.52372062 + -0.8473978 0.45399052 -0.27533621 -0.89100677 0.45399052 0 -0.8473978 0.45399052 0.27533621 + -0.72083962 0.45399052 0.52372062 -0.52372062 0.45399052 0.72083956 -0.27533621 0.45399052 0.84739769 + -2.6554064e-08 0.45399052 0.89100665 0.27533615 0.45399052 0.84739763 0.5237205 0.45399052 0.7208395 + 0.72083944 0.45399052 0.52372056 0.84739757 0.45399052 0.27533618 0.89100653 0.45399052 0 + 0.7694214 0.58778524 -0.25000015 0.65450895 0.58778524 -0.47552854 0.47552854 0.58778524 -0.65450889 + 0.25000012 0.58778524 -0.76942128 0 0.58778524 -0.80901736 -0.25000012 0.58778524 -0.76942122 + -0.47552845 0.58778524 -0.65450877 -0.65450871 0.58778524 -0.47552839 -0.7694211 0.58778524 -0.25000006 + -0.80901718 0.58778524 0 -0.7694211 0.58778524 0.25000006 -0.65450865 0.58778524 0.47552836 + -0.47552836 0.58778524 0.65450859 -0.25000006 0.58778524 0.76942098 -2.4110586e-08 0.58778524 0.80901712 + 0.24999999 0.58778524 0.76942098 0.47552827 0.58778524 0.65450853 0.65450853 0.58778524 0.4755283 + 0.76942092 0.58778524 0.25 0.809017 0.58778524 0 0.67249894 0.70710677 -0.21850814 + 0.57206178 0.70710677 -0.41562718 0.41562718 0.70710677 -0.57206172 0.21850812 0.70710677 -0.67249888 + 0 0.70710677 -0.70710713 -0.21850812 0.70710677 -0.67249882 -0.41562709 0.70710677 -0.5720616 + -0.57206154 0.70710677 -0.41562706 -0.6724987 0.70710677 -0.21850805 -0.70710695 0.70710677 0 + -0.6724987 0.70710677 0.21850805 -0.57206154 0.70710677 0.415627 -0.415627 0.70710677 0.57206148 + -0.21850805 0.70710677 0.67249858 -2.1073424e-08 0.70710677 0.70710683 0.21850799 0.70710677 0.67249858 + 0.41562691 0.70710677 0.57206142 0.57206142 0.70710677 0.41562697 0.67249852 0.70710677 0.21850802 + 0.70710677 0.70710677 0 0.55901736 0.809017 -0.18163574 0.47552857 0.809017 -0.34549171 + 0.34549171 0.809017 -0.47552854 0.18163572 0.809017 -0.5590173 0 0.809017 -0.58778554 + -0.18163572 0.809017 -0.55901724 -0.34549165 0.809017 -0.47552842 -0.47552839 0.809017 -0.34549159 + -0.55901712 0.809017 -0.18163566 -0.58778536 0.809017 0 -0.55901712 0.809017 0.18163566 + -0.47552836 0.809017 0.34549156 -0.34549156 0.809017 0.47552833 -0.18163566 0.809017 0.55901706 + -1.7517365e-08 0.809017 0.5877853 0.18163562 0.809017 0.55901706 0.3454915 0.809017 0.4755283 + 0.47552827 0.809017 0.34549153 0.559017 0.809017 0.18163563 0.58778524 0.809017 0 + 0.43177092 0.89100653 -0.14029087 0.36728629 0.89100653 -0.2668491 0.2668491 0.89100653 -0.36728626 + 0.14029086 0.89100653 -0.43177086 0 0.89100653 -0.45399073 -0.14029086 0.89100653 -0.43177083 + -0.26684904 0.89100653 -0.36728618 -0.36728615 0.89100653 -0.26684901 -0.43177077 0.89100653 -0.14029081 + -0.45399064 0.89100653 0 -0.43177077 0.89100653 0.14029081 -0.36728612 0.89100653 0.26684898; + setAttr ".vt[332:381]" -0.26684898 0.89100653 0.36728612 -0.14029081 0.89100653 0.43177071 + -1.3529972e-08 0.89100653 0.45399058 0.14029078 0.89100653 0.43177068 0.26684892 0.89100653 0.36728609 + 0.36728606 0.89100653 0.26684895 0.43177065 0.89100653 0.1402908 0.45399052 0.89100653 0 + 0.29389283 0.95105654 -0.095491566 0.25000018 0.95105654 -0.18163574 0.18163574 0.95105654 -0.25000015 + 0.095491551 0.95105654 -0.2938928 0 0.95105654 -0.30901715 -0.095491551 0.95105654 -0.29389277 + -0.18163571 0.95105654 -0.25000009 -0.25000009 0.95105654 -0.18163569 -0.29389271 0.95105654 -0.095491529 + -0.30901706 0.95105654 0 -0.29389271 0.95105654 0.095491529 -0.25000006 0.95105654 0.18163568 + -0.18163568 0.95105654 0.25000006 -0.095491529 0.95105654 0.29389268 -9.2094243e-09 0.95105654 0.30901703 + 0.095491499 0.95105654 0.29389265 0.18163563 0.95105654 0.25000003 0.25 0.95105654 0.18163565 + 0.29389265 0.95105654 0.095491506 0.309017 0.95105654 0 0.14877813 0.98768836 -0.048340943 + 0.12655823 0.98768836 -0.091949932 0.091949932 0.98768836 -0.12655823 0.048340935 0.98768836 -0.14877811 + 0 0.98768836 -0.15643455 -0.048340935 0.98768836 -0.1487781 -0.091949917 0.98768836 -0.1265582 + -0.12655818 0.98768836 -0.091949902 -0.14877807 0.98768836 -0.048340924 -0.15643452 0.98768836 0 + -0.14877807 0.98768836 0.048340924 -0.12655818 0.98768836 0.091949895 -0.091949895 0.98768836 0.12655817 + -0.048340924 0.98768836 0.14877805 -4.6621107e-09 0.98768836 0.15643449 0.048340909 0.98768836 0.14877804 + 0.09194988 0.98768836 0.12655815 0.12655815 0.98768836 0.091949888 0.14877804 0.98768836 0.048340913 + 0.15643448 0.98768836 0 0 -1 0 0 1 0; + setAttr -s 780 ".ed"; + setAttr ".ed[0:165]" 0 1 1 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1 6 7 1 7 8 1 8 9 1 + 9 10 1 10 11 1 11 12 1 12 13 1 13 14 1 14 15 1 15 16 1 16 17 1 17 18 1 18 19 1 19 0 1 + 20 21 1 21 22 1 22 23 1 23 24 1 24 25 1 25 26 1 26 27 1 27 28 1 28 29 1 29 30 1 30 31 1 + 31 32 1 32 33 1 33 34 1 34 35 1 35 36 1 36 37 1 37 38 1 38 39 1 39 20 1 40 41 1 41 42 1 + 42 43 1 43 44 1 44 45 1 45 46 1 46 47 1 47 48 1 48 49 1 49 50 1 50 51 1 51 52 1 52 53 1 + 53 54 1 54 55 1 55 56 1 56 57 1 57 58 1 58 59 1 59 40 1 60 61 1 61 62 1 62 63 1 63 64 1 + 64 65 1 65 66 1 66 67 1 67 68 1 68 69 1 69 70 1 70 71 1 71 72 1 72 73 1 73 74 1 74 75 1 + 75 76 1 76 77 1 77 78 1 78 79 1 79 60 1 80 81 1 81 82 1 82 83 1 83 84 1 84 85 1 85 86 1 + 86 87 1 87 88 1 88 89 1 89 90 1 90 91 1 91 92 1 92 93 1 93 94 1 94 95 1 95 96 1 96 97 1 + 97 98 1 98 99 1 99 80 1 100 101 1 101 102 1 102 103 1 103 104 1 104 105 1 105 106 1 + 106 107 1 107 108 1 108 109 1 109 110 1 110 111 1 111 112 1 112 113 1 113 114 1 114 115 1 + 115 116 1 116 117 1 117 118 1 118 119 1 119 100 1 120 121 1 121 122 1 122 123 1 123 124 1 + 124 125 1 125 126 1 126 127 1 127 128 1 128 129 1 129 130 1 130 131 1 131 132 1 132 133 1 + 133 134 1 134 135 1 135 136 1 136 137 1 137 138 1 138 139 1 139 120 1 140 141 1 141 142 1 + 142 143 1 143 144 1 144 145 1 145 146 1 146 147 1 147 148 1 148 149 1 149 150 1 150 151 1 + 151 152 1 152 153 1 153 154 1 154 155 1 155 156 1 156 157 1 157 158 1 158 159 1 159 140 1 + 160 161 1 161 162 1 162 163 1 163 164 1 164 165 1 165 166 1; + setAttr ".ed[166:331]" 166 167 1 167 168 1 168 169 1 169 170 1 170 171 1 171 172 1 + 172 173 1 173 174 1 174 175 1 175 176 1 176 177 1 177 178 1 178 179 1 179 160 1 180 181 1 + 181 182 1 182 183 1 183 184 1 184 185 1 185 186 1 186 187 1 187 188 1 188 189 1 189 190 1 + 190 191 1 191 192 1 192 193 1 193 194 1 194 195 1 195 196 1 196 197 1 197 198 1 198 199 1 + 199 180 1 200 201 1 201 202 1 202 203 1 203 204 1 204 205 1 205 206 1 206 207 1 207 208 1 + 208 209 1 209 210 1 210 211 1 211 212 1 212 213 1 213 214 1 214 215 1 215 216 1 216 217 1 + 217 218 1 218 219 1 219 200 1 220 221 1 221 222 1 222 223 1 223 224 1 224 225 1 225 226 1 + 226 227 1 227 228 1 228 229 1 229 230 1 230 231 1 231 232 1 232 233 1 233 234 1 234 235 1 + 235 236 1 236 237 1 237 238 1 238 239 1 239 220 1 240 241 1 241 242 1 242 243 1 243 244 1 + 244 245 1 245 246 1 246 247 1 247 248 1 248 249 1 249 250 1 250 251 1 251 252 1 252 253 1 + 253 254 1 254 255 1 255 256 1 256 257 1 257 258 1 258 259 1 259 240 1 260 261 1 261 262 1 + 262 263 1 263 264 1 264 265 1 265 266 1 266 267 1 267 268 1 268 269 1 269 270 1 270 271 1 + 271 272 1 272 273 1 273 274 1 274 275 1 275 276 1 276 277 1 277 278 1 278 279 1 279 260 1 + 280 281 1 281 282 1 282 283 1 283 284 1 284 285 1 285 286 1 286 287 1 287 288 1 288 289 1 + 289 290 1 290 291 1 291 292 1 292 293 1 293 294 1 294 295 1 295 296 1 296 297 1 297 298 1 + 298 299 1 299 280 1 300 301 1 301 302 1 302 303 1 303 304 1 304 305 1 305 306 1 306 307 1 + 307 308 1 308 309 1 309 310 1 310 311 1 311 312 1 312 313 1 313 314 1 314 315 1 315 316 1 + 316 317 1 317 318 1 318 319 1 319 300 1 320 321 1 321 322 1 322 323 1 323 324 1 324 325 1 + 325 326 1 326 327 1 327 328 1 328 329 1 329 330 1 330 331 1 331 332 1; + setAttr ".ed[332:497]" 332 333 1 333 334 1 334 335 1 335 336 1 336 337 1 337 338 1 + 338 339 1 339 320 1 340 341 1 341 342 1 342 343 1 343 344 1 344 345 1 345 346 1 346 347 1 + 347 348 1 348 349 1 349 350 1 350 351 1 351 352 1 352 353 1 353 354 1 354 355 1 355 356 1 + 356 357 1 357 358 1 358 359 1 359 340 1 360 361 1 361 362 1 362 363 1 363 364 1 364 365 1 + 365 366 1 366 367 1 367 368 1 368 369 1 369 370 1 370 371 1 371 372 1 372 373 1 373 374 1 + 374 375 1 375 376 1 376 377 1 377 378 1 378 379 1 379 360 1 0 20 1 1 21 1 2 22 1 + 3 23 1 4 24 1 5 25 1 6 26 1 7 27 1 8 28 1 9 29 1 10 30 1 11 31 1 12 32 1 13 33 1 + 14 34 1 15 35 1 16 36 1 17 37 1 18 38 1 19 39 1 20 40 1 21 41 1 22 42 1 23 43 1 24 44 1 + 25 45 1 26 46 1 27 47 1 28 48 1 29 49 1 30 50 1 31 51 1 32 52 1 33 53 1 34 54 1 35 55 1 + 36 56 1 37 57 1 38 58 1 39 59 1 40 60 1 41 61 1 42 62 1 43 63 1 44 64 1 45 65 1 46 66 1 + 47 67 1 48 68 1 49 69 1 50 70 1 51 71 1 52 72 1 53 73 1 54 74 1 55 75 1 56 76 1 57 77 1 + 58 78 1 59 79 1 60 80 1 61 81 1 62 82 1 63 83 1 64 84 1 65 85 1 66 86 1 67 87 1 68 88 1 + 69 89 1 70 90 1 71 91 1 72 92 1 73 93 1 74 94 1 75 95 1 76 96 1 77 97 1 78 98 1 79 99 1 + 80 100 1 81 101 1 82 102 1 83 103 1 84 104 1 85 105 1 86 106 1 87 107 1 88 108 1 + 89 109 1 90 110 1 91 111 1 92 112 1 93 113 1 94 114 1 95 115 1 96 116 1 97 117 1 + 98 118 1 99 119 1 100 120 1 101 121 1 102 122 1 103 123 1 104 124 1 105 125 1 106 126 1 + 107 127 1 108 128 1 109 129 1 110 130 1 111 131 1 112 132 1 113 133 1 114 134 1 115 135 1 + 116 136 1 117 137 1; + setAttr ".ed[498:663]" 118 138 1 119 139 1 120 140 1 121 141 1 122 142 1 123 143 1 + 124 144 1 125 145 1 126 146 1 127 147 1 128 148 1 129 149 1 130 150 1 131 151 1 132 152 1 + 133 153 1 134 154 1 135 155 1 136 156 1 137 157 1 138 158 1 139 159 1 140 160 1 141 161 1 + 142 162 1 143 163 1 144 164 1 145 165 1 146 166 1 147 167 1 148 168 1 149 169 1 150 170 1 + 151 171 1 152 172 1 153 173 1 154 174 1 155 175 1 156 176 1 157 177 1 158 178 1 159 179 1 + 160 180 1 161 181 1 162 182 1 163 183 1 164 184 1 165 185 1 166 186 1 167 187 1 168 188 1 + 169 189 1 170 190 1 171 191 1 172 192 1 173 193 1 174 194 1 175 195 1 176 196 1 177 197 1 + 178 198 1 179 199 1 180 200 1 181 201 1 182 202 1 183 203 1 184 204 1 185 205 1 186 206 1 + 187 207 1 188 208 1 189 209 1 190 210 1 191 211 1 192 212 1 193 213 1 194 214 1 195 215 1 + 196 216 1 197 217 1 198 218 1 199 219 1 200 220 1 201 221 1 202 222 1 203 223 1 204 224 1 + 205 225 1 206 226 1 207 227 1 208 228 1 209 229 1 210 230 1 211 231 1 212 232 1 213 233 1 + 214 234 1 215 235 1 216 236 1 217 237 1 218 238 1 219 239 1 220 240 1 221 241 1 222 242 1 + 223 243 1 224 244 1 225 245 1 226 246 1 227 247 1 228 248 1 229 249 1 230 250 1 231 251 1 + 232 252 1 233 253 1 234 254 1 235 255 1 236 256 1 237 257 1 238 258 1 239 259 1 240 260 1 + 241 261 1 242 262 1 243 263 1 244 264 1 245 265 1 246 266 1 247 267 1 248 268 1 249 269 1 + 250 270 1 251 271 1 252 272 1 253 273 1 254 274 1 255 275 1 256 276 1 257 277 1 258 278 1 + 259 279 1 260 280 1 261 281 1 262 282 1 263 283 1 264 284 1 265 285 1 266 286 1 267 287 1 + 268 288 1 269 289 1 270 290 1 271 291 1 272 292 1 273 293 1 274 294 1 275 295 1 276 296 1 + 277 297 1 278 298 1 279 299 1 280 300 1 281 301 1 282 302 1 283 303 1; + setAttr ".ed[664:779]" 284 304 1 285 305 1 286 306 1 287 307 1 288 308 1 289 309 1 + 290 310 1 291 311 1 292 312 1 293 313 1 294 314 1 295 315 1 296 316 1 297 317 1 298 318 1 + 299 319 1 300 320 1 301 321 1 302 322 1 303 323 1 304 324 1 305 325 1 306 326 1 307 327 1 + 308 328 1 309 329 1 310 330 1 311 331 1 312 332 1 313 333 1 314 334 1 315 335 1 316 336 1 + 317 337 1 318 338 1 319 339 1 320 340 1 321 341 1 322 342 1 323 343 1 324 344 1 325 345 1 + 326 346 1 327 347 1 328 348 1 329 349 1 330 350 1 331 351 1 332 352 1 333 353 1 334 354 1 + 335 355 1 336 356 1 337 357 1 338 358 1 339 359 1 340 360 1 341 361 1 342 362 1 343 363 1 + 344 364 1 345 365 1 346 366 1 347 367 1 348 368 1 349 369 1 350 370 1 351 371 1 352 372 1 + 353 373 1 354 374 1 355 375 1 356 376 1 357 377 1 358 378 1 359 379 1 380 0 1 380 1 1 + 380 2 1 380 3 1 380 4 1 380 5 1 380 6 1 380 7 1 380 8 1 380 9 1 380 10 1 380 11 1 + 380 12 1 380 13 1 380 14 1 380 15 1 380 16 1 380 17 1 380 18 1 380 19 1 360 381 1 + 361 381 1 362 381 1 363 381 1 364 381 1 365 381 1 366 381 1 367 381 1 368 381 1 369 381 1 + 370 381 1 371 381 1 372 381 1 373 381 1 374 381 1 375 381 1 376 381 1 377 381 1 378 381 1 + 379 381 1; + setAttr -s 400 -ch 1560 ".fc[0:399]" -type "polyFaces" + f 4 0 381 -21 -381 + mu 0 4 0 1 22 21 + f 4 1 382 -22 -382 + mu 0 4 1 2 23 22 + f 4 2 383 -23 -383 + mu 0 4 2 3 24 23 + f 4 3 384 -24 -384 + mu 0 4 3 4 25 24 + f 4 4 385 -25 -385 + mu 0 4 4 5 26 25 + f 4 5 386 -26 -386 + mu 0 4 5 6 27 26 + f 4 6 387 -27 -387 + mu 0 4 6 7 28 27 + f 4 7 388 -28 -388 + mu 0 4 7 8 29 28 + f 4 8 389 -29 -389 + mu 0 4 8 9 30 29 + f 4 9 390 -30 -390 + mu 0 4 9 10 31 30 + f 4 10 391 -31 -391 + mu 0 4 10 11 32 31 + f 4 11 392 -32 -392 + mu 0 4 11 12 33 32 + f 4 12 393 -33 -393 + mu 0 4 12 13 34 33 + f 4 13 394 -34 -394 + mu 0 4 13 14 35 34 + f 4 14 395 -35 -395 + mu 0 4 14 15 36 35 + f 4 15 396 -36 -396 + mu 0 4 15 16 37 36 + f 4 16 397 -37 -397 + mu 0 4 16 17 38 37 + f 4 17 398 -38 -398 + mu 0 4 17 18 39 38 + f 4 18 399 -39 -399 + mu 0 4 18 19 40 39 + f 4 19 380 -40 -400 + mu 0 4 19 20 41 40 + f 4 20 401 -41 -401 + mu 0 4 21 22 43 42 + f 4 21 402 -42 -402 + mu 0 4 22 23 44 43 + f 4 22 403 -43 -403 + mu 0 4 23 24 45 44 + f 4 23 404 -44 -404 + mu 0 4 24 25 46 45 + f 4 24 405 -45 -405 + mu 0 4 25 26 47 46 + f 4 25 406 -46 -406 + mu 0 4 26 27 48 47 + f 4 26 407 -47 -407 + mu 0 4 27 28 49 48 + f 4 27 408 -48 -408 + mu 0 4 28 29 50 49 + f 4 28 409 -49 -409 + mu 0 4 29 30 51 50 + f 4 29 410 -50 -410 + mu 0 4 30 31 52 51 + f 4 30 411 -51 -411 + mu 0 4 31 32 53 52 + f 4 31 412 -52 -412 + mu 0 4 32 33 54 53 + f 4 32 413 -53 -413 + mu 0 4 33 34 55 54 + f 4 33 414 -54 -414 + mu 0 4 34 35 56 55 + f 4 34 415 -55 -415 + mu 0 4 35 36 57 56 + f 4 35 416 -56 -416 + mu 0 4 36 37 58 57 + f 4 36 417 -57 -417 + mu 0 4 37 38 59 58 + f 4 37 418 -58 -418 + mu 0 4 38 39 60 59 + f 4 38 419 -59 -419 + mu 0 4 39 40 61 60 + f 4 39 400 -60 -420 + mu 0 4 40 41 62 61 + f 4 40 421 -61 -421 + mu 0 4 42 43 64 63 + f 4 41 422 -62 -422 + mu 0 4 43 44 65 64 + f 4 42 423 -63 -423 + mu 0 4 44 45 66 65 + f 4 43 424 -64 -424 + mu 0 4 45 46 67 66 + f 4 44 425 -65 -425 + mu 0 4 46 47 68 67 + f 4 45 426 -66 -426 + mu 0 4 47 48 69 68 + f 4 46 427 -67 -427 + mu 0 4 48 49 70 69 + f 4 47 428 -68 -428 + mu 0 4 49 50 71 70 + f 4 48 429 -69 -429 + mu 0 4 50 51 72 71 + f 4 49 430 -70 -430 + mu 0 4 51 52 73 72 + f 4 50 431 -71 -431 + mu 0 4 52 53 74 73 + f 4 51 432 -72 -432 + mu 0 4 53 54 75 74 + f 4 52 433 -73 -433 + mu 0 4 54 55 76 75 + f 4 53 434 -74 -434 + mu 0 4 55 56 77 76 + f 4 54 435 -75 -435 + mu 0 4 56 57 78 77 + f 4 55 436 -76 -436 + mu 0 4 57 58 79 78 + f 4 56 437 -77 -437 + mu 0 4 58 59 80 79 + f 4 57 438 -78 -438 + mu 0 4 59 60 81 80 + f 4 58 439 -79 -439 + mu 0 4 60 61 82 81 + f 4 59 420 -80 -440 + mu 0 4 61 62 83 82 + f 4 60 441 -81 -441 + mu 0 4 63 64 85 84 + f 4 61 442 -82 -442 + mu 0 4 64 65 86 85 + f 4 62 443 -83 -443 + mu 0 4 65 66 87 86 + f 4 63 444 -84 -444 + mu 0 4 66 67 88 87 + f 4 64 445 -85 -445 + mu 0 4 67 68 89 88 + f 4 65 446 -86 -446 + mu 0 4 68 69 90 89 + f 4 66 447 -87 -447 + mu 0 4 69 70 91 90 + f 4 67 448 -88 -448 + mu 0 4 70 71 92 91 + f 4 68 449 -89 -449 + mu 0 4 71 72 93 92 + f 4 69 450 -90 -450 + mu 0 4 72 73 94 93 + f 4 70 451 -91 -451 + mu 0 4 73 74 95 94 + f 4 71 452 -92 -452 + mu 0 4 74 75 96 95 + f 4 72 453 -93 -453 + mu 0 4 75 76 97 96 + f 4 73 454 -94 -454 + mu 0 4 76 77 98 97 + f 4 74 455 -95 -455 + mu 0 4 77 78 99 98 + f 4 75 456 -96 -456 + mu 0 4 78 79 100 99 + f 4 76 457 -97 -457 + mu 0 4 79 80 101 100 + f 4 77 458 -98 -458 + mu 0 4 80 81 102 101 + f 4 78 459 -99 -459 + mu 0 4 81 82 103 102 + f 4 79 440 -100 -460 + mu 0 4 82 83 104 103 + f 4 80 461 -101 -461 + mu 0 4 84 85 106 105 + f 4 81 462 -102 -462 + mu 0 4 85 86 107 106 + f 4 82 463 -103 -463 + mu 0 4 86 87 108 107 + f 4 83 464 -104 -464 + mu 0 4 87 88 109 108 + f 4 84 465 -105 -465 + mu 0 4 88 89 110 109 + f 4 85 466 -106 -466 + mu 0 4 89 90 111 110 + f 4 86 467 -107 -467 + mu 0 4 90 91 112 111 + f 4 87 468 -108 -468 + mu 0 4 91 92 113 112 + f 4 88 469 -109 -469 + mu 0 4 92 93 114 113 + f 4 89 470 -110 -470 + mu 0 4 93 94 115 114 + f 4 90 471 -111 -471 + mu 0 4 94 95 116 115 + f 4 91 472 -112 -472 + mu 0 4 95 96 117 116 + f 4 92 473 -113 -473 + mu 0 4 96 97 118 117 + f 4 93 474 -114 -474 + mu 0 4 97 98 119 118 + f 4 94 475 -115 -475 + mu 0 4 98 99 120 119 + f 4 95 476 -116 -476 + mu 0 4 99 100 121 120 + f 4 96 477 -117 -477 + mu 0 4 100 101 122 121 + f 4 97 478 -118 -478 + mu 0 4 101 102 123 122 + f 4 98 479 -119 -479 + mu 0 4 102 103 124 123 + f 4 99 460 -120 -480 + mu 0 4 103 104 125 124 + f 4 100 481 -121 -481 + mu 0 4 105 106 127 126 + f 4 101 482 -122 -482 + mu 0 4 106 107 128 127 + f 4 102 483 -123 -483 + mu 0 4 107 108 129 128 + f 4 103 484 -124 -484 + mu 0 4 108 109 130 129 + f 4 104 485 -125 -485 + mu 0 4 109 110 131 130 + f 4 105 486 -126 -486 + mu 0 4 110 111 132 131 + f 4 106 487 -127 -487 + mu 0 4 111 112 133 132 + f 4 107 488 -128 -488 + mu 0 4 112 113 134 133 + f 4 108 489 -129 -489 + mu 0 4 113 114 135 134 + f 4 109 490 -130 -490 + mu 0 4 114 115 136 135 + f 4 110 491 -131 -491 + mu 0 4 115 116 137 136 + f 4 111 492 -132 -492 + mu 0 4 116 117 138 137 + f 4 112 493 -133 -493 + mu 0 4 117 118 139 138 + f 4 113 494 -134 -494 + mu 0 4 118 119 140 139 + f 4 114 495 -135 -495 + mu 0 4 119 120 141 140 + f 4 115 496 -136 -496 + mu 0 4 120 121 142 141 + f 4 116 497 -137 -497 + mu 0 4 121 122 143 142 + f 4 117 498 -138 -498 + mu 0 4 122 123 144 143 + f 4 118 499 -139 -499 + mu 0 4 123 124 145 144 + f 4 119 480 -140 -500 + mu 0 4 124 125 146 145 + f 4 120 501 -141 -501 + mu 0 4 126 127 148 147 + f 4 121 502 -142 -502 + mu 0 4 127 128 149 148 + f 4 122 503 -143 -503 + mu 0 4 128 129 150 149 + f 4 123 504 -144 -504 + mu 0 4 129 130 151 150 + f 4 124 505 -145 -505 + mu 0 4 130 131 152 151 + f 4 125 506 -146 -506 + mu 0 4 131 132 153 152 + f 4 126 507 -147 -507 + mu 0 4 132 133 154 153 + f 4 127 508 -148 -508 + mu 0 4 133 134 155 154 + f 4 128 509 -149 -509 + mu 0 4 134 135 156 155 + f 4 129 510 -150 -510 + mu 0 4 135 136 157 156 + f 4 130 511 -151 -511 + mu 0 4 136 137 158 157 + f 4 131 512 -152 -512 + mu 0 4 137 138 159 158 + f 4 132 513 -153 -513 + mu 0 4 138 139 160 159 + f 4 133 514 -154 -514 + mu 0 4 139 140 161 160 + f 4 134 515 -155 -515 + mu 0 4 140 141 162 161 + f 4 135 516 -156 -516 + mu 0 4 141 142 163 162 + f 4 136 517 -157 -517 + mu 0 4 142 143 164 163 + f 4 137 518 -158 -518 + mu 0 4 143 144 165 164 + f 4 138 519 -159 -519 + mu 0 4 144 145 166 165 + f 4 139 500 -160 -520 + mu 0 4 145 146 167 166 + f 4 140 521 -161 -521 + mu 0 4 147 148 169 168 + f 4 141 522 -162 -522 + mu 0 4 148 149 170 169 + f 4 142 523 -163 -523 + mu 0 4 149 150 171 170 + f 4 143 524 -164 -524 + mu 0 4 150 151 172 171 + f 4 144 525 -165 -525 + mu 0 4 151 152 173 172 + f 4 145 526 -166 -526 + mu 0 4 152 153 174 173 + f 4 146 527 -167 -527 + mu 0 4 153 154 175 174 + f 4 147 528 -168 -528 + mu 0 4 154 155 176 175 + f 4 148 529 -169 -529 + mu 0 4 155 156 177 176 + f 4 149 530 -170 -530 + mu 0 4 156 157 178 177 + f 4 150 531 -171 -531 + mu 0 4 157 158 179 178 + f 4 151 532 -172 -532 + mu 0 4 158 159 180 179 + f 4 152 533 -173 -533 + mu 0 4 159 160 181 180 + f 4 153 534 -174 -534 + mu 0 4 160 161 182 181 + f 4 154 535 -175 -535 + mu 0 4 161 162 183 182 + f 4 155 536 -176 -536 + mu 0 4 162 163 184 183 + f 4 156 537 -177 -537 + mu 0 4 163 164 185 184 + f 4 157 538 -178 -538 + mu 0 4 164 165 186 185 + f 4 158 539 -179 -539 + mu 0 4 165 166 187 186 + f 4 159 520 -180 -540 + mu 0 4 166 167 188 187 + f 4 160 541 -181 -541 + mu 0 4 168 169 190 189 + f 4 161 542 -182 -542 + mu 0 4 169 170 191 190 + f 4 162 543 -183 -543 + mu 0 4 170 171 192 191 + f 4 163 544 -184 -544 + mu 0 4 171 172 193 192 + f 4 164 545 -185 -545 + mu 0 4 172 173 194 193 + f 4 165 546 -186 -546 + mu 0 4 173 174 195 194 + f 4 166 547 -187 -547 + mu 0 4 174 175 196 195 + f 4 167 548 -188 -548 + mu 0 4 175 176 197 196 + f 4 168 549 -189 -549 + mu 0 4 176 177 198 197 + f 4 169 550 -190 -550 + mu 0 4 177 178 199 198 + f 4 170 551 -191 -551 + mu 0 4 178 179 200 199 + f 4 171 552 -192 -552 + mu 0 4 179 180 201 200 + f 4 172 553 -193 -553 + mu 0 4 180 181 202 201 + f 4 173 554 -194 -554 + mu 0 4 181 182 203 202 + f 4 174 555 -195 -555 + mu 0 4 182 183 204 203 + f 4 175 556 -196 -556 + mu 0 4 183 184 205 204 + f 4 176 557 -197 -557 + mu 0 4 184 185 206 205 + f 4 177 558 -198 -558 + mu 0 4 185 186 207 206 + f 4 178 559 -199 -559 + mu 0 4 186 187 208 207 + f 4 179 540 -200 -560 + mu 0 4 187 188 209 208 + f 4 180 561 -201 -561 + mu 0 4 189 190 211 210 + f 4 181 562 -202 -562 + mu 0 4 190 191 212 211 + f 4 182 563 -203 -563 + mu 0 4 191 192 213 212 + f 4 183 564 -204 -564 + mu 0 4 192 193 214 213 + f 4 184 565 -205 -565 + mu 0 4 193 194 215 214 + f 4 185 566 -206 -566 + mu 0 4 194 195 216 215 + f 4 186 567 -207 -567 + mu 0 4 195 196 217 216 + f 4 187 568 -208 -568 + mu 0 4 196 197 218 217 + f 4 188 569 -209 -569 + mu 0 4 197 198 219 218 + f 4 189 570 -210 -570 + mu 0 4 198 199 220 219 + f 4 190 571 -211 -571 + mu 0 4 199 200 221 220 + f 4 191 572 -212 -572 + mu 0 4 200 201 222 221 + f 4 192 573 -213 -573 + mu 0 4 201 202 223 222 + f 4 193 574 -214 -574 + mu 0 4 202 203 224 223 + f 4 194 575 -215 -575 + mu 0 4 203 204 225 224 + f 4 195 576 -216 -576 + mu 0 4 204 205 226 225 + f 4 196 577 -217 -577 + mu 0 4 205 206 227 226 + f 4 197 578 -218 -578 + mu 0 4 206 207 228 227 + f 4 198 579 -219 -579 + mu 0 4 207 208 229 228 + f 4 199 560 -220 -580 + mu 0 4 208 209 230 229 + f 4 200 581 -221 -581 + mu 0 4 210 211 232 231 + f 4 201 582 -222 -582 + mu 0 4 211 212 233 232 + f 4 202 583 -223 -583 + mu 0 4 212 213 234 233 + f 4 203 584 -224 -584 + mu 0 4 213 214 235 234 + f 4 204 585 -225 -585 + mu 0 4 214 215 236 235 + f 4 205 586 -226 -586 + mu 0 4 215 216 237 236 + f 4 206 587 -227 -587 + mu 0 4 216 217 238 237 + f 4 207 588 -228 -588 + mu 0 4 217 218 239 238 + f 4 208 589 -229 -589 + mu 0 4 218 219 240 239 + f 4 209 590 -230 -590 + mu 0 4 219 220 241 240 + f 4 210 591 -231 -591 + mu 0 4 220 221 242 241 + f 4 211 592 -232 -592 + mu 0 4 221 222 243 242 + f 4 212 593 -233 -593 + mu 0 4 222 223 244 243 + f 4 213 594 -234 -594 + mu 0 4 223 224 245 244 + f 4 214 595 -235 -595 + mu 0 4 224 225 246 245 + f 4 215 596 -236 -596 + mu 0 4 225 226 247 246 + f 4 216 597 -237 -597 + mu 0 4 226 227 248 247 + f 4 217 598 -238 -598 + mu 0 4 227 228 249 248 + f 4 218 599 -239 -599 + mu 0 4 228 229 250 249 + f 4 219 580 -240 -600 + mu 0 4 229 230 251 250 + f 4 220 601 -241 -601 + mu 0 4 231 232 253 252 + f 4 221 602 -242 -602 + mu 0 4 232 233 254 253 + f 4 222 603 -243 -603 + mu 0 4 233 234 255 254 + f 4 223 604 -244 -604 + mu 0 4 234 235 256 255 + f 4 224 605 -245 -605 + mu 0 4 235 236 257 256 + f 4 225 606 -246 -606 + mu 0 4 236 237 258 257 + f 4 226 607 -247 -607 + mu 0 4 237 238 259 258 + f 4 227 608 -248 -608 + mu 0 4 238 239 260 259 + f 4 228 609 -249 -609 + mu 0 4 239 240 261 260 + f 4 229 610 -250 -610 + mu 0 4 240 241 262 261 + f 4 230 611 -251 -611 + mu 0 4 241 242 263 262 + f 4 231 612 -252 -612 + mu 0 4 242 243 264 263 + f 4 232 613 -253 -613 + mu 0 4 243 244 265 264 + f 4 233 614 -254 -614 + mu 0 4 244 245 266 265 + f 4 234 615 -255 -615 + mu 0 4 245 246 267 266 + f 4 235 616 -256 -616 + mu 0 4 246 247 268 267 + f 4 236 617 -257 -617 + mu 0 4 247 248 269 268 + f 4 237 618 -258 -618 + mu 0 4 248 249 270 269 + f 4 238 619 -259 -619 + mu 0 4 249 250 271 270 + f 4 239 600 -260 -620 + mu 0 4 250 251 272 271 + f 4 240 621 -261 -621 + mu 0 4 252 253 274 273 + f 4 241 622 -262 -622 + mu 0 4 253 254 275 274 + f 4 242 623 -263 -623 + mu 0 4 254 255 276 275 + f 4 243 624 -264 -624 + mu 0 4 255 256 277 276 + f 4 244 625 -265 -625 + mu 0 4 256 257 278 277 + f 4 245 626 -266 -626 + mu 0 4 257 258 279 278 + f 4 246 627 -267 -627 + mu 0 4 258 259 280 279 + f 4 247 628 -268 -628 + mu 0 4 259 260 281 280 + f 4 248 629 -269 -629 + mu 0 4 260 261 282 281 + f 4 249 630 -270 -630 + mu 0 4 261 262 283 282 + f 4 250 631 -271 -631 + mu 0 4 262 263 284 283 + f 4 251 632 -272 -632 + mu 0 4 263 264 285 284 + f 4 252 633 -273 -633 + mu 0 4 264 265 286 285 + f 4 253 634 -274 -634 + mu 0 4 265 266 287 286 + f 4 254 635 -275 -635 + mu 0 4 266 267 288 287 + f 4 255 636 -276 -636 + mu 0 4 267 268 289 288 + f 4 256 637 -277 -637 + mu 0 4 268 269 290 289 + f 4 257 638 -278 -638 + mu 0 4 269 270 291 290 + f 4 258 639 -279 -639 + mu 0 4 270 271 292 291 + f 4 259 620 -280 -640 + mu 0 4 271 272 293 292 + f 4 260 641 -281 -641 + mu 0 4 273 274 295 294 + f 4 261 642 -282 -642 + mu 0 4 274 275 296 295 + f 4 262 643 -283 -643 + mu 0 4 275 276 297 296 + f 4 263 644 -284 -644 + mu 0 4 276 277 298 297 + f 4 264 645 -285 -645 + mu 0 4 277 278 299 298 + f 4 265 646 -286 -646 + mu 0 4 278 279 300 299 + f 4 266 647 -287 -647 + mu 0 4 279 280 301 300 + f 4 267 648 -288 -648 + mu 0 4 280 281 302 301 + f 4 268 649 -289 -649 + mu 0 4 281 282 303 302 + f 4 269 650 -290 -650 + mu 0 4 282 283 304 303 + f 4 270 651 -291 -651 + mu 0 4 283 284 305 304 + f 4 271 652 -292 -652 + mu 0 4 284 285 306 305 + f 4 272 653 -293 -653 + mu 0 4 285 286 307 306 + f 4 273 654 -294 -654 + mu 0 4 286 287 308 307 + f 4 274 655 -295 -655 + mu 0 4 287 288 309 308 + f 4 275 656 -296 -656 + mu 0 4 288 289 310 309 + f 4 276 657 -297 -657 + mu 0 4 289 290 311 310 + f 4 277 658 -298 -658 + mu 0 4 290 291 312 311 + f 4 278 659 -299 -659 + mu 0 4 291 292 313 312 + f 4 279 640 -300 -660 + mu 0 4 292 293 314 313 + f 4 280 661 -301 -661 + mu 0 4 294 295 316 315 + f 4 281 662 -302 -662 + mu 0 4 295 296 317 316 + f 4 282 663 -303 -663 + mu 0 4 296 297 318 317 + f 4 283 664 -304 -664 + mu 0 4 297 298 319 318 + f 4 284 665 -305 -665 + mu 0 4 298 299 320 319 + f 4 285 666 -306 -666 + mu 0 4 299 300 321 320 + f 4 286 667 -307 -667 + mu 0 4 300 301 322 321 + f 4 287 668 -308 -668 + mu 0 4 301 302 323 322 + f 4 288 669 -309 -669 + mu 0 4 302 303 324 323 + f 4 289 670 -310 -670 + mu 0 4 303 304 325 324 + f 4 290 671 -311 -671 + mu 0 4 304 305 326 325 + f 4 291 672 -312 -672 + mu 0 4 305 306 327 326 + f 4 292 673 -313 -673 + mu 0 4 306 307 328 327 + f 4 293 674 -314 -674 + mu 0 4 307 308 329 328 + f 4 294 675 -315 -675 + mu 0 4 308 309 330 329 + f 4 295 676 -316 -676 + mu 0 4 309 310 331 330 + f 4 296 677 -317 -677 + mu 0 4 310 311 332 331 + f 4 297 678 -318 -678 + mu 0 4 311 312 333 332 + f 4 298 679 -319 -679 + mu 0 4 312 313 334 333 + f 4 299 660 -320 -680 + mu 0 4 313 314 335 334 + f 4 300 681 -321 -681 + mu 0 4 315 316 337 336 + f 4 301 682 -322 -682 + mu 0 4 316 317 338 337 + f 4 302 683 -323 -683 + mu 0 4 317 318 339 338 + f 4 303 684 -324 -684 + mu 0 4 318 319 340 339 + f 4 304 685 -325 -685 + mu 0 4 319 320 341 340 + f 4 305 686 -326 -686 + mu 0 4 320 321 342 341 + f 4 306 687 -327 -687 + mu 0 4 321 322 343 342 + f 4 307 688 -328 -688 + mu 0 4 322 323 344 343 + f 4 308 689 -329 -689 + mu 0 4 323 324 345 344 + f 4 309 690 -330 -690 + mu 0 4 324 325 346 345 + f 4 310 691 -331 -691 + mu 0 4 325 326 347 346 + f 4 311 692 -332 -692 + mu 0 4 326 327 348 347 + f 4 312 693 -333 -693 + mu 0 4 327 328 349 348 + f 4 313 694 -334 -694 + mu 0 4 328 329 350 349 + f 4 314 695 -335 -695 + mu 0 4 329 330 351 350 + f 4 315 696 -336 -696 + mu 0 4 330 331 352 351 + f 4 316 697 -337 -697 + mu 0 4 331 332 353 352 + f 4 317 698 -338 -698 + mu 0 4 332 333 354 353 + f 4 318 699 -339 -699 + mu 0 4 333 334 355 354 + f 4 319 680 -340 -700 + mu 0 4 334 335 356 355 + f 4 320 701 -341 -701 + mu 0 4 336 337 358 357 + f 4 321 702 -342 -702 + mu 0 4 337 338 359 358 + f 4 322 703 -343 -703 + mu 0 4 338 339 360 359 + f 4 323 704 -344 -704 + mu 0 4 339 340 361 360 + f 4 324 705 -345 -705 + mu 0 4 340 341 362 361 + f 4 325 706 -346 -706 + mu 0 4 341 342 363 362 + f 4 326 707 -347 -707 + mu 0 4 342 343 364 363 + f 4 327 708 -348 -708 + mu 0 4 343 344 365 364 + f 4 328 709 -349 -709 + mu 0 4 344 345 366 365 + f 4 329 710 -350 -710 + mu 0 4 345 346 367 366 + f 4 330 711 -351 -711 + mu 0 4 346 347 368 367 + f 4 331 712 -352 -712 + mu 0 4 347 348 369 368 + f 4 332 713 -353 -713 + mu 0 4 348 349 370 369 + f 4 333 714 -354 -714 + mu 0 4 349 350 371 370 + f 4 334 715 -355 -715 + mu 0 4 350 351 372 371 + f 4 335 716 -356 -716 + mu 0 4 351 352 373 372 + f 4 336 717 -357 -717 + mu 0 4 352 353 374 373 + f 4 337 718 -358 -718 + mu 0 4 353 354 375 374 + f 4 338 719 -359 -719 + mu 0 4 354 355 376 375 + f 4 339 700 -360 -720 + mu 0 4 355 356 377 376 + f 4 340 721 -361 -721 + mu 0 4 357 358 379 378 + f 4 341 722 -362 -722 + mu 0 4 358 359 380 379 + f 4 342 723 -363 -723 + mu 0 4 359 360 381 380 + f 4 343 724 -364 -724 + mu 0 4 360 361 382 381 + f 4 344 725 -365 -725 + mu 0 4 361 362 383 382 + f 4 345 726 -366 -726 + mu 0 4 362 363 384 383 + f 4 346 727 -367 -727 + mu 0 4 363 364 385 384 + f 4 347 728 -368 -728 + mu 0 4 364 365 386 385 + f 4 348 729 -369 -729 + mu 0 4 365 366 387 386 + f 4 349 730 -370 -730 + mu 0 4 366 367 388 387 + f 4 350 731 -371 -731 + mu 0 4 367 368 389 388 + f 4 351 732 -372 -732 + mu 0 4 368 369 390 389 + f 4 352 733 -373 -733 + mu 0 4 369 370 391 390 + f 4 353 734 -374 -734 + mu 0 4 370 371 392 391 + f 4 354 735 -375 -735 + mu 0 4 371 372 393 392 + f 4 355 736 -376 -736 + mu 0 4 372 373 394 393 + f 4 356 737 -377 -737 + mu 0 4 373 374 395 394 + f 4 357 738 -378 -738 + mu 0 4 374 375 396 395 + f 4 358 739 -379 -739 + mu 0 4 375 376 397 396 + f 4 359 720 -380 -740 + mu 0 4 376 377 398 397 + f 3 -1 -741 741 + mu 0 3 1 0 399 + f 3 -2 -742 742 + mu 0 3 2 1 400 + f 3 -3 -743 743 + mu 0 3 3 2 401 + f 3 -4 -744 744 + mu 0 3 4 3 402 + f 3 -5 -745 745 + mu 0 3 5 4 403 + f 3 -6 -746 746 + mu 0 3 6 5 404 + f 3 -7 -747 747 + mu 0 3 7 6 405 + f 3 -8 -748 748 + mu 0 3 8 7 406 + f 3 -9 -749 749 + mu 0 3 9 8 407 + f 3 -10 -750 750 + mu 0 3 10 9 408 + f 3 -11 -751 751 + mu 0 3 11 10 409 + f 3 -12 -752 752 + mu 0 3 12 11 410 + f 3 -13 -753 753 + mu 0 3 13 12 411 + f 3 -14 -754 754 + mu 0 3 14 13 412 + f 3 -15 -755 755 + mu 0 3 15 14 413 + f 3 -16 -756 756 + mu 0 3 16 15 414 + f 3 -17 -757 757 + mu 0 3 17 16 415 + f 3 -18 -758 758 + mu 0 3 18 17 416 + f 3 -19 -759 759 + mu 0 3 19 18 417 + f 3 -20 -760 740 + mu 0 3 20 19 418 + f 3 360 761 -761 + mu 0 3 378 379 419 + f 3 361 762 -762 + mu 0 3 379 380 420 + f 3 362 763 -763 + mu 0 3 380 381 421 + f 3 363 764 -764 + mu 0 3 381 382 422 + f 3 364 765 -765 + mu 0 3 382 383 423 + f 3 365 766 -766 + mu 0 3 383 384 424 + f 3 366 767 -767 + mu 0 3 384 385 425 + f 3 367 768 -768 + mu 0 3 385 386 426 + f 3 368 769 -769 + mu 0 3 386 387 427 + f 3 369 770 -770 + mu 0 3 387 388 428 + f 3 370 771 -771 + mu 0 3 388 389 429 + f 3 371 772 -772 + mu 0 3 389 390 430 + f 3 372 773 -773 + mu 0 3 390 391 431 + f 3 373 774 -774 + mu 0 3 391 392 432 + f 3 374 775 -775 + mu 0 3 392 393 433 + f 3 375 776 -776 + mu 0 3 393 394 434 + f 3 376 777 -777 + mu 0 3 394 395 435 + f 3 377 778 -778 + mu 0 3 395 396 436 + f 3 378 779 -779 + mu 0 3 396 397 437 + f 3 379 760 -780 + mu 0 3 397 398 438; + setAttr ".cd" -type "dataPolyComponent" Index_Data Edge 0 ; + setAttr ".cvd" -type "dataPolyComponent" Index_Data Vertex 0 ; + setAttr ".pd[0]" -type "dataPolyComponent" Index_Data UV 0 ; + setAttr ".hfd" -type "dataPolyComponent" Index_Data Face 0 ; + setAttr ".dr" 1; + setAttr ".ai_translator" -type "string" "polymesh"; + setAttr ".cbId" -type "string" "60df31e2be2b48bd3695c056:6c77a15a98a9"; +select -ne :time1; + setAttr ".o" 1001; + setAttr ".unw" 1001; +select -ne :hardwareRenderingGlobals; + setAttr ".otfna" -type "stringArray" 22 "NURBS Curves" "NURBS Surfaces" "Polygons" "Subdiv Surface" "Particles" "Particle Instance" "Fluids" "Strokes" "Image Planes" "UI" "Lights" "Cameras" "Locators" "Joints" "IK Handles" "Deformers" "Motion Trails" "Components" "Hair Systems" "Follicles" "Misc. UI" "Ornaments" ; + setAttr ".otfva" -type "Int32Array" 22 0 1 1 1 1 1 + 1 1 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 ; + setAttr ".fprt" yes; +select -ne :renderPartition; + setAttr -s 2 ".st"; +select -ne :renderGlobalsList1; +select -ne :defaultShaderList1; + setAttr -s 5 ".s"; +select -ne :postProcessList1; + setAttr -s 2 ".p"; +select -ne :defaultRenderingList1; + setAttr -s 2 ".r"; +select -ne :lightList1; +select -ne :initialShadingGroup; + setAttr -s 2 ".dsm"; + setAttr ".ro" yes; +select -ne :initialParticleSE; + setAttr ".ro" yes; +select -ne :defaultRenderGlobals; + addAttr -ci true -h true -sn "dss" -ln "defaultSurfaceShader" -dt "string"; + setAttr ".ren" -type "string" "arnold"; + setAttr ".outf" 51; + setAttr ".imfkey" -type "string" "exr"; + setAttr ".an" yes; + setAttr ".fs" 1001; + setAttr ".ef" 1001; + setAttr ".oft" -type "string" ""; + setAttr ".pff" yes; + setAttr ".ifp" -type "string" "//_"; + setAttr ".rv" -type "string" ""; + setAttr ".pram" -type "string" ""; + setAttr ".poam" -type "string" ""; + setAttr ".prlm" -type "string" ""; + setAttr ".polm" -type "string" ""; + setAttr ".prm" -type "string" ""; + setAttr ".pom" -type "string" ""; + setAttr ".dss" -type "string" "lambert1"; +select -ne :defaultResolution; + setAttr ".w" 1920; + setAttr ".h" 1080; + setAttr ".pa" 1; + setAttr ".dar" 1.7777777910232544; +select -ne :defaultLightSet; +select -ne :hardwareRenderGlobals; + setAttr ".ctrs" 256; + setAttr ".btrs" 512; +connectAttr "pSphere1_GEOShape1.iog" ":initialShadingGroup.dsm" -na; +// End of modelMain.ma diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.abc b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.abc new file mode 100644 index 0000000000000000000000000000000000000000..d9e54259960efb658348c78adaa0f9ae0958083e GIT binary patch literal 24787 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 MH=R?xes^8}8yK4hrvLx| literal 0 HcmV?d00001 diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.ma b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.ma new file mode 100644 index 0000000000..9ee588337e --- /dev/null +++ b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/model/modelMain/v001/test_project_test_asset_modelMain_v001.ma @@ -0,0 +1,1208 @@ +//Maya ASCII 2020 scene +//Name: modelMain.ma +//Last modified: Mon, Oct 24, 2022 02:57:47 PM +//Codeset: 1252 +requires maya "2020"; +requires "mtoa" "4.1.1"; +currentUnit -l centimeter -a degree -t pal; +fileInfo "application" "maya"; +fileInfo "product" "Maya 2020"; +fileInfo "version" "2020"; +fileInfo "cutIdentifier" "202011110415-b1e20b88e2"; +fileInfo "osv" "Microsoft Windows 10 Technical Preview (Build 19044)\n"; +fileInfo "UUID" "A787A358-4FE7-6E55-0C81-61BFEB0C2726"; +createNode transform -n "model_GRP"; + rename -uid "445FDC20-4A9D-2C5B-C7BD-F98F6E660B5C"; + setAttr ".rlio[0]" 1 yes 0; +createNode transform -n "pSphere1_GEO" -p "model_GRP"; + rename -uid "7445A43F-444F-B2D3-4315-2AA013D2E0B6"; + addAttr -ci true -sn "cbId" -ln "cbId" -dt "string"; + setAttr ".cbId" -type "string" "60df31e2be2b48bd3695c056:302a4c6123a4"; +createNode mesh -n "pSphere1_GEOShape1" -p "pSphere1_GEO"; + rename -uid "7C731260-45C6-339E-07BF-359446B08EA1"; + addAttr -ci true -sn "cbId" -ln "cbId" -dt "string"; + setAttr -k off ".v"; + setAttr ".vir" yes; + setAttr ".vif" yes; + setAttr ".uvst[0].uvsn" -type "string" "map1"; + setAttr -s 439 ".uvst[0].uvsp"; + setAttr ".uvst[0].uvsp[0:249]" -type "float2" 0 0.050000001 0.050000001 0.050000001 + 0.1 0.050000001 0.15000001 0.050000001 0.2 0.050000001 0.25 0.050000001 0.30000001 + 0.050000001 0.35000002 0.050000001 0.40000004 0.050000001 0.45000005 0.050000001 + 0.50000006 0.050000001 0.55000007 0.050000001 0.60000008 0.050000001 0.6500001 0.050000001 + 0.70000011 0.050000001 0.75000012 0.050000001 0.80000013 0.050000001 0.85000014 0.050000001 + 0.90000015 0.050000001 0.95000017 0.050000001 1.000000119209 0.050000001 0 0.1 0.050000001 + 0.1 0.1 0.1 0.15000001 0.1 0.2 0.1 0.25 0.1 0.30000001 0.1 0.35000002 0.1 0.40000004 + 0.1 0.45000005 0.1 0.50000006 0.1 0.55000007 0.1 0.60000008 0.1 0.6500001 0.1 0.70000011 + 0.1 0.75000012 0.1 0.80000013 0.1 0.85000014 0.1 0.90000015 0.1 0.95000017 0.1 1.000000119209 + 0.1 0 0.15000001 0.050000001 0.15000001 0.1 0.15000001 0.15000001 0.15000001 0.2 + 0.15000001 0.25 0.15000001 0.30000001 0.15000001 0.35000002 0.15000001 0.40000004 + 0.15000001 0.45000005 0.15000001 0.50000006 0.15000001 0.55000007 0.15000001 0.60000008 + 0.15000001 0.6500001 0.15000001 0.70000011 0.15000001 0.75000012 0.15000001 0.80000013 + 0.15000001 0.85000014 0.15000001 0.90000015 0.15000001 0.95000017 0.15000001 1.000000119209 + 0.15000001 0 0.2 0.050000001 0.2 0.1 0.2 0.15000001 0.2 0.2 0.2 0.25 0.2 0.30000001 + 0.2 0.35000002 0.2 0.40000004 0.2 0.45000005 0.2 0.50000006 0.2 0.55000007 0.2 0.60000008 + 0.2 0.6500001 0.2 0.70000011 0.2 0.75000012 0.2 0.80000013 0.2 0.85000014 0.2 0.90000015 + 0.2 0.95000017 0.2 1.000000119209 0.2 0 0.25 0.050000001 0.25 0.1 0.25 0.15000001 + 0.25 0.2 0.25 0.25 0.25 0.30000001 0.25 0.35000002 0.25 0.40000004 0.25 0.45000005 + 0.25 0.50000006 0.25 0.55000007 0.25 0.60000008 0.25 0.6500001 0.25 0.70000011 0.25 + 0.75000012 0.25 0.80000013 0.25 0.85000014 0.25 0.90000015 0.25 0.95000017 0.25 1.000000119209 + 0.25 0 0.30000001 0.050000001 0.30000001 0.1 0.30000001 0.15000001 0.30000001 0.2 + 0.30000001 0.25 0.30000001 0.30000001 0.30000001 0.35000002 0.30000001 0.40000004 + 0.30000001 0.45000005 0.30000001 0.50000006 0.30000001 0.55000007 0.30000001 0.60000008 + 0.30000001 0.6500001 0.30000001 0.70000011 0.30000001 0.75000012 0.30000001 0.80000013 + 0.30000001 0.85000014 0.30000001 0.90000015 0.30000001 0.95000017 0.30000001 1.000000119209 + 0.30000001 0 0.35000002 0.050000001 0.35000002 0.1 0.35000002 0.15000001 0.35000002 + 0.2 0.35000002 0.25 0.35000002 0.30000001 0.35000002 0.35000002 0.35000002 0.40000004 + 0.35000002 0.45000005 0.35000002 0.50000006 0.35000002 0.55000007 0.35000002 0.60000008 + 0.35000002 0.6500001 0.35000002 0.70000011 0.35000002 0.75000012 0.35000002 0.80000013 + 0.35000002 0.85000014 0.35000002 0.90000015 0.35000002 0.95000017 0.35000002 1.000000119209 + 0.35000002 0 0.40000004 0.050000001 0.40000004 0.1 0.40000004 0.15000001 0.40000004 + 0.2 0.40000004 0.25 0.40000004 0.30000001 0.40000004 0.35000002 0.40000004 0.40000004 + 0.40000004 0.45000005 0.40000004 0.50000006 0.40000004 0.55000007 0.40000004 0.60000008 + 0.40000004 0.6500001 0.40000004 0.70000011 0.40000004 0.75000012 0.40000004 0.80000013 + 0.40000004 0.85000014 0.40000004 0.90000015 0.40000004 0.95000017 0.40000004 1.000000119209 + 0.40000004 0 0.45000005 0.050000001 0.45000005 0.1 0.45000005 0.15000001 0.45000005 + 0.2 0.45000005 0.25 0.45000005 0.30000001 0.45000005 0.35000002 0.45000005 0.40000004 + 0.45000005 0.45000005 0.45000005 0.50000006 0.45000005 0.55000007 0.45000005 0.60000008 + 0.45000005 0.6500001 0.45000005 0.70000011 0.45000005 0.75000012 0.45000005 0.80000013 + 0.45000005 0.85000014 0.45000005 0.90000015 0.45000005 0.95000017 0.45000005 1.000000119209 + 0.45000005 0 0.50000006 0.050000001 0.50000006 0.1 0.50000006 0.15000001 0.50000006 + 0.2 0.50000006 0.25 0.50000006 0.30000001 0.50000006 0.35000002 0.50000006 0.40000004 + 0.50000006 0.45000005 0.50000006 0.50000006 0.50000006 0.55000007 0.50000006 0.60000008 + 0.50000006 0.6500001 0.50000006 0.70000011 0.50000006 0.75000012 0.50000006 0.80000013 + 0.50000006 0.85000014 0.50000006 0.90000015 0.50000006 0.95000017 0.50000006 1.000000119209 + 0.50000006 0 0.55000007 0.050000001 0.55000007 0.1 0.55000007 0.15000001 0.55000007 + 0.2 0.55000007 0.25 0.55000007 0.30000001 0.55000007 0.35000002 0.55000007 0.40000004 + 0.55000007 0.45000005 0.55000007 0.50000006 0.55000007 0.55000007 0.55000007 0.60000008 + 0.55000007 0.6500001 0.55000007 0.70000011 0.55000007 0.75000012 0.55000007 0.80000013 + 0.55000007 0.85000014 0.55000007 0.90000015 0.55000007 0.95000017 0.55000007 1.000000119209 + 0.55000007 0 0.60000008 0.050000001 0.60000008 0.1 0.60000008 0.15000001 0.60000008 + 0.2 0.60000008 0.25 0.60000008 0.30000001 0.60000008 0.35000002 0.60000008 0.40000004 + 0.60000008 0.45000005 0.60000008 0.50000006 0.60000008 0.55000007 0.60000008 0.60000008 + 0.60000008 0.6500001 0.60000008 0.70000011 0.60000008 0.75000012 0.60000008 0.80000013 + 0.60000008 0.85000014 0.60000008 0.90000015 0.60000008; + setAttr ".uvst[0].uvsp[250:438]" 0.95000017 0.60000008 1.000000119209 0.60000008 + 0 0.6500001 0.050000001 0.6500001 0.1 0.6500001 0.15000001 0.6500001 0.2 0.6500001 + 0.25 0.6500001 0.30000001 0.6500001 0.35000002 0.6500001 0.40000004 0.6500001 0.45000005 + 0.6500001 0.50000006 0.6500001 0.55000007 0.6500001 0.60000008 0.6500001 0.6500001 + 0.6500001 0.70000011 0.6500001 0.75000012 0.6500001 0.80000013 0.6500001 0.85000014 + 0.6500001 0.90000015 0.6500001 0.95000017 0.6500001 1.000000119209 0.6500001 0 0.70000011 + 0.050000001 0.70000011 0.1 0.70000011 0.15000001 0.70000011 0.2 0.70000011 0.25 0.70000011 + 0.30000001 0.70000011 0.35000002 0.70000011 0.40000004 0.70000011 0.45000005 0.70000011 + 0.50000006 0.70000011 0.55000007 0.70000011 0.60000008 0.70000011 0.6500001 0.70000011 + 0.70000011 0.70000011 0.75000012 0.70000011 0.80000013 0.70000011 0.85000014 0.70000011 + 0.90000015 0.70000011 0.95000017 0.70000011 1.000000119209 0.70000011 0 0.75000012 + 0.050000001 0.75000012 0.1 0.75000012 0.15000001 0.75000012 0.2 0.75000012 0.25 0.75000012 + 0.30000001 0.75000012 0.35000002 0.75000012 0.40000004 0.75000012 0.45000005 0.75000012 + 0.50000006 0.75000012 0.55000007 0.75000012 0.60000008 0.75000012 0.6500001 0.75000012 + 0.70000011 0.75000012 0.75000012 0.75000012 0.80000013 0.75000012 0.85000014 0.75000012 + 0.90000015 0.75000012 0.95000017 0.75000012 1.000000119209 0.75000012 0 0.80000013 + 0.050000001 0.80000013 0.1 0.80000013 0.15000001 0.80000013 0.2 0.80000013 0.25 0.80000013 + 0.30000001 0.80000013 0.35000002 0.80000013 0.40000004 0.80000013 0.45000005 0.80000013 + 0.50000006 0.80000013 0.55000007 0.80000013 0.60000008 0.80000013 0.6500001 0.80000013 + 0.70000011 0.80000013 0.75000012 0.80000013 0.80000013 0.80000013 0.85000014 0.80000013 + 0.90000015 0.80000013 0.95000017 0.80000013 1.000000119209 0.80000013 0 0.85000014 + 0.050000001 0.85000014 0.1 0.85000014 0.15000001 0.85000014 0.2 0.85000014 0.25 0.85000014 + 0.30000001 0.85000014 0.35000002 0.85000014 0.40000004 0.85000014 0.45000005 0.85000014 + 0.50000006 0.85000014 0.55000007 0.85000014 0.60000008 0.85000014 0.6500001 0.85000014 + 0.70000011 0.85000014 0.75000012 0.85000014 0.80000013 0.85000014 0.85000014 0.85000014 + 0.90000015 0.85000014 0.95000017 0.85000014 1.000000119209 0.85000014 0 0.90000015 + 0.050000001 0.90000015 0.1 0.90000015 0.15000001 0.90000015 0.2 0.90000015 0.25 0.90000015 + 0.30000001 0.90000015 0.35000002 0.90000015 0.40000004 0.90000015 0.45000005 0.90000015 + 0.50000006 0.90000015 0.55000007 0.90000015 0.60000008 0.90000015 0.6500001 0.90000015 + 0.70000011 0.90000015 0.75000012 0.90000015 0.80000013 0.90000015 0.85000014 0.90000015 + 0.90000015 0.90000015 0.95000017 0.90000015 1.000000119209 0.90000015 0 0.95000017 + 0.050000001 0.95000017 0.1 0.95000017 0.15000001 0.95000017 0.2 0.95000017 0.25 0.95000017 + 0.30000001 0.95000017 0.35000002 0.95000017 0.40000004 0.95000017 0.45000005 0.95000017 + 0.50000006 0.95000017 0.55000007 0.95000017 0.60000008 0.95000017 0.6500001 0.95000017 + 0.70000011 0.95000017 0.75000012 0.95000017 0.80000013 0.95000017 0.85000014 0.95000017 + 0.90000015 0.95000017 0.95000017 0.95000017 1.000000119209 0.95000017 0.025 0 0.075000003 + 0 0.125 0 0.17500001 0 0.22500001 0 0.27500001 0 0.32500002 0 0.375 0 0.42500001 + 0 0.47500002 0 0.52499998 0 0.57499999 0 0.625 0 0.67500001 0 0.72499996 0 0.77499998 + 0 0.82499999 0 0.875 0 0.92500001 0 0.97499996 0 0.025 1 0.075000003 1 0.125 1 0.17500001 + 1 0.22500001 1 0.27500001 1 0.32500002 1 0.375 1 0.42500001 1 0.47500002 1 0.52499998 + 1 0.57499999 1 0.625 1 0.67500001 1 0.72499996 1 0.77499998 1 0.82499999 1 0.875 + 1 0.92500001 1 0.97499996 1; + setAttr ".cuvs" -type "string" "map1"; + setAttr ".dcc" -type "string" "Ambient+Diffuse"; + setAttr ".covm[0]" 0 1 1; + setAttr ".cdvm[0]" 0 1 1; + setAttr -s 382 ".vt"; + setAttr ".vt[0:165]" 0.14877813 -0.98768836 -0.048340943 0.12655823 -0.98768836 -0.091949932 + 0.091949932 -0.98768836 -0.12655823 0.048340935 -0.98768836 -0.14877811 0 -0.98768836 -0.15643455 + -0.048340935 -0.98768836 -0.1487781 -0.091949917 -0.98768836 -0.1265582 -0.12655818 -0.98768836 -0.091949902 + -0.14877807 -0.98768836 -0.048340924 -0.15643452 -0.98768836 0 -0.14877807 -0.98768836 0.048340924 + -0.12655818 -0.98768836 0.091949895 -0.091949895 -0.98768836 0.12655817 -0.048340924 -0.98768836 0.14877805 + -4.6621107e-09 -0.98768836 0.15643449 0.048340909 -0.98768836 0.14877804 0.09194988 -0.98768836 0.12655815 + 0.12655815 -0.98768836 0.091949888 0.14877804 -0.98768836 0.048340913 0.15643448 -0.98768836 0 + 0.29389283 -0.95105654 -0.095491566 0.25000018 -0.95105654 -0.18163574 0.18163574 -0.95105654 -0.25000015 + 0.095491551 -0.95105654 -0.2938928 0 -0.95105654 -0.30901715 -0.095491551 -0.95105654 -0.29389277 + -0.18163571 -0.95105654 -0.25000009 -0.25000009 -0.95105654 -0.18163569 -0.29389271 -0.95105654 -0.095491529 + -0.30901706 -0.95105654 0 -0.29389271 -0.95105654 0.095491529 -0.25000006 -0.95105654 0.18163568 + -0.18163568 -0.95105654 0.25000006 -0.095491529 -0.95105654 0.29389268 -9.2094243e-09 -0.95105654 0.30901703 + 0.095491499 -0.95105654 0.29389265 0.18163563 -0.95105654 0.25000003 0.25 -0.95105654 0.18163565 + 0.29389265 -0.95105654 0.095491506 0.309017 -0.95105654 0 0.43177092 -0.89100653 -0.14029087 + 0.36728629 -0.89100653 -0.2668491 0.2668491 -0.89100653 -0.36728626 0.14029086 -0.89100653 -0.43177086 + 0 -0.89100653 -0.45399073 -0.14029086 -0.89100653 -0.43177083 -0.26684904 -0.89100653 -0.36728618 + -0.36728615 -0.89100653 -0.26684901 -0.43177077 -0.89100653 -0.14029081 -0.45399064 -0.89100653 0 + -0.43177077 -0.89100653 0.14029081 -0.36728612 -0.89100653 0.26684898 -0.26684898 -0.89100653 0.36728612 + -0.14029081 -0.89100653 0.43177071 -1.3529972e-08 -0.89100653 0.45399058 0.14029078 -0.89100653 0.43177068 + 0.26684892 -0.89100653 0.36728609 0.36728606 -0.89100653 0.26684895 0.43177065 -0.89100653 0.1402908 + 0.45399052 -0.89100653 0 0.55901736 -0.809017 -0.18163574 0.47552857 -0.809017 -0.34549171 + 0.34549171 -0.809017 -0.47552854 0.18163572 -0.809017 -0.5590173 0 -0.809017 -0.58778554 + -0.18163572 -0.809017 -0.55901724 -0.34549165 -0.809017 -0.47552842 -0.47552839 -0.809017 -0.34549159 + -0.55901712 -0.809017 -0.18163566 -0.58778536 -0.809017 0 -0.55901712 -0.809017 0.18163566 + -0.47552836 -0.809017 0.34549156 -0.34549156 -0.809017 0.47552833 -0.18163566 -0.809017 0.55901706 + -1.7517365e-08 -0.809017 0.5877853 0.18163562 -0.809017 0.55901706 0.3454915 -0.809017 0.4755283 + 0.47552827 -0.809017 0.34549153 0.559017 -0.809017 0.18163563 0.58778524 -0.809017 0 + 0.67249894 -0.70710677 -0.21850814 0.57206178 -0.70710677 -0.41562718 0.41562718 -0.70710677 -0.57206172 + 0.21850812 -0.70710677 -0.67249888 0 -0.70710677 -0.70710713 -0.21850812 -0.70710677 -0.67249882 + -0.41562709 -0.70710677 -0.5720616 -0.57206154 -0.70710677 -0.41562706 -0.6724987 -0.70710677 -0.21850805 + -0.70710695 -0.70710677 0 -0.6724987 -0.70710677 0.21850805 -0.57206154 -0.70710677 0.415627 + -0.415627 -0.70710677 0.57206148 -0.21850805 -0.70710677 0.67249858 -2.1073424e-08 -0.70710677 0.70710683 + 0.21850799 -0.70710677 0.67249858 0.41562691 -0.70710677 0.57206142 0.57206142 -0.70710677 0.41562697 + 0.67249852 -0.70710677 0.21850802 0.70710677 -0.70710677 0 0.7694214 -0.58778524 -0.25000015 + 0.65450895 -0.58778524 -0.47552854 0.47552854 -0.58778524 -0.65450889 0.25000012 -0.58778524 -0.76942128 + 0 -0.58778524 -0.80901736 -0.25000012 -0.58778524 -0.76942122 -0.47552845 -0.58778524 -0.65450877 + -0.65450871 -0.58778524 -0.47552839 -0.7694211 -0.58778524 -0.25000006 -0.80901718 -0.58778524 0 + -0.7694211 -0.58778524 0.25000006 -0.65450865 -0.58778524 0.47552836 -0.47552836 -0.58778524 0.65450859 + -0.25000006 -0.58778524 0.76942098 -2.4110586e-08 -0.58778524 0.80901712 0.24999999 -0.58778524 0.76942098 + 0.47552827 -0.58778524 0.65450853 0.65450853 -0.58778524 0.4755283 0.76942092 -0.58778524 0.25 + 0.809017 -0.58778524 0 0.8473981 -0.45399052 -0.27533633 0.72083992 -0.45399052 -0.5237208 + 0.5237208 -0.45399052 -0.72083986 0.2753363 -0.45399052 -0.84739798 0 -0.45399052 -0.89100695 + -0.2753363 -0.45399052 -0.84739798 -0.52372068 -0.45399052 -0.72083968 -0.72083962 -0.45399052 -0.52372062 + -0.8473978 -0.45399052 -0.27533621 -0.89100677 -0.45399052 0 -0.8473978 -0.45399052 0.27533621 + -0.72083962 -0.45399052 0.52372062 -0.52372062 -0.45399052 0.72083956 -0.27533621 -0.45399052 0.84739769 + -2.6554064e-08 -0.45399052 0.89100665 0.27533615 -0.45399052 0.84739763 0.5237205 -0.45399052 0.7208395 + 0.72083944 -0.45399052 0.52372056 0.84739757 -0.45399052 0.27533618 0.89100653 -0.45399052 0 + 0.90450913 -0.30901697 -0.2938928 0.7694214 -0.30901697 -0.55901736 0.55901736 -0.30901697 -0.76942134 + 0.29389277 -0.30901697 -0.90450901 0 -0.30901697 -0.95105702 -0.29389277 -0.30901697 -0.90450895 + -0.55901724 -0.30901697 -0.76942122 -0.76942116 -0.30901697 -0.55901718 -0.90450877 -0.30901697 -0.29389271 + -0.95105678 -0.30901697 0 -0.90450877 -0.30901697 0.29389271 -0.7694211 -0.30901697 0.55901712 + -0.55901712 -0.30901697 0.76942104 -0.29389271 -0.30901697 0.90450865 -2.8343694e-08 -0.30901697 0.95105666 + 0.29389262 -0.30901697 0.90450859 0.559017 -0.30901697 0.76942098 0.76942092 -0.30901697 0.55901706 + 0.90450853 -0.30901697 0.29389265 0.95105654 -0.30901697 0 0.93934804 -0.15643437 -0.30521268 + 0.79905719 -0.15643437 -0.580549 0.580549 -0.15643437 -0.79905713 0.30521265 -0.15643437 -0.93934792 + 0 -0.15643437 -0.98768884 -0.30521265 -0.15643437 -0.93934786; + setAttr ".vt[166:331]" -0.58054888 -0.15643437 -0.79905695 -0.79905689 -0.15643437 -0.58054882 + -0.93934768 -0.15643437 -0.30521256 -0.9876886 -0.15643437 0 -0.93934768 -0.15643437 0.30521256 + -0.79905683 -0.15643437 0.58054876 -0.58054876 -0.15643437 0.79905677 -0.30521256 -0.15643437 0.93934757 + -2.9435407e-08 -0.15643437 0.98768848 0.30521247 -0.15643437 0.93934757 0.58054864 -0.15643437 0.79905671 + 0.79905665 -0.15643437 0.5805487 0.93934751 -0.15643437 0.3052125 0.98768836 -0.15643437 0 + 0.95105714 0 -0.30901718 0.80901754 0 -0.5877856 0.5877856 0 -0.80901748 0.30901715 0 -0.95105702 + 0 0 -1.000000476837 -0.30901715 0 -0.95105696 -0.58778548 0 -0.8090173 -0.80901724 0 -0.58778542 + -0.95105678 0 -0.30901706 -1.000000238419 0 0 -0.95105678 0 0.30901706 -0.80901718 0 0.58778536 + -0.58778536 0 0.80901712 -0.30901706 0 0.95105666 -2.9802322e-08 0 1.000000119209 + 0.30901697 0 0.9510566 0.58778524 0 0.80901706 0.809017 0 0.5877853 0.95105654 0 0.309017 + 1 0 0 0.93934804 0.15643437 -0.30521268 0.79905719 0.15643437 -0.580549 0.580549 0.15643437 -0.79905713 + 0.30521265 0.15643437 -0.93934792 0 0.15643437 -0.98768884 -0.30521265 0.15643437 -0.93934786 + -0.58054888 0.15643437 -0.79905695 -0.79905689 0.15643437 -0.58054882 -0.93934768 0.15643437 -0.30521256 + -0.9876886 0.15643437 0 -0.93934768 0.15643437 0.30521256 -0.79905683 0.15643437 0.58054876 + -0.58054876 0.15643437 0.79905677 -0.30521256 0.15643437 0.93934757 -2.9435407e-08 0.15643437 0.98768848 + 0.30521247 0.15643437 0.93934757 0.58054864 0.15643437 0.79905671 0.79905665 0.15643437 0.5805487 + 0.93934751 0.15643437 0.3052125 0.98768836 0.15643437 0 0.90450913 0.30901697 -0.2938928 + 0.7694214 0.30901697 -0.55901736 0.55901736 0.30901697 -0.76942134 0.29389277 0.30901697 -0.90450901 + 0 0.30901697 -0.95105702 -0.29389277 0.30901697 -0.90450895 -0.55901724 0.30901697 -0.76942122 + -0.76942116 0.30901697 -0.55901718 -0.90450877 0.30901697 -0.29389271 -0.95105678 0.30901697 0 + -0.90450877 0.30901697 0.29389271 -0.7694211 0.30901697 0.55901712 -0.55901712 0.30901697 0.76942104 + -0.29389271 0.30901697 0.90450865 -2.8343694e-08 0.30901697 0.95105666 0.29389262 0.30901697 0.90450859 + 0.559017 0.30901697 0.76942098 0.76942092 0.30901697 0.55901706 0.90450853 0.30901697 0.29389265 + 0.95105654 0.30901697 0 0.8473981 0.45399052 -0.27533633 0.72083992 0.45399052 -0.5237208 + 0.5237208 0.45399052 -0.72083986 0.2753363 0.45399052 -0.84739798 0 0.45399052 -0.89100695 + -0.2753363 0.45399052 -0.84739798 -0.52372068 0.45399052 -0.72083968 -0.72083962 0.45399052 -0.52372062 + -0.8473978 0.45399052 -0.27533621 -0.89100677 0.45399052 0 -0.8473978 0.45399052 0.27533621 + -0.72083962 0.45399052 0.52372062 -0.52372062 0.45399052 0.72083956 -0.27533621 0.45399052 0.84739769 + -2.6554064e-08 0.45399052 0.89100665 0.27533615 0.45399052 0.84739763 0.5237205 0.45399052 0.7208395 + 0.72083944 0.45399052 0.52372056 0.84739757 0.45399052 0.27533618 0.89100653 0.45399052 0 + 0.7694214 0.58778524 -0.25000015 0.65450895 0.58778524 -0.47552854 0.47552854 0.58778524 -0.65450889 + 0.25000012 0.58778524 -0.76942128 0 0.58778524 -0.80901736 -0.25000012 0.58778524 -0.76942122 + -0.47552845 0.58778524 -0.65450877 -0.65450871 0.58778524 -0.47552839 -0.7694211 0.58778524 -0.25000006 + -0.80901718 0.58778524 0 -0.7694211 0.58778524 0.25000006 -0.65450865 0.58778524 0.47552836 + -0.47552836 0.58778524 0.65450859 -0.25000006 0.58778524 0.76942098 -2.4110586e-08 0.58778524 0.80901712 + 0.24999999 0.58778524 0.76942098 0.47552827 0.58778524 0.65450853 0.65450853 0.58778524 0.4755283 + 0.76942092 0.58778524 0.25 0.809017 0.58778524 0 0.67249894 0.70710677 -0.21850814 + 0.57206178 0.70710677 -0.41562718 0.41562718 0.70710677 -0.57206172 0.21850812 0.70710677 -0.67249888 + 0 0.70710677 -0.70710713 -0.21850812 0.70710677 -0.67249882 -0.41562709 0.70710677 -0.5720616 + -0.57206154 0.70710677 -0.41562706 -0.6724987 0.70710677 -0.21850805 -0.70710695 0.70710677 0 + -0.6724987 0.70710677 0.21850805 -0.57206154 0.70710677 0.415627 -0.415627 0.70710677 0.57206148 + -0.21850805 0.70710677 0.67249858 -2.1073424e-08 0.70710677 0.70710683 0.21850799 0.70710677 0.67249858 + 0.41562691 0.70710677 0.57206142 0.57206142 0.70710677 0.41562697 0.67249852 0.70710677 0.21850802 + 0.70710677 0.70710677 0 0.55901736 0.809017 -0.18163574 0.47552857 0.809017 -0.34549171 + 0.34549171 0.809017 -0.47552854 0.18163572 0.809017 -0.5590173 0 0.809017 -0.58778554 + -0.18163572 0.809017 -0.55901724 -0.34549165 0.809017 -0.47552842 -0.47552839 0.809017 -0.34549159 + -0.55901712 0.809017 -0.18163566 -0.58778536 0.809017 0 -0.55901712 0.809017 0.18163566 + -0.47552836 0.809017 0.34549156 -0.34549156 0.809017 0.47552833 -0.18163566 0.809017 0.55901706 + -1.7517365e-08 0.809017 0.5877853 0.18163562 0.809017 0.55901706 0.3454915 0.809017 0.4755283 + 0.47552827 0.809017 0.34549153 0.559017 0.809017 0.18163563 0.58778524 0.809017 0 + 0.43177092 0.89100653 -0.14029087 0.36728629 0.89100653 -0.2668491 0.2668491 0.89100653 -0.36728626 + 0.14029086 0.89100653 -0.43177086 0 0.89100653 -0.45399073 -0.14029086 0.89100653 -0.43177083 + -0.26684904 0.89100653 -0.36728618 -0.36728615 0.89100653 -0.26684901 -0.43177077 0.89100653 -0.14029081 + -0.45399064 0.89100653 0 -0.43177077 0.89100653 0.14029081 -0.36728612 0.89100653 0.26684898; + setAttr ".vt[332:381]" -0.26684898 0.89100653 0.36728612 -0.14029081 0.89100653 0.43177071 + -1.3529972e-08 0.89100653 0.45399058 0.14029078 0.89100653 0.43177068 0.26684892 0.89100653 0.36728609 + 0.36728606 0.89100653 0.26684895 0.43177065 0.89100653 0.1402908 0.45399052 0.89100653 0 + 0.29389283 0.95105654 -0.095491566 0.25000018 0.95105654 -0.18163574 0.18163574 0.95105654 -0.25000015 + 0.095491551 0.95105654 -0.2938928 0 0.95105654 -0.30901715 -0.095491551 0.95105654 -0.29389277 + -0.18163571 0.95105654 -0.25000009 -0.25000009 0.95105654 -0.18163569 -0.29389271 0.95105654 -0.095491529 + -0.30901706 0.95105654 0 -0.29389271 0.95105654 0.095491529 -0.25000006 0.95105654 0.18163568 + -0.18163568 0.95105654 0.25000006 -0.095491529 0.95105654 0.29389268 -9.2094243e-09 0.95105654 0.30901703 + 0.095491499 0.95105654 0.29389265 0.18163563 0.95105654 0.25000003 0.25 0.95105654 0.18163565 + 0.29389265 0.95105654 0.095491506 0.309017 0.95105654 0 0.14877813 0.98768836 -0.048340943 + 0.12655823 0.98768836 -0.091949932 0.091949932 0.98768836 -0.12655823 0.048340935 0.98768836 -0.14877811 + 0 0.98768836 -0.15643455 -0.048340935 0.98768836 -0.1487781 -0.091949917 0.98768836 -0.1265582 + -0.12655818 0.98768836 -0.091949902 -0.14877807 0.98768836 -0.048340924 -0.15643452 0.98768836 0 + -0.14877807 0.98768836 0.048340924 -0.12655818 0.98768836 0.091949895 -0.091949895 0.98768836 0.12655817 + -0.048340924 0.98768836 0.14877805 -4.6621107e-09 0.98768836 0.15643449 0.048340909 0.98768836 0.14877804 + 0.09194988 0.98768836 0.12655815 0.12655815 0.98768836 0.091949888 0.14877804 0.98768836 0.048340913 + 0.15643448 0.98768836 0 0 -1 0 0 1 0; + setAttr -s 780 ".ed"; + setAttr ".ed[0:165]" 0 1 1 1 2 1 2 3 1 3 4 1 4 5 1 5 6 1 6 7 1 7 8 1 8 9 1 + 9 10 1 10 11 1 11 12 1 12 13 1 13 14 1 14 15 1 15 16 1 16 17 1 17 18 1 18 19 1 19 0 1 + 20 21 1 21 22 1 22 23 1 23 24 1 24 25 1 25 26 1 26 27 1 27 28 1 28 29 1 29 30 1 30 31 1 + 31 32 1 32 33 1 33 34 1 34 35 1 35 36 1 36 37 1 37 38 1 38 39 1 39 20 1 40 41 1 41 42 1 + 42 43 1 43 44 1 44 45 1 45 46 1 46 47 1 47 48 1 48 49 1 49 50 1 50 51 1 51 52 1 52 53 1 + 53 54 1 54 55 1 55 56 1 56 57 1 57 58 1 58 59 1 59 40 1 60 61 1 61 62 1 62 63 1 63 64 1 + 64 65 1 65 66 1 66 67 1 67 68 1 68 69 1 69 70 1 70 71 1 71 72 1 72 73 1 73 74 1 74 75 1 + 75 76 1 76 77 1 77 78 1 78 79 1 79 60 1 80 81 1 81 82 1 82 83 1 83 84 1 84 85 1 85 86 1 + 86 87 1 87 88 1 88 89 1 89 90 1 90 91 1 91 92 1 92 93 1 93 94 1 94 95 1 95 96 1 96 97 1 + 97 98 1 98 99 1 99 80 1 100 101 1 101 102 1 102 103 1 103 104 1 104 105 1 105 106 1 + 106 107 1 107 108 1 108 109 1 109 110 1 110 111 1 111 112 1 112 113 1 113 114 1 114 115 1 + 115 116 1 116 117 1 117 118 1 118 119 1 119 100 1 120 121 1 121 122 1 122 123 1 123 124 1 + 124 125 1 125 126 1 126 127 1 127 128 1 128 129 1 129 130 1 130 131 1 131 132 1 132 133 1 + 133 134 1 134 135 1 135 136 1 136 137 1 137 138 1 138 139 1 139 120 1 140 141 1 141 142 1 + 142 143 1 143 144 1 144 145 1 145 146 1 146 147 1 147 148 1 148 149 1 149 150 1 150 151 1 + 151 152 1 152 153 1 153 154 1 154 155 1 155 156 1 156 157 1 157 158 1 158 159 1 159 140 1 + 160 161 1 161 162 1 162 163 1 163 164 1 164 165 1 165 166 1; + setAttr ".ed[166:331]" 166 167 1 167 168 1 168 169 1 169 170 1 170 171 1 171 172 1 + 172 173 1 173 174 1 174 175 1 175 176 1 176 177 1 177 178 1 178 179 1 179 160 1 180 181 1 + 181 182 1 182 183 1 183 184 1 184 185 1 185 186 1 186 187 1 187 188 1 188 189 1 189 190 1 + 190 191 1 191 192 1 192 193 1 193 194 1 194 195 1 195 196 1 196 197 1 197 198 1 198 199 1 + 199 180 1 200 201 1 201 202 1 202 203 1 203 204 1 204 205 1 205 206 1 206 207 1 207 208 1 + 208 209 1 209 210 1 210 211 1 211 212 1 212 213 1 213 214 1 214 215 1 215 216 1 216 217 1 + 217 218 1 218 219 1 219 200 1 220 221 1 221 222 1 222 223 1 223 224 1 224 225 1 225 226 1 + 226 227 1 227 228 1 228 229 1 229 230 1 230 231 1 231 232 1 232 233 1 233 234 1 234 235 1 + 235 236 1 236 237 1 237 238 1 238 239 1 239 220 1 240 241 1 241 242 1 242 243 1 243 244 1 + 244 245 1 245 246 1 246 247 1 247 248 1 248 249 1 249 250 1 250 251 1 251 252 1 252 253 1 + 253 254 1 254 255 1 255 256 1 256 257 1 257 258 1 258 259 1 259 240 1 260 261 1 261 262 1 + 262 263 1 263 264 1 264 265 1 265 266 1 266 267 1 267 268 1 268 269 1 269 270 1 270 271 1 + 271 272 1 272 273 1 273 274 1 274 275 1 275 276 1 276 277 1 277 278 1 278 279 1 279 260 1 + 280 281 1 281 282 1 282 283 1 283 284 1 284 285 1 285 286 1 286 287 1 287 288 1 288 289 1 + 289 290 1 290 291 1 291 292 1 292 293 1 293 294 1 294 295 1 295 296 1 296 297 1 297 298 1 + 298 299 1 299 280 1 300 301 1 301 302 1 302 303 1 303 304 1 304 305 1 305 306 1 306 307 1 + 307 308 1 308 309 1 309 310 1 310 311 1 311 312 1 312 313 1 313 314 1 314 315 1 315 316 1 + 316 317 1 317 318 1 318 319 1 319 300 1 320 321 1 321 322 1 322 323 1 323 324 1 324 325 1 + 325 326 1 326 327 1 327 328 1 328 329 1 329 330 1 330 331 1 331 332 1; + setAttr ".ed[332:497]" 332 333 1 333 334 1 334 335 1 335 336 1 336 337 1 337 338 1 + 338 339 1 339 320 1 340 341 1 341 342 1 342 343 1 343 344 1 344 345 1 345 346 1 346 347 1 + 347 348 1 348 349 1 349 350 1 350 351 1 351 352 1 352 353 1 353 354 1 354 355 1 355 356 1 + 356 357 1 357 358 1 358 359 1 359 340 1 360 361 1 361 362 1 362 363 1 363 364 1 364 365 1 + 365 366 1 366 367 1 367 368 1 368 369 1 369 370 1 370 371 1 371 372 1 372 373 1 373 374 1 + 374 375 1 375 376 1 376 377 1 377 378 1 378 379 1 379 360 1 0 20 1 1 21 1 2 22 1 + 3 23 1 4 24 1 5 25 1 6 26 1 7 27 1 8 28 1 9 29 1 10 30 1 11 31 1 12 32 1 13 33 1 + 14 34 1 15 35 1 16 36 1 17 37 1 18 38 1 19 39 1 20 40 1 21 41 1 22 42 1 23 43 1 24 44 1 + 25 45 1 26 46 1 27 47 1 28 48 1 29 49 1 30 50 1 31 51 1 32 52 1 33 53 1 34 54 1 35 55 1 + 36 56 1 37 57 1 38 58 1 39 59 1 40 60 1 41 61 1 42 62 1 43 63 1 44 64 1 45 65 1 46 66 1 + 47 67 1 48 68 1 49 69 1 50 70 1 51 71 1 52 72 1 53 73 1 54 74 1 55 75 1 56 76 1 57 77 1 + 58 78 1 59 79 1 60 80 1 61 81 1 62 82 1 63 83 1 64 84 1 65 85 1 66 86 1 67 87 1 68 88 1 + 69 89 1 70 90 1 71 91 1 72 92 1 73 93 1 74 94 1 75 95 1 76 96 1 77 97 1 78 98 1 79 99 1 + 80 100 1 81 101 1 82 102 1 83 103 1 84 104 1 85 105 1 86 106 1 87 107 1 88 108 1 + 89 109 1 90 110 1 91 111 1 92 112 1 93 113 1 94 114 1 95 115 1 96 116 1 97 117 1 + 98 118 1 99 119 1 100 120 1 101 121 1 102 122 1 103 123 1 104 124 1 105 125 1 106 126 1 + 107 127 1 108 128 1 109 129 1 110 130 1 111 131 1 112 132 1 113 133 1 114 134 1 115 135 1 + 116 136 1 117 137 1; + setAttr ".ed[498:663]" 118 138 1 119 139 1 120 140 1 121 141 1 122 142 1 123 143 1 + 124 144 1 125 145 1 126 146 1 127 147 1 128 148 1 129 149 1 130 150 1 131 151 1 132 152 1 + 133 153 1 134 154 1 135 155 1 136 156 1 137 157 1 138 158 1 139 159 1 140 160 1 141 161 1 + 142 162 1 143 163 1 144 164 1 145 165 1 146 166 1 147 167 1 148 168 1 149 169 1 150 170 1 + 151 171 1 152 172 1 153 173 1 154 174 1 155 175 1 156 176 1 157 177 1 158 178 1 159 179 1 + 160 180 1 161 181 1 162 182 1 163 183 1 164 184 1 165 185 1 166 186 1 167 187 1 168 188 1 + 169 189 1 170 190 1 171 191 1 172 192 1 173 193 1 174 194 1 175 195 1 176 196 1 177 197 1 + 178 198 1 179 199 1 180 200 1 181 201 1 182 202 1 183 203 1 184 204 1 185 205 1 186 206 1 + 187 207 1 188 208 1 189 209 1 190 210 1 191 211 1 192 212 1 193 213 1 194 214 1 195 215 1 + 196 216 1 197 217 1 198 218 1 199 219 1 200 220 1 201 221 1 202 222 1 203 223 1 204 224 1 + 205 225 1 206 226 1 207 227 1 208 228 1 209 229 1 210 230 1 211 231 1 212 232 1 213 233 1 + 214 234 1 215 235 1 216 236 1 217 237 1 218 238 1 219 239 1 220 240 1 221 241 1 222 242 1 + 223 243 1 224 244 1 225 245 1 226 246 1 227 247 1 228 248 1 229 249 1 230 250 1 231 251 1 + 232 252 1 233 253 1 234 254 1 235 255 1 236 256 1 237 257 1 238 258 1 239 259 1 240 260 1 + 241 261 1 242 262 1 243 263 1 244 264 1 245 265 1 246 266 1 247 267 1 248 268 1 249 269 1 + 250 270 1 251 271 1 252 272 1 253 273 1 254 274 1 255 275 1 256 276 1 257 277 1 258 278 1 + 259 279 1 260 280 1 261 281 1 262 282 1 263 283 1 264 284 1 265 285 1 266 286 1 267 287 1 + 268 288 1 269 289 1 270 290 1 271 291 1 272 292 1 273 293 1 274 294 1 275 295 1 276 296 1 + 277 297 1 278 298 1 279 299 1 280 300 1 281 301 1 282 302 1 283 303 1; + setAttr ".ed[664:779]" 284 304 1 285 305 1 286 306 1 287 307 1 288 308 1 289 309 1 + 290 310 1 291 311 1 292 312 1 293 313 1 294 314 1 295 315 1 296 316 1 297 317 1 298 318 1 + 299 319 1 300 320 1 301 321 1 302 322 1 303 323 1 304 324 1 305 325 1 306 326 1 307 327 1 + 308 328 1 309 329 1 310 330 1 311 331 1 312 332 1 313 333 1 314 334 1 315 335 1 316 336 1 + 317 337 1 318 338 1 319 339 1 320 340 1 321 341 1 322 342 1 323 343 1 324 344 1 325 345 1 + 326 346 1 327 347 1 328 348 1 329 349 1 330 350 1 331 351 1 332 352 1 333 353 1 334 354 1 + 335 355 1 336 356 1 337 357 1 338 358 1 339 359 1 340 360 1 341 361 1 342 362 1 343 363 1 + 344 364 1 345 365 1 346 366 1 347 367 1 348 368 1 349 369 1 350 370 1 351 371 1 352 372 1 + 353 373 1 354 374 1 355 375 1 356 376 1 357 377 1 358 378 1 359 379 1 380 0 1 380 1 1 + 380 2 1 380 3 1 380 4 1 380 5 1 380 6 1 380 7 1 380 8 1 380 9 1 380 10 1 380 11 1 + 380 12 1 380 13 1 380 14 1 380 15 1 380 16 1 380 17 1 380 18 1 380 19 1 360 381 1 + 361 381 1 362 381 1 363 381 1 364 381 1 365 381 1 366 381 1 367 381 1 368 381 1 369 381 1 + 370 381 1 371 381 1 372 381 1 373 381 1 374 381 1 375 381 1 376 381 1 377 381 1 378 381 1 + 379 381 1; + setAttr -s 400 -ch 1560 ".fc[0:399]" -type "polyFaces" + f 4 0 381 -21 -381 + mu 0 4 0 1 22 21 + f 4 1 382 -22 -382 + mu 0 4 1 2 23 22 + f 4 2 383 -23 -383 + mu 0 4 2 3 24 23 + f 4 3 384 -24 -384 + mu 0 4 3 4 25 24 + f 4 4 385 -25 -385 + mu 0 4 4 5 26 25 + f 4 5 386 -26 -386 + mu 0 4 5 6 27 26 + f 4 6 387 -27 -387 + mu 0 4 6 7 28 27 + f 4 7 388 -28 -388 + mu 0 4 7 8 29 28 + f 4 8 389 -29 -389 + mu 0 4 8 9 30 29 + f 4 9 390 -30 -390 + mu 0 4 9 10 31 30 + f 4 10 391 -31 -391 + mu 0 4 10 11 32 31 + f 4 11 392 -32 -392 + mu 0 4 11 12 33 32 + f 4 12 393 -33 -393 + mu 0 4 12 13 34 33 + f 4 13 394 -34 -394 + mu 0 4 13 14 35 34 + f 4 14 395 -35 -395 + mu 0 4 14 15 36 35 + f 4 15 396 -36 -396 + mu 0 4 15 16 37 36 + f 4 16 397 -37 -397 + mu 0 4 16 17 38 37 + f 4 17 398 -38 -398 + mu 0 4 17 18 39 38 + f 4 18 399 -39 -399 + mu 0 4 18 19 40 39 + f 4 19 380 -40 -400 + mu 0 4 19 20 41 40 + f 4 20 401 -41 -401 + mu 0 4 21 22 43 42 + f 4 21 402 -42 -402 + mu 0 4 22 23 44 43 + f 4 22 403 -43 -403 + mu 0 4 23 24 45 44 + f 4 23 404 -44 -404 + mu 0 4 24 25 46 45 + f 4 24 405 -45 -405 + mu 0 4 25 26 47 46 + f 4 25 406 -46 -406 + mu 0 4 26 27 48 47 + f 4 26 407 -47 -407 + mu 0 4 27 28 49 48 + f 4 27 408 -48 -408 + mu 0 4 28 29 50 49 + f 4 28 409 -49 -409 + mu 0 4 29 30 51 50 + f 4 29 410 -50 -410 + mu 0 4 30 31 52 51 + f 4 30 411 -51 -411 + mu 0 4 31 32 53 52 + f 4 31 412 -52 -412 + mu 0 4 32 33 54 53 + f 4 32 413 -53 -413 + mu 0 4 33 34 55 54 + f 4 33 414 -54 -414 + mu 0 4 34 35 56 55 + f 4 34 415 -55 -415 + mu 0 4 35 36 57 56 + f 4 35 416 -56 -416 + mu 0 4 36 37 58 57 + f 4 36 417 -57 -417 + mu 0 4 37 38 59 58 + f 4 37 418 -58 -418 + mu 0 4 38 39 60 59 + f 4 38 419 -59 -419 + mu 0 4 39 40 61 60 + f 4 39 400 -60 -420 + mu 0 4 40 41 62 61 + f 4 40 421 -61 -421 + mu 0 4 42 43 64 63 + f 4 41 422 -62 -422 + mu 0 4 43 44 65 64 + f 4 42 423 -63 -423 + mu 0 4 44 45 66 65 + f 4 43 424 -64 -424 + mu 0 4 45 46 67 66 + f 4 44 425 -65 -425 + mu 0 4 46 47 68 67 + f 4 45 426 -66 -426 + mu 0 4 47 48 69 68 + f 4 46 427 -67 -427 + mu 0 4 48 49 70 69 + f 4 47 428 -68 -428 + mu 0 4 49 50 71 70 + f 4 48 429 -69 -429 + mu 0 4 50 51 72 71 + f 4 49 430 -70 -430 + mu 0 4 51 52 73 72 + f 4 50 431 -71 -431 + mu 0 4 52 53 74 73 + f 4 51 432 -72 -432 + mu 0 4 53 54 75 74 + f 4 52 433 -73 -433 + mu 0 4 54 55 76 75 + f 4 53 434 -74 -434 + mu 0 4 55 56 77 76 + f 4 54 435 -75 -435 + mu 0 4 56 57 78 77 + f 4 55 436 -76 -436 + mu 0 4 57 58 79 78 + f 4 56 437 -77 -437 + mu 0 4 58 59 80 79 + f 4 57 438 -78 -438 + mu 0 4 59 60 81 80 + f 4 58 439 -79 -439 + mu 0 4 60 61 82 81 + f 4 59 420 -80 -440 + mu 0 4 61 62 83 82 + f 4 60 441 -81 -441 + mu 0 4 63 64 85 84 + f 4 61 442 -82 -442 + mu 0 4 64 65 86 85 + f 4 62 443 -83 -443 + mu 0 4 65 66 87 86 + f 4 63 444 -84 -444 + mu 0 4 66 67 88 87 + f 4 64 445 -85 -445 + mu 0 4 67 68 89 88 + f 4 65 446 -86 -446 + mu 0 4 68 69 90 89 + f 4 66 447 -87 -447 + mu 0 4 69 70 91 90 + f 4 67 448 -88 -448 + mu 0 4 70 71 92 91 + f 4 68 449 -89 -449 + mu 0 4 71 72 93 92 + f 4 69 450 -90 -450 + mu 0 4 72 73 94 93 + f 4 70 451 -91 -451 + mu 0 4 73 74 95 94 + f 4 71 452 -92 -452 + mu 0 4 74 75 96 95 + f 4 72 453 -93 -453 + mu 0 4 75 76 97 96 + f 4 73 454 -94 -454 + mu 0 4 76 77 98 97 + f 4 74 455 -95 -455 + mu 0 4 77 78 99 98 + f 4 75 456 -96 -456 + mu 0 4 78 79 100 99 + f 4 76 457 -97 -457 + mu 0 4 79 80 101 100 + f 4 77 458 -98 -458 + mu 0 4 80 81 102 101 + f 4 78 459 -99 -459 + mu 0 4 81 82 103 102 + f 4 79 440 -100 -460 + mu 0 4 82 83 104 103 + f 4 80 461 -101 -461 + mu 0 4 84 85 106 105 + f 4 81 462 -102 -462 + mu 0 4 85 86 107 106 + f 4 82 463 -103 -463 + mu 0 4 86 87 108 107 + f 4 83 464 -104 -464 + mu 0 4 87 88 109 108 + f 4 84 465 -105 -465 + mu 0 4 88 89 110 109 + f 4 85 466 -106 -466 + mu 0 4 89 90 111 110 + f 4 86 467 -107 -467 + mu 0 4 90 91 112 111 + f 4 87 468 -108 -468 + mu 0 4 91 92 113 112 + f 4 88 469 -109 -469 + mu 0 4 92 93 114 113 + f 4 89 470 -110 -470 + mu 0 4 93 94 115 114 + f 4 90 471 -111 -471 + mu 0 4 94 95 116 115 + f 4 91 472 -112 -472 + mu 0 4 95 96 117 116 + f 4 92 473 -113 -473 + mu 0 4 96 97 118 117 + f 4 93 474 -114 -474 + mu 0 4 97 98 119 118 + f 4 94 475 -115 -475 + mu 0 4 98 99 120 119 + f 4 95 476 -116 -476 + mu 0 4 99 100 121 120 + f 4 96 477 -117 -477 + mu 0 4 100 101 122 121 + f 4 97 478 -118 -478 + mu 0 4 101 102 123 122 + f 4 98 479 -119 -479 + mu 0 4 102 103 124 123 + f 4 99 460 -120 -480 + mu 0 4 103 104 125 124 + f 4 100 481 -121 -481 + mu 0 4 105 106 127 126 + f 4 101 482 -122 -482 + mu 0 4 106 107 128 127 + f 4 102 483 -123 -483 + mu 0 4 107 108 129 128 + f 4 103 484 -124 -484 + mu 0 4 108 109 130 129 + f 4 104 485 -125 -485 + mu 0 4 109 110 131 130 + f 4 105 486 -126 -486 + mu 0 4 110 111 132 131 + f 4 106 487 -127 -487 + mu 0 4 111 112 133 132 + f 4 107 488 -128 -488 + mu 0 4 112 113 134 133 + f 4 108 489 -129 -489 + mu 0 4 113 114 135 134 + f 4 109 490 -130 -490 + mu 0 4 114 115 136 135 + f 4 110 491 -131 -491 + mu 0 4 115 116 137 136 + f 4 111 492 -132 -492 + mu 0 4 116 117 138 137 + f 4 112 493 -133 -493 + mu 0 4 117 118 139 138 + f 4 113 494 -134 -494 + mu 0 4 118 119 140 139 + f 4 114 495 -135 -495 + mu 0 4 119 120 141 140 + f 4 115 496 -136 -496 + mu 0 4 120 121 142 141 + f 4 116 497 -137 -497 + mu 0 4 121 122 143 142 + f 4 117 498 -138 -498 + mu 0 4 122 123 144 143 + f 4 118 499 -139 -499 + mu 0 4 123 124 145 144 + f 4 119 480 -140 -500 + mu 0 4 124 125 146 145 + f 4 120 501 -141 -501 + mu 0 4 126 127 148 147 + f 4 121 502 -142 -502 + mu 0 4 127 128 149 148 + f 4 122 503 -143 -503 + mu 0 4 128 129 150 149 + f 4 123 504 -144 -504 + mu 0 4 129 130 151 150 + f 4 124 505 -145 -505 + mu 0 4 130 131 152 151 + f 4 125 506 -146 -506 + mu 0 4 131 132 153 152 + f 4 126 507 -147 -507 + mu 0 4 132 133 154 153 + f 4 127 508 -148 -508 + mu 0 4 133 134 155 154 + f 4 128 509 -149 -509 + mu 0 4 134 135 156 155 + f 4 129 510 -150 -510 + mu 0 4 135 136 157 156 + f 4 130 511 -151 -511 + mu 0 4 136 137 158 157 + f 4 131 512 -152 -512 + mu 0 4 137 138 159 158 + f 4 132 513 -153 -513 + mu 0 4 138 139 160 159 + f 4 133 514 -154 -514 + mu 0 4 139 140 161 160 + f 4 134 515 -155 -515 + mu 0 4 140 141 162 161 + f 4 135 516 -156 -516 + mu 0 4 141 142 163 162 + f 4 136 517 -157 -517 + mu 0 4 142 143 164 163 + f 4 137 518 -158 -518 + mu 0 4 143 144 165 164 + f 4 138 519 -159 -519 + mu 0 4 144 145 166 165 + f 4 139 500 -160 -520 + mu 0 4 145 146 167 166 + f 4 140 521 -161 -521 + mu 0 4 147 148 169 168 + f 4 141 522 -162 -522 + mu 0 4 148 149 170 169 + f 4 142 523 -163 -523 + mu 0 4 149 150 171 170 + f 4 143 524 -164 -524 + mu 0 4 150 151 172 171 + f 4 144 525 -165 -525 + mu 0 4 151 152 173 172 + f 4 145 526 -166 -526 + mu 0 4 152 153 174 173 + f 4 146 527 -167 -527 + mu 0 4 153 154 175 174 + f 4 147 528 -168 -528 + mu 0 4 154 155 176 175 + f 4 148 529 -169 -529 + mu 0 4 155 156 177 176 + f 4 149 530 -170 -530 + mu 0 4 156 157 178 177 + f 4 150 531 -171 -531 + mu 0 4 157 158 179 178 + f 4 151 532 -172 -532 + mu 0 4 158 159 180 179 + f 4 152 533 -173 -533 + mu 0 4 159 160 181 180 + f 4 153 534 -174 -534 + mu 0 4 160 161 182 181 + f 4 154 535 -175 -535 + mu 0 4 161 162 183 182 + f 4 155 536 -176 -536 + mu 0 4 162 163 184 183 + f 4 156 537 -177 -537 + mu 0 4 163 164 185 184 + f 4 157 538 -178 -538 + mu 0 4 164 165 186 185 + f 4 158 539 -179 -539 + mu 0 4 165 166 187 186 + f 4 159 520 -180 -540 + mu 0 4 166 167 188 187 + f 4 160 541 -181 -541 + mu 0 4 168 169 190 189 + f 4 161 542 -182 -542 + mu 0 4 169 170 191 190 + f 4 162 543 -183 -543 + mu 0 4 170 171 192 191 + f 4 163 544 -184 -544 + mu 0 4 171 172 193 192 + f 4 164 545 -185 -545 + mu 0 4 172 173 194 193 + f 4 165 546 -186 -546 + mu 0 4 173 174 195 194 + f 4 166 547 -187 -547 + mu 0 4 174 175 196 195 + f 4 167 548 -188 -548 + mu 0 4 175 176 197 196 + f 4 168 549 -189 -549 + mu 0 4 176 177 198 197 + f 4 169 550 -190 -550 + mu 0 4 177 178 199 198 + f 4 170 551 -191 -551 + mu 0 4 178 179 200 199 + f 4 171 552 -192 -552 + mu 0 4 179 180 201 200 + f 4 172 553 -193 -553 + mu 0 4 180 181 202 201 + f 4 173 554 -194 -554 + mu 0 4 181 182 203 202 + f 4 174 555 -195 -555 + mu 0 4 182 183 204 203 + f 4 175 556 -196 -556 + mu 0 4 183 184 205 204 + f 4 176 557 -197 -557 + mu 0 4 184 185 206 205 + f 4 177 558 -198 -558 + mu 0 4 185 186 207 206 + f 4 178 559 -199 -559 + mu 0 4 186 187 208 207 + f 4 179 540 -200 -560 + mu 0 4 187 188 209 208 + f 4 180 561 -201 -561 + mu 0 4 189 190 211 210 + f 4 181 562 -202 -562 + mu 0 4 190 191 212 211 + f 4 182 563 -203 -563 + mu 0 4 191 192 213 212 + f 4 183 564 -204 -564 + mu 0 4 192 193 214 213 + f 4 184 565 -205 -565 + mu 0 4 193 194 215 214 + f 4 185 566 -206 -566 + mu 0 4 194 195 216 215 + f 4 186 567 -207 -567 + mu 0 4 195 196 217 216 + f 4 187 568 -208 -568 + mu 0 4 196 197 218 217 + f 4 188 569 -209 -569 + mu 0 4 197 198 219 218 + f 4 189 570 -210 -570 + mu 0 4 198 199 220 219 + f 4 190 571 -211 -571 + mu 0 4 199 200 221 220 + f 4 191 572 -212 -572 + mu 0 4 200 201 222 221 + f 4 192 573 -213 -573 + mu 0 4 201 202 223 222 + f 4 193 574 -214 -574 + mu 0 4 202 203 224 223 + f 4 194 575 -215 -575 + mu 0 4 203 204 225 224 + f 4 195 576 -216 -576 + mu 0 4 204 205 226 225 + f 4 196 577 -217 -577 + mu 0 4 205 206 227 226 + f 4 197 578 -218 -578 + mu 0 4 206 207 228 227 + f 4 198 579 -219 -579 + mu 0 4 207 208 229 228 + f 4 199 560 -220 -580 + mu 0 4 208 209 230 229 + f 4 200 581 -221 -581 + mu 0 4 210 211 232 231 + f 4 201 582 -222 -582 + mu 0 4 211 212 233 232 + f 4 202 583 -223 -583 + mu 0 4 212 213 234 233 + f 4 203 584 -224 -584 + mu 0 4 213 214 235 234 + f 4 204 585 -225 -585 + mu 0 4 214 215 236 235 + f 4 205 586 -226 -586 + mu 0 4 215 216 237 236 + f 4 206 587 -227 -587 + mu 0 4 216 217 238 237 + f 4 207 588 -228 -588 + mu 0 4 217 218 239 238 + f 4 208 589 -229 -589 + mu 0 4 218 219 240 239 + f 4 209 590 -230 -590 + mu 0 4 219 220 241 240 + f 4 210 591 -231 -591 + mu 0 4 220 221 242 241 + f 4 211 592 -232 -592 + mu 0 4 221 222 243 242 + f 4 212 593 -233 -593 + mu 0 4 222 223 244 243 + f 4 213 594 -234 -594 + mu 0 4 223 224 245 244 + f 4 214 595 -235 -595 + mu 0 4 224 225 246 245 + f 4 215 596 -236 -596 + mu 0 4 225 226 247 246 + f 4 216 597 -237 -597 + mu 0 4 226 227 248 247 + f 4 217 598 -238 -598 + mu 0 4 227 228 249 248 + f 4 218 599 -239 -599 + mu 0 4 228 229 250 249 + f 4 219 580 -240 -600 + mu 0 4 229 230 251 250 + f 4 220 601 -241 -601 + mu 0 4 231 232 253 252 + f 4 221 602 -242 -602 + mu 0 4 232 233 254 253 + f 4 222 603 -243 -603 + mu 0 4 233 234 255 254 + f 4 223 604 -244 -604 + mu 0 4 234 235 256 255 + f 4 224 605 -245 -605 + mu 0 4 235 236 257 256 + f 4 225 606 -246 -606 + mu 0 4 236 237 258 257 + f 4 226 607 -247 -607 + mu 0 4 237 238 259 258 + f 4 227 608 -248 -608 + mu 0 4 238 239 260 259 + f 4 228 609 -249 -609 + mu 0 4 239 240 261 260 + f 4 229 610 -250 -610 + mu 0 4 240 241 262 261 + f 4 230 611 -251 -611 + mu 0 4 241 242 263 262 + f 4 231 612 -252 -612 + mu 0 4 242 243 264 263 + f 4 232 613 -253 -613 + mu 0 4 243 244 265 264 + f 4 233 614 -254 -614 + mu 0 4 244 245 266 265 + f 4 234 615 -255 -615 + mu 0 4 245 246 267 266 + f 4 235 616 -256 -616 + mu 0 4 246 247 268 267 + f 4 236 617 -257 -617 + mu 0 4 247 248 269 268 + f 4 237 618 -258 -618 + mu 0 4 248 249 270 269 + f 4 238 619 -259 -619 + mu 0 4 249 250 271 270 + f 4 239 600 -260 -620 + mu 0 4 250 251 272 271 + f 4 240 621 -261 -621 + mu 0 4 252 253 274 273 + f 4 241 622 -262 -622 + mu 0 4 253 254 275 274 + f 4 242 623 -263 -623 + mu 0 4 254 255 276 275 + f 4 243 624 -264 -624 + mu 0 4 255 256 277 276 + f 4 244 625 -265 -625 + mu 0 4 256 257 278 277 + f 4 245 626 -266 -626 + mu 0 4 257 258 279 278 + f 4 246 627 -267 -627 + mu 0 4 258 259 280 279 + f 4 247 628 -268 -628 + mu 0 4 259 260 281 280 + f 4 248 629 -269 -629 + mu 0 4 260 261 282 281 + f 4 249 630 -270 -630 + mu 0 4 261 262 283 282 + f 4 250 631 -271 -631 + mu 0 4 262 263 284 283 + f 4 251 632 -272 -632 + mu 0 4 263 264 285 284 + f 4 252 633 -273 -633 + mu 0 4 264 265 286 285 + f 4 253 634 -274 -634 + mu 0 4 265 266 287 286 + f 4 254 635 -275 -635 + mu 0 4 266 267 288 287 + f 4 255 636 -276 -636 + mu 0 4 267 268 289 288 + f 4 256 637 -277 -637 + mu 0 4 268 269 290 289 + f 4 257 638 -278 -638 + mu 0 4 269 270 291 290 + f 4 258 639 -279 -639 + mu 0 4 270 271 292 291 + f 4 259 620 -280 -640 + mu 0 4 271 272 293 292 + f 4 260 641 -281 -641 + mu 0 4 273 274 295 294 + f 4 261 642 -282 -642 + mu 0 4 274 275 296 295 + f 4 262 643 -283 -643 + mu 0 4 275 276 297 296 + f 4 263 644 -284 -644 + mu 0 4 276 277 298 297 + f 4 264 645 -285 -645 + mu 0 4 277 278 299 298 + f 4 265 646 -286 -646 + mu 0 4 278 279 300 299 + f 4 266 647 -287 -647 + mu 0 4 279 280 301 300 + f 4 267 648 -288 -648 + mu 0 4 280 281 302 301 + f 4 268 649 -289 -649 + mu 0 4 281 282 303 302 + f 4 269 650 -290 -650 + mu 0 4 282 283 304 303 + f 4 270 651 -291 -651 + mu 0 4 283 284 305 304 + f 4 271 652 -292 -652 + mu 0 4 284 285 306 305 + f 4 272 653 -293 -653 + mu 0 4 285 286 307 306 + f 4 273 654 -294 -654 + mu 0 4 286 287 308 307 + f 4 274 655 -295 -655 + mu 0 4 287 288 309 308 + f 4 275 656 -296 -656 + mu 0 4 288 289 310 309 + f 4 276 657 -297 -657 + mu 0 4 289 290 311 310 + f 4 277 658 -298 -658 + mu 0 4 290 291 312 311 + f 4 278 659 -299 -659 + mu 0 4 291 292 313 312 + f 4 279 640 -300 -660 + mu 0 4 292 293 314 313 + f 4 280 661 -301 -661 + mu 0 4 294 295 316 315 + f 4 281 662 -302 -662 + mu 0 4 295 296 317 316 + f 4 282 663 -303 -663 + mu 0 4 296 297 318 317 + f 4 283 664 -304 -664 + mu 0 4 297 298 319 318 + f 4 284 665 -305 -665 + mu 0 4 298 299 320 319 + f 4 285 666 -306 -666 + mu 0 4 299 300 321 320 + f 4 286 667 -307 -667 + mu 0 4 300 301 322 321 + f 4 287 668 -308 -668 + mu 0 4 301 302 323 322 + f 4 288 669 -309 -669 + mu 0 4 302 303 324 323 + f 4 289 670 -310 -670 + mu 0 4 303 304 325 324 + f 4 290 671 -311 -671 + mu 0 4 304 305 326 325 + f 4 291 672 -312 -672 + mu 0 4 305 306 327 326 + f 4 292 673 -313 -673 + mu 0 4 306 307 328 327 + f 4 293 674 -314 -674 + mu 0 4 307 308 329 328 + f 4 294 675 -315 -675 + mu 0 4 308 309 330 329 + f 4 295 676 -316 -676 + mu 0 4 309 310 331 330 + f 4 296 677 -317 -677 + mu 0 4 310 311 332 331 + f 4 297 678 -318 -678 + mu 0 4 311 312 333 332 + f 4 298 679 -319 -679 + mu 0 4 312 313 334 333 + f 4 299 660 -320 -680 + mu 0 4 313 314 335 334 + f 4 300 681 -321 -681 + mu 0 4 315 316 337 336 + f 4 301 682 -322 -682 + mu 0 4 316 317 338 337 + f 4 302 683 -323 -683 + mu 0 4 317 318 339 338 + f 4 303 684 -324 -684 + mu 0 4 318 319 340 339 + f 4 304 685 -325 -685 + mu 0 4 319 320 341 340 + f 4 305 686 -326 -686 + mu 0 4 320 321 342 341 + f 4 306 687 -327 -687 + mu 0 4 321 322 343 342 + f 4 307 688 -328 -688 + mu 0 4 322 323 344 343 + f 4 308 689 -329 -689 + mu 0 4 323 324 345 344 + f 4 309 690 -330 -690 + mu 0 4 324 325 346 345 + f 4 310 691 -331 -691 + mu 0 4 325 326 347 346 + f 4 311 692 -332 -692 + mu 0 4 326 327 348 347 + f 4 312 693 -333 -693 + mu 0 4 327 328 349 348 + f 4 313 694 -334 -694 + mu 0 4 328 329 350 349 + f 4 314 695 -335 -695 + mu 0 4 329 330 351 350 + f 4 315 696 -336 -696 + mu 0 4 330 331 352 351 + f 4 316 697 -337 -697 + mu 0 4 331 332 353 352 + f 4 317 698 -338 -698 + mu 0 4 332 333 354 353 + f 4 318 699 -339 -699 + mu 0 4 333 334 355 354 + f 4 319 680 -340 -700 + mu 0 4 334 335 356 355 + f 4 320 701 -341 -701 + mu 0 4 336 337 358 357 + f 4 321 702 -342 -702 + mu 0 4 337 338 359 358 + f 4 322 703 -343 -703 + mu 0 4 338 339 360 359 + f 4 323 704 -344 -704 + mu 0 4 339 340 361 360 + f 4 324 705 -345 -705 + mu 0 4 340 341 362 361 + f 4 325 706 -346 -706 + mu 0 4 341 342 363 362 + f 4 326 707 -347 -707 + mu 0 4 342 343 364 363 + f 4 327 708 -348 -708 + mu 0 4 343 344 365 364 + f 4 328 709 -349 -709 + mu 0 4 344 345 366 365 + f 4 329 710 -350 -710 + mu 0 4 345 346 367 366 + f 4 330 711 -351 -711 + mu 0 4 346 347 368 367 + f 4 331 712 -352 -712 + mu 0 4 347 348 369 368 + f 4 332 713 -353 -713 + mu 0 4 348 349 370 369 + f 4 333 714 -354 -714 + mu 0 4 349 350 371 370 + f 4 334 715 -355 -715 + mu 0 4 350 351 372 371 + f 4 335 716 -356 -716 + mu 0 4 351 352 373 372 + f 4 336 717 -357 -717 + mu 0 4 352 353 374 373 + f 4 337 718 -358 -718 + mu 0 4 353 354 375 374 + f 4 338 719 -359 -719 + mu 0 4 354 355 376 375 + f 4 339 700 -360 -720 + mu 0 4 355 356 377 376 + f 4 340 721 -361 -721 + mu 0 4 357 358 379 378 + f 4 341 722 -362 -722 + mu 0 4 358 359 380 379 + f 4 342 723 -363 -723 + mu 0 4 359 360 381 380 + f 4 343 724 -364 -724 + mu 0 4 360 361 382 381 + f 4 344 725 -365 -725 + mu 0 4 361 362 383 382 + f 4 345 726 -366 -726 + mu 0 4 362 363 384 383 + f 4 346 727 -367 -727 + mu 0 4 363 364 385 384 + f 4 347 728 -368 -728 + mu 0 4 364 365 386 385 + f 4 348 729 -369 -729 + mu 0 4 365 366 387 386 + f 4 349 730 -370 -730 + mu 0 4 366 367 388 387 + f 4 350 731 -371 -731 + mu 0 4 367 368 389 388 + f 4 351 732 -372 -732 + mu 0 4 368 369 390 389 + f 4 352 733 -373 -733 + mu 0 4 369 370 391 390 + f 4 353 734 -374 -734 + mu 0 4 370 371 392 391 + f 4 354 735 -375 -735 + mu 0 4 371 372 393 392 + f 4 355 736 -376 -736 + mu 0 4 372 373 394 393 + f 4 356 737 -377 -737 + mu 0 4 373 374 395 394 + f 4 357 738 -378 -738 + mu 0 4 374 375 396 395 + f 4 358 739 -379 -739 + mu 0 4 375 376 397 396 + f 4 359 720 -380 -740 + mu 0 4 376 377 398 397 + f 3 -1 -741 741 + mu 0 3 1 0 399 + f 3 -2 -742 742 + mu 0 3 2 1 400 + f 3 -3 -743 743 + mu 0 3 3 2 401 + f 3 -4 -744 744 + mu 0 3 4 3 402 + f 3 -5 -745 745 + mu 0 3 5 4 403 + f 3 -6 -746 746 + mu 0 3 6 5 404 + f 3 -7 -747 747 + mu 0 3 7 6 405 + f 3 -8 -748 748 + mu 0 3 8 7 406 + f 3 -9 -749 749 + mu 0 3 9 8 407 + f 3 -10 -750 750 + mu 0 3 10 9 408 + f 3 -11 -751 751 + mu 0 3 11 10 409 + f 3 -12 -752 752 + mu 0 3 12 11 410 + f 3 -13 -753 753 + mu 0 3 13 12 411 + f 3 -14 -754 754 + mu 0 3 14 13 412 + f 3 -15 -755 755 + mu 0 3 15 14 413 + f 3 -16 -756 756 + mu 0 3 16 15 414 + f 3 -17 -757 757 + mu 0 3 17 16 415 + f 3 -18 -758 758 + mu 0 3 18 17 416 + f 3 -19 -759 759 + mu 0 3 19 18 417 + f 3 -20 -760 740 + mu 0 3 20 19 418 + f 3 360 761 -761 + mu 0 3 378 379 419 + f 3 361 762 -762 + mu 0 3 379 380 420 + f 3 362 763 -763 + mu 0 3 380 381 421 + f 3 363 764 -764 + mu 0 3 381 382 422 + f 3 364 765 -765 + mu 0 3 382 383 423 + f 3 365 766 -766 + mu 0 3 383 384 424 + f 3 366 767 -767 + mu 0 3 384 385 425 + f 3 367 768 -768 + mu 0 3 385 386 426 + f 3 368 769 -769 + mu 0 3 386 387 427 + f 3 369 770 -770 + mu 0 3 387 388 428 + f 3 370 771 -771 + mu 0 3 388 389 429 + f 3 371 772 -772 + mu 0 3 389 390 430 + f 3 372 773 -773 + mu 0 3 390 391 431 + f 3 373 774 -774 + mu 0 3 391 392 432 + f 3 374 775 -775 + mu 0 3 392 393 433 + f 3 375 776 -776 + mu 0 3 393 394 434 + f 3 376 777 -777 + mu 0 3 394 395 435 + f 3 377 778 -778 + mu 0 3 395 396 436 + f 3 378 779 -779 + mu 0 3 396 397 437 + f 3 379 760 -780 + mu 0 3 397 398 438; + setAttr ".cd" -type "dataPolyComponent" Index_Data Edge 0 ; + setAttr ".cvd" -type "dataPolyComponent" Index_Data Vertex 0 ; + setAttr ".pd[0]" -type "dataPolyComponent" Index_Data UV 0 ; + setAttr ".hfd" -type "dataPolyComponent" Index_Data Face 0 ; + setAttr ".dr" 1; + setAttr ".ai_translator" -type "string" "polymesh"; + setAttr ".cbId" -type "string" "60df31e2be2b48bd3695c056:6c77a15a98a9"; +select -ne :time1; + setAttr ".o" 1001; + setAttr ".unw" 1001; +select -ne :hardwareRenderingGlobals; + setAttr ".otfna" -type "stringArray" 22 "NURBS Curves" "NURBS Surfaces" "Polygons" "Subdiv Surface" "Particles" "Particle Instance" "Fluids" "Strokes" "Image Planes" "UI" "Lights" "Cameras" "Locators" "Joints" "IK Handles" "Deformers" "Motion Trails" "Components" "Hair Systems" "Follicles" "Misc. UI" "Ornaments" ; + setAttr ".otfva" -type "Int32Array" 22 0 1 1 1 1 1 + 1 1 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 ; + setAttr ".fprt" yes; +select -ne :renderPartition; + setAttr -s 2 ".st"; +select -ne :renderGlobalsList1; +select -ne :defaultShaderList1; + setAttr -s 5 ".s"; +select -ne :postProcessList1; + setAttr -s 2 ".p"; +select -ne :defaultRenderingList1; + setAttr -s 2 ".r"; +select -ne :lightList1; +select -ne :initialShadingGroup; + setAttr -s 2 ".dsm"; + setAttr ".ro" yes; +select -ne :initialParticleSE; + setAttr ".ro" yes; +select -ne :defaultRenderGlobals; + addAttr -ci true -h true -sn "dss" -ln "defaultSurfaceShader" -dt "string"; + setAttr ".ren" -type "string" "arnold"; + setAttr ".outf" 51; + setAttr ".imfkey" -type "string" "exr"; + setAttr ".an" yes; + setAttr ".fs" 1001; + setAttr ".ef" 1001; + setAttr ".oft" -type "string" ""; + setAttr ".pff" yes; + setAttr ".ifp" -type "string" "//_"; + setAttr ".rv" -type "string" ""; + setAttr ".pram" -type "string" ""; + setAttr ".poam" -type "string" ""; + setAttr ".prlm" -type "string" ""; + setAttr ".polm" -type "string" ""; + setAttr ".prm" -type "string" ""; + setAttr ".pom" -type "string" ""; + setAttr ".dss" -type "string" "lambert1"; +select -ne :defaultResolution; + setAttr ".w" 1920; + setAttr ".h" 1080; + setAttr ".pa" 1; + setAttr ".dar" 1.7777777910232544; +select -ne :defaultLightSet; +select -ne :hardwareRenderGlobals; + setAttr ".ctrs" 256; + setAttr ".btrs" 512; +connectAttr "pSphere1_GEOShape1.iog" ":initialShadingGroup.dsm" -na; +// End of modelMain.ma diff --git a/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/render/renderTest_taskMain_beauty/v001/test_project_test_asset_renderTest_taskMain_beauty_v001.exr b/tests/integration/hosts/maya/test_deadline_publish_in_maya/expected/test_project/test_asset/publish/render/renderTest_taskMain_beauty/v001/test_project_test_asset_renderTest_taskMain_beauty_v001.exr new file mode 100644 index 0000000000000000000000000000000000000000..b137a46dfd7d763017b172f9b8df014f7c82f281 GIT binary patch literal 3608096 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 ?ASAMn5K#SWdl_B$>_K>>jd%zl?2<+o_1+f zpN7g#@Xo0wOH-Ei#RQMbrsUuP5o#p<@-Q`*Kwf2#@=6;eD2dm@$)T%hC-!Ak5tW8j(cAQwGd8iz$ddrh=-8;mRcMY6xsl?lEbsAO)TjF8!jID8M{ zoq5rrxI|IH{@tLShH(pNq=L1I5%~-BgATo#N@avAEa(0Xf7h4h>AplO|DXuO4+dKV zmkL22MWzV0u0E)7A5rb6N^QjJkImdM%g@8h5K~TQ8rw{lj33)-BQ+I}{J9UI@bipv zWExBVz15+8I7&pYulbVfinJGHBP48U*AH(y>jN)ZU?z;`mEtItOYXzLH(U`R0(B8)0jMsfJp7KmD-c6yG*Q+mFY5A z`@E3ea)h&st|@K>^%6lPi>!+9%|)C_fovza)6e?`BD0^;lP$&;(I%RCN0~$$rFtFg zW|r9qK0V8gygzc+W9C$ADoZ|OBdnUljKu6<4AUmME%WKOS=xhP(_VnS^G z=*^%*tirN%jc6zQHi5$Lw*NfwVZ^W0UEkmC?!P0V5N8M9)SYT<(xmwd?w@r}+=+u7 zERgqBuR;ot8n6_$Bo>Qg_^Qz+y{{S^Vxu?&Xnq7MjuI5UjD&>pK7I1zLYW;#`62xP zdu@ef#4Ppawh>*a9IwQ}cGt|+UV%8@Z!BI|37+12NrBA-p#jP%jEb_W7Z3H`i8h4S zohXpNvL!XY3b)5wFIz8QvqEosljE$c-3qsyU8;9)EOGB^U)g`?oQ_$PH)A!_=v4WE zpBS3*9*q!Ee{Pk~$Mb8|A0=;A_ajeFZk8dFvuJ_t8L!Y(z0#qY@W!LwV|+Y8)6-Bz&k^;oNdvDQ|v?bv8K!7E1MM$SglD|K*rxCr`GP+&23~WhkDU zQp9Su>&&`QoOBI-0^7x&Et(o9^_0#xP$KXxg zbjR3tD4PR++AAITN^o8JY+B1{hPRr8946c-vaH(_RIkxT2F2V{Eks^{5u+rRl#|q@ zI8Fo_OrqTr`nu9|h`;&U~L%oOxmwx`5F_!83Pwfj9KCOXo{f2k|GfNwiXT z2gE3j`HL4PW>z_%@i`b{j?6X6yZih9pq-@3vQ|C&d8F`U?1MEm zX5+5dXNY9_N}4`W%vU09U%yMgZ^iQs1REWKFq4!+jZK+Oj*rs;RWy1uchVkZ4;p<; zqB44LzhDJNZYHEoQf-JoG}d8>EOFh}RqNyCJy(n*t9HRFYr#R3jjKo>?(WaYkN~Bc z%O}DE{mkw`)%qdMQ?$3X6FisBw5v%v*U4_JL?}qALOt&I9O=}4dd9W=(a`WsC&o+j zv}Msee4kHR4D-)^Gv>A^X|3<5y;m6$+lH)cK2bMu$cR5ZKX#OUHdt!LxR-S3(o~(a zE?N6Io-`N2F-fOo|9}9Y0=h=929@{JD!e+svyvj$OSsFPD(@Drn0ZO3LoTeSrYW1; zcXokG3cuWW!@Mr;vV_zYB$;hCAZ1X^Nqm>D3GLPVfsE=&VotJ*{W}&m)v`)_Zh_qi zJ7QlctZ%Du{*>?o_aW6DZAhByri3l0f<(rYcTo_AQlzI2LA@Wd$wh+kFOk((rVOzE)|!@PO5ay-u+%7ic82q6D;B)o@xGKkToMG|5B5%Cd_z zzWvFCS_wPbiaY1rES274ldfBPw8$T>{_eS3yv9djBclY<&>rDvy=TE?O)BH2tk9U! zt|^?8Y$Ik(%DKDS`jVRo-4(C)nx`_egXV3LSBMTTfB)7lO>=+bL6~yt5w$#U!GHf$ zZ|l2fm1~*Q1`+q=_KS6QsR8Gu!*UsCyJOt+gp39}+b~DtOIX;Ym|tOoA@*+bfofcX zW}xrfU6H{zLu9COks4zPwH={4)dIXEdds(!jXNO;NaK_z*}CgYwyztW>E(|Kel|Wq zxwl;}jx`%)d&ReZ%l&<+jb~t#9O?rYj?+i&-#90G?K6&wT8vqlGIfTn@kQKnzK3@A zyT7Ycepb~g^2HtCz5fft0`~6g;!L|Y%1(a6WFjSCBJ$7;XMAsPIFc)mw0=H{qildI zH&1^(A=@F#AaDv|N@f?UWy3g8kNHIX>gVoKlG#))TbH2n(04;)eDfZzb%F?|E!;-M zX(~)ws9NC{`M{0(6Gw&b1xasx!|J9e{C90KA8ats)+oiAwDK!go0E71%hliNgq0mK z?aL`2#Zf(EqMCYd$>V96KB?qvnUbFGf?q$^sZ;)x+lgq%5S1@@4q;(}zMF@KF|5A) zPV!?30hl@G;N`GiO!KB+xK=sG=Cd%~^Yta)ZSrZ6zU7t-7?jd9)t^L{sY7t{?)}3J z(j0}?TipT(KGrE+v~CezZ=>BbD!nt4{GW%SqeG20R{FTvyEETu7c6W>mX>Hderk}f z{3X@I^X#K^3u~B<TfYlb6*$XneyursPl|=G?X^uiK9XQYiAsh+ zhCy_#$0p1#fc$HZ#P~txr8`Wiq-@;A8R~U$6 zS7JRO4>Z6YR#N|9l`a|aUAJk^ojT*}TzX26X6;w&ET;3vq+Shjjd#KWY_$0hx$U98RkF~(WYE-ps}|;h!$rS^XS-lT zqp?$|aAuu|5xR9b?DNIE!--dAN=K&aQ=F>SmEld~968jCDp?wl%VY@K}p zIl-hcRI|eJ5vz9#&(L`M8NKz{8%C*X|96_QvII0$M27X z4|BgO82XX^YUkA|4rpK+8)l-IMqYwUux=*kDrJ}!F|mj&jC+5Uio?DYo`hfbqG!VB zK^F(*)j4VlP_0kAz0-6>x@_OBypU%UOMZ^( zFFravy8nW8)8Vt=xpjlQF~xV+uiKj*Fx}M=nzU!{{q)tM`MStpcWq#o_qOSW^0SuE zi4-rXhxPMyisNil3xfQbIYS&D{WxE)b9)|KW=FcoyZBBj!oKCUci1aW#sS0!FqqWK zm+>2srIoLIG_2C1G1A|Omv`}+90pljsrlC%e12X*btzZAIoyFp&e{Y+8Tr6ddw-Rc zWsxrBbv(u)@w<|{sJ!#OMP7H$5`15tw$mz{@J#h@;^Z0_|1vsJT~eG6c*J~U8~2&| z^^D#Ux%ThCpfK52g!E`{$q664wHQ_ot<7uc(tTMAQ~D|?vVM1XNa2edhXmi|N{qWI z%fhZ^!TLR2>X4>io13e1w0F0TPj0zEs}#dABi*=F9)A;obB?O>eNA}fOO8uM*Rxe8 zJj`~^FzB>)r|0W)3Dpyrg*B_yL6IySOY7ECvln$bN+Y@nO}y*BmIdc%+|Jp1_ar1f zzVb(bVvJoW zy~wQgIqvK4W0XAyVyP-VtYuSRy_Mi{Ug6r3{N_pTO<+}OogM*9lZ))uE$lCoWycq$-m4k zl0Ssy+t>x}QhwIJSN4IQSLf(WsU#Xu@_|Ja>LQ!sMr@PWAO+-hKjeJP{pUxdriXoY z{hOo4uw)|_@+9kWjKDsTi=Qh*iUPYAZ(Vph{mEsr(GI#PiJ|8@g2yj?w@>JFVsMKE z#ot0uRv<~?f>%!C7!6*(Cde^3@Aa3eoYsXRpZbvG7jo)`D7blD5TR;1)3%Eq!E*JZ zy`wAH2FB?kZ+%ivcxPZmV-)GnEv8aV;*g`BYHv?0(IhXVU4Zf!*3Vm}A7!VOJGgqq z@|n}8gFi^W=J83h4b6AwguYupG~&%MD(dg-~!>)D@V+FUB$YWRqf>_UCgBe%yNpio9qEHid~NtSCNf z9}L^iFMe&fq5pOb>}~Si^axeY4vG-15FCno8VNZSFUOlOvf-aq>+gZ{1`y!qdzi-u;d9auZS| z8dVkP>4k)*slSJ*T10B9$`n#l6SA=LF1^)AK)NDahgKp{G}|>iz-N-h_{|7iI8?j9 zC2%j^^pomG=`YFJ#+5yEkkyhM|J+QH)1Tu_vUC&l(JS`KpGgN7!d4R583^!ZZG*Ni zlaU7y1%iocOT^F4)8Do1iFg&gd7fdfR*6nwq+P(KD6Pk?yrVvP#rC@EyicT;e}Ujq zf&_-4552RZ9*NwA4#gg9bnZZ98$(k6%sH-{{Xs#tMqFfB8>b@5@kK@$VhbY=XA!$6pbcV2bDnrOXRg7p_`b+xMWnYs z+;3NTaB`Hgd>}GQGq~d1Y#E0=%-dY`bGq$on&uzSAXhG0rkH9qNBu=ssAG)QB5miP z=oc(*7&!s$F!NNXDaByYGW~J~r_aw#(yMOE7mt{oo?UPccUc`O7;lQ)EqP1Fq`FCm zt)RxV7o)7!0AZYkod?Oimhi38Uv>$q7jD7IzKkhB_qd}JuNYEiW1jWS?19G})+h*v z{=11Y6j-uHeY`>=wmz&4GWNJqDZs5jXKctP&_5hK6B#-}u+}21T9|Km8Oh&&yB7LE zqvkgytRE2t;!|s$nQJ_x(pJWpL(uWVO)!M~h?q${V2`yCO4u#FjWWHD)fPDa7Ny4Q zSx@<6tyHPcs@NQa8&k`H#Ug$LGL3Z#Z>>^GWY}Pw)XhghLv8goTXgHSC=1Fs8~d)J z6C$D2C;Ov=DjesHyZDVSAOE(8c;F`}F(OwSq^groyQSU;Okuh=B%aL$WEEVFMs?Ai)S`p7<4@`EpoC&KWD zu4T|pQ+1F?k8OI=i#ZzQdi;ZWQO4fE?0Q|zZ1?1hrbiPg_9(7bM40_5LeEl=H^nni z(iGaw6n0whTt_O@xk@W>N~kmLxHV5e21lg@o*UM+yScdDc?#`$+9kw2C?vi@YCut{ zoNkP41e0%gu<}KeWPRmg!CLUjEZyq!K3UH}HtJMCvSwkS)K3Tuo$i3M#Ib8KjOgv| z^2ObsR9p8*ed`+nx2cPN{+ir*54|Ys(`&kS#8%1vo#s~+{A&;jp z@+GS`Y`rV^p*1}8?49|BntAdy6jyz;%AOd9r!bkkqH3AZC%R4crOXT8_sKtGJ!crl zDowYPotRgGp@r0H=QIRjeRZn*vi6=RWJA6N*(ZGbvSAh3<2wvtQ?zJ%80XaH{YMsN z3H?Fb$T1PJho<^%^O~?QTI zeI;GAU_<7^@5sn;hu#&=vbs%Jt}g9xD{oVfkI&{R`SK92aQmBOif_JzS2)mN6(PvH z)P@m1^TGtW01X{IpS05uL>N^B1`GRf?smI0$}X1K*-QlUpf>n>4~EAW?4_fnudH1z z@{EObrPEVIKi^V!O&rm2$dyWA{3q|<-xrAaTCkz-WhV}nW==dNV5lPmEq!+vD?Sjt zVfo^oXfs7?i?{O?hJ)FELRWT3WbshkBK6SaaCF_muij$@c1|8rV?iS3kK>6{2|a;~ zmU)gf%}T6WjJ_5)HQt9ocfGGDXSz=ee&NmVelm+anun!_R@3Ox>eM50L@71F1Wy0? z1pKdu;SD>oM_&V!s^fiPts^W0OeJ%r${#L0D~L1~&kwSZEsC;1KVp$}uAu7bZp#Yg zV>>=5=fV&~(on!+N3BVh>`6k`meY#wCpT=mM2>Svcxa=Yv$Zc(e}BV0&0?G~&Lq&U zc}9iD9Zj_#Rs>|Q}BR$mZ)MhCz@vrQ$A(nA9GR?FtOj~nxT{>@+QECZg zDbBtgjYMtboeGRamLCwx(rngWWwc%JDn5lj&}cXn5H}c!5=5d{?@V2JT#I5!e^{2$ z)>MI5&zPu1UybImM+U7A85j+##Z&$g;O8BYXq(4c^{mc&N-U&E>lQ!rg`!QCy01KL-2EKK8`h;m_|fu#=)U>p zBVF_=Pt<2!audw4(X7_1IsC@uqm0N~NO5lM3d8Q}(vG$@{M$xU57nY~f26*vh`_UB z@Be-Dz0Vm(_)NJhTc=!#ewMHO=;}6a<8!XgJwn3zIm9{DlR~tCIDAHWOMQvVRt&DV z0cW?-*Sr_u<7~%2PgS!LhggWs3ds)9*H%c(+l&~;jLEJ%HS)g5(;5kM(vF2x^$FgN zW*(*ZPBTjJ9u&(`(;G`B29Y|3I%`r`K-i<1kkjCG{A8S?-w*L(1PL zmElTkQv80N4Wdu86>6nRsYXS4EEDYFZbk3nK8Fr4cGHR#_OPxV+?hHTZe*scQ18#f zkJLRQsiygaQ_@tOFO1UVfs<&JYOKbzN$}dy|0+j=X?S}6gR=5x*Tf>-H$LAug?ia0 zN7;!;jcV1ZpB6>ESVzwEQ7sI&k*!ZO4K_~qe&ZQrA8qUt|H@qaYpN+S={)VN<8da% zeCp9jT9Y)j%0^YRv)RjZ)nq@+Jygv87@5lkl-f<2pQod**Xa7=zonnhe&fpUOE6!= zpzQQdbq-j?czLN3O*sff#A?0IE4(rPJW6k}nWr@~QT}aFx3XMnG{F5i-Kn)>(f}XWXxT!9O;l?dEu!7JVw zw#r?VMq!a=Y!9aKfX8EXDDZ85&*>Oqjc1=&I4~^5XOCw_%%L(eP!mS0m-asWomkVY z1GBeK7CT4ZHLO_c0H{1StV<+^dEBX(GL)#8a)hgushBeVPOR@n2hAtvMAefAK3DbX zTp!;vyl2kQoAk?&+90Xc+9Rn>&Kgq?-4CiqoTt&VAh~@QT*ogtH1d==zKGD;ACjvP z-W24Xc8-a6I_ckPWm{#uP*t^Zr?*!h_%e+m8iD@=}1z8L>mCXq3}kmqT`j~S-e$CXQK zMXPl8?9WhZ;s(f#%!vi0OBG+2Q5lT&%rU`!>}>zzKXe|>145YU^BWZ#O1ym52b(L0 zgw#AVU0c1XJFP_-#{RsR(C487UDc4SRm+#CedB*zypF*Y%Eup)yZw-AlP2t$WV**d zvMslQUOw|UYtI@%a9xgJ{l%(wff`fWlx2!_?CoP$oCcdl#UNMeWyl-s%ZDxYt)J`6 zHdj$R2{%|(pyT2qIl7BvuCLE6{F5)yH2V^MPlWPuVPJ64t(h0LW*QH{pmq1xezd-& zmQaGMTW0yf7Qe>0c-XE9ia z{ad#K;iDhfI@Na?JwM4w=ei{Kl?m=P*}$~#xCKtIes>lV18<6B36U=}}S@cYDxJ&Hq7P@G2BcfKwpr0#1B z*>e+8y2*q>DZao}63foXx)36Bi7TzvS#RXW2?CPRyqpmt^~ZiV?63t9rQ8tvXqRWX zAtf;`DJ3zk@YBjI!|t_NruQBx5ofwRw#N|v8`tfnPrQ1$14Ui!B&5`F100yqYO36e zA}8?_QB^S1L9SVD<$^m)lN{Az?=_hEqrB8}Xb1Y~XBe%59&j4HBdxtKPx~5^YJuCzZN&`}MJw+^PlwW_|?IcXRHGwV8JJh6Ok#uWV?5Ulyg!h=R*s~`f zR{b0*i(7e6^Hk%v^)F4+a`kBq>O#X_=A@gxm8@-^Ly}9jZx^;op#34r*Eb4LbqiGf z0#B4CmsjtyEK{f_w~3XjQI0RgHa&t~Te9L?FF)8n85yz=A~Tf`)-FDk5FUU(7=S%7 z8sZ|QF)H4P?8E3-dh#HJ_9JR4)?!luRQUHqp}9=Tl=N-xxB){kih~kp4+7o}{sz?# z-p*#>yBkz6iSpYW5LIE`atu~wmTv*eGhMz;rLtnekj*gH79p!7ZUv)4>GIodG(7za zyMAZ4A!u9Blci6%(bk>(HAuEr$l@xWRY$2P^&Fr|75xk&R8sFQ@v&%NZJRWoP>7>( zUy^MbSzEZcZqh6i|DHe;BJL+Ds`?r;se`PR*})u1!_#B(F!GDjt;E4g zJ<{%Cdmej{U8sOQd(p+strF=k{L5rxf=sNuhL90 zH#+EL>Ymlq5~F1JW$xq*NJI6v-H8n#Idj{-8{=;^_V)TBZKc@OT(! zhPSKWp|2I8E#aMrd8Tf`b=(o^W-iW_{i7N+_sC%95G$XQ^s_1?+fwcfzeBuPp-yYZ zvt4n63tl9_O&UVkiQkwU34Pk={qgsh#v%og;s!F>Ea`bKeow^rXP?Fm9F!|QMHFHY zSs@l2?B#?mepL=^TEeB8WSWj{iZ{mlC0)OF$=FL&aJngWe^7V?rN_Glqo-CB=li|I zmC-TrOyZDd0v8W*n8%u0-r_xxC6t~LArD+&)Pi`2yLrCEhuNm#_MVdeWK)`_(qIyh zp@mT!rGF?fbdL6YEmj-agcQo6H^e8XqEOz$8R90}KtJ_lO7TmBxL5=IG`2Z}Lxm~} z&vx|5x1r~xK{+CqQ`8h=QeTDJz9>0j!8VoUWUI=%wZtmfa#>nJtQIfq;9*Keq&-drNVfb-Aj)Q4bX_&o=am#^l^KQg( zw#&Rhz236~ju!g@)MwdfwO2v*h@u^^TR#*u8ZL{LRGv18s4>3FdYAbj(=t_+rH9KA zry?@Sxk!t2A?3sUwU-SjZB?=_o8CXOz906ZNo3i?9+P7vDpCHU3X{6xC~mPQDw&4T z7aCoO6L#ZMBtccbIX?ECA1vEm(}w1ViSh&t zm>gXX$PIUw%EN^&b#mVto2KOHx6I5l>*njQ=w;stg#@2HfmRU=H9LHcDfzXQ`;g${ z`me<-YuNc|p}}F*_=A~yi3VG|Hqn#?7nWzb2^<#>hKwWbk2Ps1M2#qDJlZH;=uF)k z;toIeisHa2?Qc3dC`|g^7r3Cnb=z$Z(-F%F+mzG=i%rRd+?Wj4j!M5YI@0w^)NMC0 z%K+75tb#omfh^N!xy8x5M82Wo^*K6+VZLwSkLlF8-bB0Ii+*F)XHfqf>oxpMA3228 zx3-2bYyQH5gwjx4)3YJ#o2#>hN1po(xscf+;+99J3>SPO&f@eO+?_CLOTuyzp1#$EU9z~PN@C|`U(23OcK zb)`oe@7K3;?M+6a;P2^AP3&JfutwJfcTT1~^7w7N`WY{is$=?V)a8%C(b_Ot-7rsH z$+{2*Ess|L3xqa`9Ns7^n^z;uV+)&ieoG5{)>16jDn{S)Jb_<%dV{?7{UUnUFvcz! zM=2(;JS1w}1EQSzg?j~WYl@denUH@Q%FSwSX6^rdoR`I_ETOqze0ss_efEvaft+rd zQU!Jo*Ro01DI&aNh^?1d>jP_ho;aV%JnM&K^06zCt!)gce7sTomSZN{hAm7ajWGMf z^2lU68lxEs(>HD{n8vgKaR|vH0HSe^J#+?;fBgMEdj=Z}W z>y&0pf|=!LLx{7DKfO2Cy0d8VP<)=mH;s6MZ23DAZ;x;E)^3n%PV(+9(qkC+41HIu z&)u_GzE;*%C5mIQ4_~a$+p-u4Likr6b74T#=Fj&q%~E_lAHpy(jVf$kc6O0NEQ36w zi)ES_>8Ee4Jb|VvwW5qLq&d+JwDzgc5?NU5Hr;;#Pk=H=G3BuPTC__2{d4RujvqW3 zSHE~NLRb<`Br3h{L^_7}iIyUUHi=V?Q0hSfi<7gg286mNP6!ii)(G4qdibcuu6jJk zVYbv`O)jq5=-KDwN9g^-6_LUPkJaXB_AzpGd)X9A={4Kt+W3nSCx#fmN%1X_T4Xea zptwOTGwCOz&Uv6jUEK&O8&9ovu-wAN5emq|cYSJVMV5nRW6H>&MN9||{BWwh0z-1?Dy z3fsEH7nWntjE}cp<4C7*#xfi3B`JWjBEE;IPf4NwvQOl}A{ERu&Ls1}dOMd!!RR9z zZNe2^g(2=rd1-;BFad>J%ZA!^Qqcki~FUxQti5t z#z)$~Z55UVr1wN63oS=kXP2!fLfe7|%ba;HQcaY9lI)B4JFvy*w>`{jtS*m8H?zH` z#*+5F$py zln)0|tcq{V{4Ka{kX5$)OB9!!65D50UTJHXH&inh1s}HBhMKBP4zU@2A}OHCblama zxge?GvRv}fH1rGw;!yljKU1Py7Ona+o`qS2e454zUoU@cmB=!*2L4DACk@ia%`c_E z^X}Q%>BbS-PK)%qm#(Vsly_sJA8D>quF~bhI5&F40O>|qwEZ(Gw=i^9X5?+O<|EiJ z6R((v)acOCZb-wU*@&{l7xx_I+O`RncfSuw)L&ZIr%2Q&R;Jk?M3g*h2!iQt61bzy zGpK(a+lBu=j@jt9y9-vYCVFKI8;x$TKzvcJMvg;vAltiM*$-nMOza2ZY)!+*O>NsU z2pIT6gZ1RJR27r#G(K{65-cY^zZHQq0MnQ7^($IZEs;6It7OaYi^k1i{^9@jRwdi9 zTEzY7Gx%L@Z(hXrTxWdGSf!{9O|wL#pSAvy=6izG9K#mb`Cg(kN*DUXx5q@?=VkXJ zR*n4T_3|n7_l_a{Z|pY+xLcjDO7u-q_30)aH-_o42=rjG!#L&+HxGnnh4hDyk<(RJ z%!&C!<{RonG2BF2@pmwfNf&rK18SWEm-;wgxf(yr&D=jOQ#2+$I4+AeYQwW<>o+Ei z|LlyDo5`*Wf25}zv?Ov?tdnq*VvPZv=2or}EzfkRHss#i%OjufpTGDTQyI}V=L^|C zM}j}+JBr`Ux2Z*0ql5p&VUJkNgSY|Q!S4}{JUvNEMK<{#tc0Ny2fH~DbfH8G%0aW1 zd)&9T^2m+kxW3cZpZ0TPKg%?gt<_?L1mE6)lCy^s9INe!y(F_b!TAjTOGR7LCwSrp zTY2?Ys?xlp_yq^^kS*&CRyx-cLK`~mE{@-{zgH!81F#nD0+n*B{D0hfwBb`tu|z)Q zUB$XD@_6N?gT=bT&%=Z43)Oe>B&l?^5sE zBoqprG0(xT${qOI2y?m1O__GXHkmpnv{QlnQ9*FH@laXqVF?Vj3vPR(g z%GW#G88r##Gh+Q!LZ2WKK4V*khJqsxy(RBO?)JAd^dm&HDabx~nfwbpn^=aYE5!T~ zXYaNjREU};G$_`H_48e>$)pi2KC<$U)lPp_y?Iblynw~7B^OiHI{VWewMK?_|LEA! zpiORE>;Sh|cHHisZimNjwwTsg-%Acf&Pe=EQZqyr35@qXw@g69J|MJasw=%76+%>f zg1&uQZsHYpNNsTK0}HEFu>-EipCtm4hW@#_BYk1N7UbVOxRBhmmVQb0iKc+$i4`=c zP|-9slvLskc048|3vo`JYYs6;|A+tTD;v*tg~CVQe9v@aV*P&*W(_oL|D12NAi=fG zgU+=zh(3QicCI9H$NlQ8E1Os#6?Jd{$+nns+N(cL?^yv3qY-%r#`*2jGqhe5aS;a1 z159j}KGxEh99@2imkryvubk^eYbEO=&n=^#@3deo(tN^Nq#7`n58QrQZV0ssbGuh? z?}&K=VouyY^2_=IQIL?wo^ZYUSt}Q(ie4e@v~a(5rfem~Tbxu^YWV4ggt>jj7JcFr zJH(KT%i@KKT(=tv8^>Acr#P{Gk)AR?;}$nTPMTNlu#JtuX=V#b9bpNJ&*pzGXA z8~rx-#-o9_jYk5f8Et3Y9&K61d{XHjluCJ}d{mEUV?C)m5FL1?Z(SgaT`fU)3J6|1 zrTN5GkzXJju`Cc^_M@`xp>{(LV319G+UeJhWXr;>!QMEp%R)VE@g7(b|C)UWLoMEb z|J`M)rpPXGq&5FRzH`SW&d>dMn958`7jHBq$r|(fWkI4pM7%o06?Yj$7<#4>Z+&+s z*aG3JW-VVOTlv%1rfbNjJEz#gzJAO`zpRb?ws3i+4zL3nU*$gaOdiVmFf=jIwR+c% zgr}dc`)d8sRH4M-++J2kSS^|lmEm+(2K7ZFjz`Cw0tb>F|e?go?ZuSmnI_aNGac$M&v2-1dL^Njl)e z_Q1#KCgHuqKS`H)CXiqU3$Tl_{C{XWr|3+g?#*|1I<{@wR>xMywylnB+qP}nwryK) zk~foYzMHw3tN%=`s#$sFT)%6vh<19GMcK}XyFm*;V>~&GW%MVYe74()oJCwl1b;&(sOdsE1UDKtW(d_9J*GT(z&nL?XhB25-ad=K09@KF)| z`W>XhbZo|rI_?D(jz}oi|0_e{F7}jObPv(#;=9&Pc}bjLFSwNTM;b5~7S?AEh-S~|P+#icw%rqM)a4nUQn zvG3jv%K)Fv;NR%?g3n(9S62M1q?bf9qEV$&Fp0JRW#QEYwK39dKU8c%lEDOE9fHcE zUxQ=pJM{ui^1s_D5FYG5tuLhuM`ZNLSs@R!CZEV(tXSO3f{V0~i-Af!b`-r19j{I` z=z2#kf57f!dc9r#ZPIVH%s%op>*tSFFYsjKL*6&@0;=5;U0`_?NUkrnl#J7m4ofX1 zraw#$jVO#OB2;Tjfv?80xR4&G1s*9F=&Dw}B9*-$nzC}~VbmOy8 zcB9MZ_4t`93Y!AaAIhE4IRw9qa}3pSkH+h2macf8FXyR-$?wo5Kl#y%*F);1I65_!@o9JHi! z@J`={jRGZ;wpiYm&wGw|1FFLcZIId1AlX#VKd+#@%?P(=C(}HI!;>94{t-;%)#7F^ zhABz_!1B`}K&LEx!Q6&6{@KmPEbi+AbzQEL+?@Q4Vr7-TI6n$T;HlX zMhE?NaWjmY^0;z5X|zzESfL|9dSasm|LWrRRUqu2A;6mU^X*CQE*$1$m9yjkaJ`9w za}nEvDA3scOz=R3>Cv8P1N-*21Ko;f9_Qo4Kr>EDOVgX?`$e#2tnK|$?9?HVw#xuD z^VRV;hbH2%T}B5*V;7Kw#h9^>53r>>YCVj;g%2b2`5LLbk=J!M5f8sJN{@K(u~(>$ z2>#grm8MdXe&;)iFn@zzMkk^33%OpqJc>tGEjc-@+W|Io<4FE`I}{@PuLbY6|Ko=` zTGT|U%Q}krvbSB3cFn@y8uekmp2At}yoHL)!#6pe`5AunFcDLFbZJO+ltLXv+85by z_(Oofmy${iHl?jmFFrf92`i3UsJYwI1(L7?&mhU zs(a9&9o!3Iv0h)f>u-V3ZKfLi%n!Y8STSaGCoZsiv>N@%|6g^$$I`=P9{g-Mc&omHT27g39w- zyFID{f`{uGD5%^!si~bB9IZiSJM7c+vKFx6g}Dq4sN7188p@I#{@4(~H=K{_%#Ga22WD1>TH)WBiC$it>vUZH4Om zS*9-$Q!PBTX-B7t3N%Iwtp>HM0phUl1)mh-Qxq&F$8qEVL* zFQv0MHwP1w5gFhoaQqz%Gnf|x>|A{b?pF@p)lCD;UE|e;;yzzps>4>7f1#ugwOOdT zZYSxJBUvejkIrfl05h0GJW362iP;fzYaz@&qZ=`c|H`|26&evM;WPE^%72! zFfY7V$ybcP`?_aOS!~<(_~BQ(*Lx}#6RaO16$ucvG9FL6)e~jJTT8-Q!~%)jzRm{j zWEkj~|I#ju{KiU&44Y)}ULm@FRfm|9^6RHCV(y*Ho!u zx_bz_@~_a%%{)1O0myfPx3u;u)Qk5+RYaNP7m|Xb*9u2CNz3ewvKOR?XR8UZjGCXcwnuU_8ePGtTwx}Ki zOCmwpnAldH^FF7z&0d-;wi1rGxsG(Oxs5C5IE@N+RBQO35m(5Us9DMvsTQJaG8~_; z$`}PaAN;1cqHaP=TiZ-$uQrZOm2^F7{q9H#xmV0box|aCx5zb6)$C?Ap{O|*9C(&* zJ|Ugn%cJszM)(Za)=}WC!eI=@;&Wy#b39Lyi59dAWQOnMvc25CS7q65<6hoJKsrg* zd97w-k7QJ&ZUijQ;DhAt@>lx1ZVMF!)xcP;Rd@|NJBj3NBN1E#Mz?_DCzkVwrde}p za#;%_cH@OXz~zG#wAm8uc)JnmMxjUeB!$b`iR#(P>1M)}!-v7#Id;!KDb6p?tmTB; z1BAKr{)Q=#ycYW7CG*@RcCRPk?>@yErj>sw^T0e6+P;Sbqm2Af1`RKn_W{kWP@)JvKv|076N_f!Jbl}?#TQ3qkdhj*P7^zRuLa<2o)sPM_zvzsyn z@{OVPQAV*2*|rHz>YYArTDH*X&z;w&0LuyKPo&>+1%HQ{f8Gf?ex<6A))czpuPCtq zj)SINb0)D<(N9u+&XsOt{2kbb`Il>Y4N{PzfNAkA}?tV^!VZH2Fg+Tg+VlQs&?WspIZzj1zTftgPpS3Hi)!Qt^*&lvSF$o{erddhpCpy&h+#3((l)sEgnmhQ(v{;il1JIE-`^b_-k!&vv(L%P&AkE zLW-}jN}NBPKfN9g?5v%DjwEUffvce#w{x0`1d{@a+>JY8uPavg+v|IqUA8h%VMBM| za1qe)2@Ino6Sk(p>v49ngxl$tCfJK+=~&!Z7xHtJ&4c<9W{X2fN8URbJ8u{Vx_X11 zb~ry5H^@-epB(AM)5ZAlG0DyM0poHRsEn13I4y4ZicwbD35DyS7mAj#7bJ#5;L$C& zGL$~C*Lk`{>w8(--0uQ_53z#l&oJwArhwa981lY4P5sUVp?o7NBfI){qzJMy_!gNc ztFJ@us&z$Md|lapDOcnFAR^(y$D2OASJ~Jp!rxA|V)f(bdBk6!r*bq_EQ;Df;g!y? z5}haHulE73N2=E>Q&4X&+oe@ z1rj<;TW8ZJI;;GNXM7)9lmRY)J7c5wmtUR-uH7&Zix!_ATilGpJET!wz^FXAPU~w$ zOW>GV4=t9_y9f85VofLUcJP&#pb&3o!9T8nK1fo00QLMY*NJUThWe-7QEWsRs>h1> z96k!{L^q^sP!1!h7mgC_q~W(^bDH{U27(Rv?`b*QsO3<6C>_F+EZtQ#yIp>WFEo#X z3=^Gs^w=8n_||YM-UU#lqu%fOk*};IpG-U;nJ!h7?XsWK^GXg<;Am|tOt7)j(SJ9E z<2cXzdOQU(&zmo_$t*UUmV7tm)E#1=8RQ+swxSx0 z`us+Uc9!iO=2Nr5?<6Z$Z>xjxkD7{N4?pc%H!`nfU;w1xgoElS-=FJ{5!=!!ujOt^ zLPz{rE~SN11F^_s9H!djIt$oVB)lo^oOCr`YN=dLbT5~V3Mu`8z9tV<^&dZ&|1;L3 z<@j%`r!23t*4%9Wzg<&YkT(6n1tDbZT;ysA2-OHU`at@&{&Vcz)W|wFU0!?r%lf?W zYT7=@r&j)4>Nv(RoMJrQHSqKM`Rg|X0>K~OAOD{pa=$8v)BJhQN^bNn4RQzou8UF* zFec`GUzXPps(~4wo0_lFb79MxzxSv7wm&yz=e}4yYC$TQ6CqLzoP+S;<;gIEH1Myo z^4&bXJb*l2oM4-utWeo~dDpA&d(|ou8lZXCUu&Q6x6>@iR*w%L;2ZrbR38S*6lrEr zc1sf-F;xjQ+JBlIKw2W+`Q>~&9=;wVVrR%P7bee2*da6r6{Z_t#+F;%2RF98(~W1R zAE2P^8^jIq^>F(*h%}{}e}PcXBAs^q8D)5e?B|j8q@E9V5M_S3;hjSMy)g=gxZ=Bp ze(BY$a0XDBi(&f*$?ZCsz~|?#E5l@lMjP)G?&w_m^1Ho~?`oe&7tbKIaN?_X`{qQY zyk4BvB99!sim@>3@!5fe7=$GWB7#PP$B&uROicx8Vpr#3IJKK=Vme zBz@CCrM#0-Y1!&h_oBA+mj)!WpvCUZVmHQu)X`}ib#D5I>T%&KoZGg>{+OspN;r0f zL9D{8iAXobWAx(DDFI(HO_br~Cn0}PCVwiah1bdq+XVLRm?{`}NhWEkk2mGZ|`33O@>6a7RGm-lFX7KTaxHj8*^O1k%(>c1Z@A@=75ARnyf=4TOP_QPjr zbu7?11ouJAEN5Vg4-o84_(GNLZ|Y#+sfElZuNAF&@V3l4Xepg26`lRKhJ1o}h{Idx zr@dRg?i49!2V-o0?Nv(dS;0NlnQzYvJ@r5Zw6^v?ImY*x>yAb-v%jXGP@Dcn8FbkW zUeJ%PifR#6A`fX4UbKOomiUaCrV?mr6SN7>PR+{k2ki7-?aoamRSd5oSyL!u9_rzo z9X>o>?Q?mSs^FN~pgz4cMZNF1G@rVr0I9s<+zs}oj7eFWeGNk^UsIz z5pGwzdMxz|I)|A=5*JkZT;E`I3+CziHsSAHT%_CwyFopfq07}XFWvttN~@B{m+grt z(a;AKD}pNh3}% zRS9(xck_s~pAkTN$^WuLM6uxOAz9~%Zyk?h?h|a29(JGmcWz9IxhSDQq)t$_w&%|p z0rbCuH1bWT&p|#l^0)FotsxHGA@p(u_r|;LKX!y8eE-y%CPv^^qRx|;+KLUOTSS3T zj&A(PVclQJ@%sE~`$8E&gnOnu%eVE7$DUmg>c|@L!(*_E3%y^Oa0Ni^66|eZ3$b!R_b<876mdS5K=G#;-$kw9^24 zDnNqg!x^Hb4~T9hABA0@ej@Y{)poYNLnhGDcOcGhp9^}W3{2xVL2WmJYx{I z#o;oA)KOBzHzmla2`YTS$Hg-s?4FfZVAT*M+pstWu|kf;Rme5`m#zlUObMT`Fl}V5 zBS>ym%iz{2xV;vBM+ofoql^FgIb)H~e&dwrN_<5;L_PnX{(zb5*lr6=Q_f-yn*@G>j~jJFNHzeqw{P;R!`*2UHS6i?C&z#@sTGb^=UZG{%Uw z7T`=_`6aIW$d*6t%K^>H`!nAv?c>J5*NSsw_ZQ`WQ6%Z)RpKCdtE@Tx$+byLs|umm z%bQ+y{6EBxZ8GhA+N&&ODpePH+pzG0p5+<1IF~t^h)f|pG4p>E-~!&Zh7FMtBFfg}(4!omZ5=Fy2++vQw!4;~V{JqG>d`p!v=-2<^ zxO$bj4b?j3J^bHA?4w*$cG1GdQo!8O#$^#30}NLP`Uo>ZRv6eU%mMV?WRo|lSTerUrHCSzs^cTbGi@;U7pRQqwfF%(CILm!VT&j5OQP@a5gSy+Z%{cmi~R6l|70J2S^cKZg-! ze_jq~W0JFn9+wSi=-CEsG{8nNpOvJHQKEB$QY+CYDord&f^@Zktp^=h)V;jBR_|FJ zsf@}hU>56mJwYIzrWcecb^8tM*t{1JyWzi)xq;L7nu5pZhZ~Mko!#v35SA*deXDn- z_;@Dy`o}mIiEQI(H549x9Y|KI5PPK;tj;n`v*jr%oMc#mtgR#e9tIL0VyOpCz|FBS zUIq!3+OljNZlGiXA5}{zfZnbf^ZY1O?MJsQ^G}3?*rcyme4L`3=#5`!HT}s5SA&yFMvdi8>P*43PV*-d5F+jX1|Ge&**{=TmsY2vI z@{CnWj^H)U8itra4-#y2aSoHAi+q}~=`?Z+)aTgspozp5h{Or0#v8qkR{Y&=3==GE z!jB~WkEXE|blAA*F|rm20q-tBWEPeKt*ikaHPhm=%C5r+3f1MY%7ghN`)Br+#10WM zql1P;75kCE!V734&xE;WARp5b0(&Ss{OB^ieaqN#X|g714FXeCoGih0`5~0EmzS=0 zOU%L9{#CUSpaQ}O>jFjjT(_4&c1H-#5ra&YNs@(8HaqY1q+R&;YbV9QO}5@X&Lv8s zl@{p~(>zsS&hmS(Yg^1`AK@@#FSxB~dbff@a`PqVr8WKxTXzorp<#($>jmGxqI&0j zq#*)R_8tf04!ca+^{~mAp7Tjgu#VqgtxQn`S+#KML0bkgfBiiX@y$hD?w%n)0+49J zmdjc7uS1KKe3YmNwRL=1Dc1|3*=CSl<_fm`^ie1isn|;!V8)Z-?g~3?P<2TQS7(;0 z(Jhd-2I6m!tmT?mpNA4a$j*e~MY>r)l7UX#1fykY|Tb*{8j?mKg{{ff9fNWB!=&7h&#&MkJvnrd8}f z!&dBl*b4Z)J{|qJXFNJ$EvhDZsd`;lD2imL80YZl5}KLI!_6+HsVFCTk9~B0+Q1g>F4tgYk=GlptyneNsAc*#@>lKaSmihUA&JB}iu(b(!CTb5(U|=^ghhQAoYQC<9Btens@_tzJO(iH= z4XwjCxOoWoBv>&{%q(p8QK^{fy0#i#$NY=8Fw|`C@cF|KBhtPu81r21iTRT3#4)-ZuotIG{(H)}P4TFSbm}3-Y{xNewzr0v}iX_n1`GZ|*CpQllYZngMJ&s@Q zT^kqb94XA|Zi2Y3WaP9J{{@BtXo z;aeVQqEK-7V+AD941K*p+PIGD2xn{`iTNWPx+^>051dYhk})(EFuZy3}PXgc`8r`_qS5)4s2-$-PU znjn{W?HH@4I*_PF#v$(bH|X0V7O>(D3-ps>JIoI80cRa^!ruve(YandH^cZ^l{YJY z!t_k#;}cQzBt`%jqBaJY5Z>~XRQA#0KcknEt4}lb2JZ=zY`(@sxfXUBW#yRgcQwd3 z#7VCy)p|Jhh}RBgyd+(jW#Ba>-z1(1b=FAh9C`QkrDkcmml6ETR2tx_gUNt;QV$<} zF?P37Y#gBJf=Ys{E@}@=i6{)Fl%cv^IWh=x@8XF@d{^^%yg|uLm#fd!u!%#okgm%q zjIT1pKgJMm2ngrPJ}_%pkBTgMUvu1Yv8Erb?Rz_^*}v>>S>$ z6}w+%aY07#2`Q2JNHXU~Fy*;h#3FMd-Om<=1ej@oI5xj(h87LZbGNm2!$FYtGm z1jJ?@?M?0AGQ~wzk(rpqjat=yYt2`yuC?TUcc$`K&Wi^hxIK^kp^27-4;6(}RrJso zL7hSaS=D(Hiv>Km{W-a*#gE+%&fs8y01=Kz<^(G$^uV^@;J|gP;|))h&u$5XGaQs$ zrQoi{s0XQ$SMasrE~(dD1K_vjXLN%P(aSL{@Rnuj7qC@X>BzM6D5COS6_V|aZTSvG zQ&hb(3%An_zOcf)Ml~!s%#_o6?JUeqw7Qv55tC&5s|zF3u=7!7h-Uv%5#v3Eao_ zZ2)%^V>ZnuTV12^_6u}V%e}&kw0{)x_8%iYl)2xK%N<+YkPFD{Xq|t;7M4{0$>+sW zP)Tl9@7&{beEy6t!?gY_r5WLxo$>NbH@ZY(7_XO|T!OzE;}s@N+GUsFONhIfsuE_wiW7Cs^8~ zR%fP`@eTP$hPTfU`Gl0M8V3o~H7oZJGW7p++N9{=Lwa9gc!}EFjBxQw1h}2wVmd$k z3UYXXIld~P8Y79=dC$qmHH7*nZ@o1BO=m5w7K&~~*>#JCw~%ROk++P#JXD~rj9ne> z2r0hywY&MAU5RyA0p1ey{g9rO8#_$$9NYqM<~*AuLy_;i8}z!}y6P1?zuh6x*8sKh zaiZxe+1F2AX@tNfzHL6J$01O#r$VDEd~W@lUVO>RhMvxX_}$%W!eTdIbp^@@gOrnl zu`BkDjF}2`(3zWrJMKTgLwM+` z8{*mf503FIs=m1hk6FT5sU4yy7YNX|`dNCl&do->aFV`YPy5)6){Gyit9I#D%SQ6>DD2KW5=(Hd@M)$LC+QaPB5_g(7C^KFA%{_|X1uu{0QS;WPA{Hw+8bV`C)5?`IydPAnfTK&>>O{J4Gw^_&$b5n zb=ol3AzV(n{Ij4@@=9veKxRR@7%>8c{zmihpUtw{f?W?rw!qr?V~afaV1oYwEfpz~ zqLRhXC9yqTvD?q<;xzaeSwe;Ht8s%0+l(O z0&BZ`&g&trHl1PIO=Om>Ol_2VH~e=r^Ri`7GM5>Q3JHs8&3nXRftHy5DRgn7DN>Ub z_+1402V-i=V~J-9I70l}f2tG)nQiU{I9P>ZWw|ysv5qkJ()hhPhXuU&gip}H>fAw) zO<&DG39`os^>E)mF}F59Gg?)y)z@2cbi8X+I{gN?To$A3|*9c5Y)XeZK% zF%)b$gc_!bvfoFcl_Njw>Pm?!jT$~0B3$CFLw#s_ zP^GvCEx$bC*5756PQ6%tGXx;Omv)#!`dekNd7PTR{pJeiFb~5r>azj`b5J$G8114k zWuy8Cfn!{m((-@DA0levq~SMVP1NC;4TG8C-q}2Yu6wg8sAZ= zQMB{JJEKsYV6;pS<_%~rUS6do*euLA+ZF1;#HtTirN5OC>%I=jH=RV)h$?i?cE}QU z%q8A-&-QK}qV1F|b8I#4$ECTNoRZ07L|LTm^jyO=nSAGpllhQwT9T}U-dF_vP$o+u z=nF=%3@OF7nxb#TraJ1W`U)@%9wLUpcqOPZb&5ouTtfjl*@ax^s`g34d;y*pG=;`w7x+aC~lp(5%?i zqc+grAXUbD{sQB~F3ik7F{4o=$QEALNlYpqS_AR{qmc5hqvFSG>tQd7xL@Q7RMQ8suDU2w#As>0^5qPYiXnF<);v=NiB;s5wv>o&`L2-+(jUp_OJbgLfL=6 zY544&+eOnb#9DizQ!x2@=4a^Anx?H&`TRUN)~$iL>kPu)`xuibw}32BoV<5oUA>g5 z7)1C&@`{66uM$GpdPEqgu+{OKKl1hyJM|whX;TSvVc)upa+p}`@7hAro3SlGnlc$n zO{t6aXk&(9Wr~5QYB-@>oXD<0q+1h(zq2+-l6-rQX6UI9;16sS?hJ9e4}HE%%|pi8 z9Q-^*JJUlZ|C?X}*nlhSmTmf5gJem>H$OwH_28vzRGw{#{->!;T(ZZ{-8wbgsUgY; z&?Hr>-YF`@uU?g}DqbtX{PMF?aTk+}0^;m`iaZEFeyg-)1JnrOn!>Agi5p)!q?QKR z*W)$YCij8WCu^Z^*6LQ7w3VGfDpqHXyHc~S*zaZG^ZIhv3v*yujhuR_>VSE)iLvkSyz+-=vImZr*kd|7L%zH)CR7{WCwxYCzZJ zhwXdB8d8w>#&6^Yjwzh;DO|y%elpkr-+yI)jhpq`2`^yovjxrTIQyr5cZuH7I5z$I z05aNCUn70;*hHr(q{}oKc;)G*9pY#ga&J{?`^jw8{XpO%g#S4UR&On z_3?$}Ja)lSL7*p%LnR$_P9_{Imdq~eCSI(q$Jy#-6XDz-w1$Xi=o+tymKjSly@^t* zbVtxI4D*FHdZ<^%jWEx@I>1gWh!nX6e?m$Y%jQKI?12&8UDW{9!1?-Q^+(~g4YWP8 zfg6Q{boWi#`N9>^_@b^b4i-WGZv8tanHQEs-+qhLu~VK5yKVYED8*}unbXf2rDuNd z2>OFmCL}TGq6K@5KZ>)>)%?39z@1T)YC=D4dJyC89E+{!@%h!`r4Vn~yL57Yhq(7} zQ3Ab|uKUsxvXg5RK(lC)2@B*Ky036=EB}c3`Mu#qWg56Nc1Q`WsWHIeUw^p=a~I<@ z#2a4%^B~HpL9R%Nth;roiAS7;k7@M$K(BI;(HX!nBgo>8GfmW3x(`G5zW7O=dUep`=n|SXLJcF%_L4sI-#%gg zBVpfv?;VXya}QuqRAJ*8uas`=Y(#KWDUc#L$v-6C}92eM~YH_dzj#q&x~#Z z#n?C*-ah4KlT4uq&G;MS{snbW`B!$2!x1`jO)kX=X*e8V13kH!Bg^8$FYPaNxj42t zm2AE_l{=F;l|I=%S%5jv=G)anAepfnuTQoc4`{RZtot?dmD5e%^G(1pXcH=xqF7L> zz<+b~%(6NICm4%T3zKcaT7|+*1=-*Sb-7O|I zG^Ms>TA`&DL5|(-tav=>tNIHZ{CTgYW?i@x4W^+W)A*tqVOsu|=eW+STtX#m!@^W+ z(A;!&oH*<4lW;4Ch>tt8%K@Ul_av)cs`c{_uM%+NYYQ92Tz*hweO0vf<-3%dmo`#{ zrY2^7tR|L+mr5qAnMP)_TaB<9k~U)RQU`Zx^6KsiFgtby08d;xyK=RD7*F@$fzGP` z0)U>n#KcmeKI5;5d;X$PoLmsxvVZ0PXNMHpYKXKzfneY2KeS+k-?One8q}DVp;e?v z9@jxJ|4Sp%iehGof^T4gg>Nvt9>y-ltxo!MJGT5ueNBc*dVWrde?|DM#rX7cgvl(R zi#;!zi{TA$zNbV#usZU&ea_Bv1yiLo#?-$N<32l9rq(E~jb@TbErxC(&Jp7-OD<8n z-rw%SF!g3Uz~bn|GPyZAx}a1*zx+`BC_|fE;0g?0;||pEMz@Y?g1$fBTbPPyDoEQP zAkrn%nOR^RjeC=*S1G&1SRm_P8Q{|@;~6HJ6XuU{rPL%}3-#QllWymlh5?*wH07(x z`^LBs0G~+;%-fX)diLe&O;WYXpZV_JC#(jP|Mtmt;zkl@^NkNNCkjaiQ!Xo1`+1n% z8&3<=p%p`(dSvqzLxvY|W9&b9S#53^J`%%Jf?Rt~3&gXAlXl}x3$$WC>-Wi~a{_IE zHu6eeE1^xL4D#*D9P9&eUU-j;l8g%aO}rzk%(we@ z{ug-1ixaRRmPOphrTL$9+dB70>Kdo-Qo?n~vI2qBk;Hw|yf}%>XYSAX2a{atq2%+* zZ}_bpPxD-FUObfr_*dq~7{zRmdo?Y0jPT@`$W@5+RmedbmM9eHFLw7%$`ju;J{;JG z*PqKL-&jU{BwA@Tg39P{+LI$U=z*2y;Hqe4JOg}Ie%K0p?PGTp^1#;MI;@=n9he)c zc{gy9hfj`onr2?5$mm(5qnDUuP^hX=BhIi?rci=tFu)PP#l`R3XU5OQJ0@1^Q+tz& zw1}z<>{&mVu^jZ+eq3Z&B9?jrLk@oq?2QQnMaZ^p`)*$W{X>_Wg9KpS2c=)Dq&ULC<174nzWIA*32Ng>@)>2R= z;NhzG_>Hj&&y4~)%M(q^y?$97)x(acr4Kp6fN?fKeQoC$oIRZ&J<0S-8h7F{)QX80 zLWh=sR6>2z!Ic5>E=S|!5SL!(Z!0-N8K@N*B&BGbAlgKLwlXv>&?acBeS4QCsHp`A z_NngE6G6WGEMF>wBcd^l+7iV^Lzqk2jnR^p!wIf8pBw)EXNa_l8hJ+$@@2uMKXr-L z6mw4D;m*G9uUM6Q5z&mW#1Lbyl8ce>Yw37PKxPm!WYaa z!IXWn?U=3D-FV9isodRo*WT4X{pcz|ZcRIJ1F0L4D?w&EsAh+lf}Q^~`?m*t|c{OO)TnQV6ao7>z}fHlAgb&>N!ZspZQj$l=y$=6esop^nGYld%f;~j!i z=mc$;fpl?>ZjvF$sgIFmQm2w}Y;^|rFsX!l{M)@Dy;`GM0mt$LH`SPBka1Lk`{DxL z#SuiT*&wS`76wQ&r$lXvJhLHHFIroqy?dccesS~e0&J=6zY5H7<@V3g{?+a_oQ5Nm z5<36%zRDOqgf)5K!Vt~)xw${Z;o-q?R-B{DEmDK*V<*mzyW79rBPi~Ag0zRzB+|=T zEApqVFek(4Y3TB2xkzP-i=TzRc~oHv`{EYx8>s4X3Jr1k)O~-sm0+1te0ZuvPN}$m z-0D-J<`Wd<#?_ClhO@uiYYiIOfNAhy1X<#a&V$QS)s34e$XpXGK6`RxjDD`O-7P*_ z3;FbtVM3@z+D5d2v)9A*-N!#{l3b_6c=HaFVV@x&U+M=Q)O4-q^ljv6yb{XsZxJQe zEYQJ}bI2jY#uQfM>cp4@*vGr!ocVX)KOj6F$u%P`D?A!DBhIO8>x7caTlemOc|pgz zYUf5c+@U1>LjwSP+J$B{XI2JyrdfMgd-*2Wh*sZT?oO^qSMzhw&VL-GTWRCNZ$brH)%~PHI3bU_QoSm`7=AY_RJIK(9JBHodkn`lFOy+tkEop41cfQW!`*}E# z-DiGWQ7EcTVrhO1XfvYD@@I_37S81kcOQeqy0(ckf!}#a@wu}7inAWv6Kbuf`QC0Y zaZ;@C2#TtIdNIN?M}fA(G}P>krS#<}($+_&lF|H~&}j|2+TH4pu7|TT#wm}f>4TuN8^vveE=RGtGKZ4V#D3t_#ztw%SMECWpiknn4 zO_itN6dBmOG7NBlumyknKudN`bd2r52c|p5x@NiJ9)x>KNPd-J`^_P5lD`B#|*QKno=I)e(00N`6L&R}b(0@$NCK>BAWg;$J-d!L>iX z;taBNZdT{#;jMnA`tb?H1s~fsoSbgBaZZ9Vp z)-T*bAKNFWGDowVaPtW--LiKl#e1E@F`-r>Kjs7{%}wk01PsxqMHUE#c#>^! ze4OD9f>DP3ooMYf256(-2B_Z4yPny#B6eg+j2Jl`IgL!HZ9$Q$ZE2}R7him6Y-nuI z0;w#hENJaGoWK!kY@ji$ZNU-xrA=bF_&@-k%s4HO%~zj94v`OA8lo#`KgBq>732K@ z5!N8q3h5)m8)HAn`iK8h6}L_edgaF&R3F+U?K{Jrdum1wzHQAP)uee0sU)Q9YPWRL zS`V|-4B>^67HQ<{K29)Zr`C?;FnM@Ok}@<)5*Z{tJ$Ac0wt&oOh0224m6_etkdaev zS7~J1c=h4#RA)%nz{XJA0-ps#TvTfjZvD)UhMpe!yY|1z@kz?_v{s!{C_<43TzB6M zgD%kog2xC<8y6tcT?i&pjU{8zw_siyOce0t>O?!Ew61t;GWB} zGmlDiUgMg@Bkt{EZIk-iqrB^||TBo`vKKJUv3je(qKf9UFlBBvAeJo2v^c-n=Zw@B8 z+^m@?c`62Z5Z51ef>~9~A}p5hw+_RrO(6mH6LpQUV6HW=GObS!vw=(gcjTHLfChb( zUC|4yZHWlXg}*2tD)^w@f#jy>py2uhf#54t%Er5M`BQ#!c<& zpK)x<3Vw9{Ri<{4#QCu0ppD3jisx>fxZ$Mvu&9CG3v}cqgZ>%Sly(}Z*jZp@VMnzxvCBYE+HR$6ziWAQ)SL|lQ26`bJIRrTT>9{Q+ z?SYp%Q}Y~x;xk-B6LVZXy&KI!f15yNr*+WrBoHkc4>>KZdy0 z2@h}g0zmeP#WSRSFAflsP~;%cGs1&&RwN?OOD)zQ^lu)UNiIRK2XuOVRw36Q>|383 z6=dpqeG>M_T49IS4e{tuzvN%W03BIAHPVp^JACA8`vC0gn1>AFD^$r1`IHiPoRlVBXFVTFHkVIRqZIyDB zuJXk?=n_M_5cb^9c#`W*#vxB7S^z)hBL6_}l>g(v=2a_Zm2Fc0VkoDU%Xer2A(IBi5V zFUSGwy3+zVoJb8}cFLuTF^;s{jnV!=5zq>TKz~*;rjj}mGp9_YG_loBfqqfs@!EaX z6fV2q2s1TT8|B*`M+}qBStYo=4V6R~9rNtBO+TJU%^g^d`sUv0Pl4`YFSG^E2uMx+axb{Mwsg4l5Au>>ZC^ z;q8LUlo0MWWoYGzN)vT2=EwP2G>VUopxhFwL0n|1@!t|~ehw|dPKjqI3$&If>cxEw z1AK3=onh57apsv7g|hEFv^DH4$DaK1=JW>j<}_!h zlR!JvoiID`<}{BiuN=E02zdI3z)ntXUbcU`P$coa@rU)k^Sb(>qaR&4XexIrb};4q z5(rHo^@nvd;r6#auM-z|&2K{B!#;*}Mm3B$kt&W&(E#0;L@lxG>Y+IZ!EWr`{W-`J z?Wt3UX*$8PO`4n25u;sIs?sh&F?VsO8=1G0Ux z3?dIB4k|```$cZEudl%%51kW7swm|As3=rWnOg=g6_AaIC4>ve8yCY_E z5YkRB@8yGeEm_+neulv;1b%0Pj=ej;Rj#l(^Qm|YC))S~*-r(z7j9w`CfLTb4*B%> z;?gHN_Lnv1$F@!wSv+eor2G(nui$qx$DdP2*?n~{c{g=0pzVLyIlA#Wac42T{lU^f z3AG5dXXP5;7pD0HbqF_w8Y1i9bq5q_W2@xp_HFqCn57wI{f}K%-xDKZVp$x`$TI_6 zxo2N42Yjl3NFz(3q=r}#lUNe0aAPpk(wpqgyl&)1{y1vXC=;B*km{bs8pDKI50m*| z=2#EgW)Ca=+r&QhoyA(nHj%x_5IM(_O=SLXj$MJ!#D`xHE*ELwn7|l`b;CL)+$TMq zI6Ry%KR%p5q#LvS7J&DBRTPp~a(JxVBFNqICsT~7NVAWtmi{PB4_HGz-HU z{m8zi_W!~{vF0{_0=(nu)r9gy>lG@C)DFJI;KuRx33d@bY)>$?8qA_ie4&+E;A$<7 zsFEC?46lB9_V%iYg>YONu!e(pmM8Z1ZjPdei!a9% zU#URrOU9QOP}_35(%Ds5;lzA6aX4{0q6B?1Di5FQ0kTgzg!I6%PkNLuA0j_;Q$W8e zQOi2$*E7Wz=>YchEh`@>Q2SH_y9Qe{G{l{i6XWI_7H74C(I%vk_wx&DCi|{lK{!e= zi**{|Rw*D@=A|{r{+99hk7$uckPK5`0rBow(s+DGrr+`vvz<2+m*>`EDI=*HLL>F%Z;9s@e_4N*FjHV<}3-LfT_T^~)FW$~6 zxU#5g*WE$Kwr$%+$F|Lm({Zvpw(X8>+qRu_Y+F13{^~y$r_TL%R@JK7*K5r^=U8LB z@AD42IeEWi45f}G?x@kczS&}6+7J||GT;{g0NRyKF`WwV88%IDBivq)m;dUJObI|D zllaM576lEuqq81aEvg^#^P*cNr{`uuJluN}d>9&fdXemme{ zjV$uBiZ0Ll4v9=`u`OXu5&hf1xMyf}7F-TPYRvsa1<-A^3XiZaOpzReJr>8C;AZB}4&3jVlptTI zHN*sS@(qZsvC@iV*+0(=3q1ou9L=*=X{@l|en<*9JW*`S3ZS!}NBhM7M!tmLeMVv# z(fb`0NdQ3f%21z?Sh7VpA zV(XE_)&Zh4<{=(Ah0uKJT?Wtv5p-gi|Aoo(8bkj17ZeEwc*YsWp1=*)M82r9Hwaur zm1sNTX0y^T|6&>W#y+$~Trbz=U!h#80{g(I9_f>NWA6`p6=Jm?%CERn11u>GO*CeN!dO%tCGq-U>~by()g z(+dw$Si9AJer<30RoniL^X|-J4&&;XL-(%xcA(YrEW$Fx-x(~=c8w1Idt_sdzCCcQ zZ(@aJo?g8`#|rBS`gO^$<8P{Fp?tN*b*2;LLzg7W1%vw+Cy+44ns;JV(5;Kza0X1h z+ONL@ljX@c+b61k@q0p(lDm?jQn>~d+@n#P3&J(ZJb9lW{uOM-E~^5iPR}Pqxzx!> z`taznhBUft@#*~ITbuIq!33+&yN3#cm8G{Q;PLu6rD|g&rh!58vzTj||0lSPda7`; zN+&{}MkT>po!1yvgNAZM5e{!XM)rry;pnrUA0knJfTeZ#N)2-D^UluMviEo|d&`4?a`ukv?zQDlMmf%wm}obkv=vj}AUhb=%Z!()^L zU#$Y}MS?fr*LOI~5V8Ll2>-ufaQ?&G`M=$Y#w`EqRs?0dYrj8#KfMB730J6vg%YCT z?P4OL5b;Wdkjm{H9b%xn!}IEXGJ|73Xuq@d`YZGPvvNr1!e#l|`)Td><$32SGV)(x ze=tZ`bZVvl@{hAG4ao90!Y>hDB$P+T^Zv+#D zer+8^)OJtOUrtmF9b-b# z8C#Um6?{GLIp^Q2_n1zzKW(}(X178cZ0iJ6aIV~}!b2jFMb}MJEc8tl8H0*7+FQ+< z*sA!E5VvG=Sd+IUo?nb`E6yJ5ch8_owb7NboQh-@M6|P@E&}`KYk+$Kr6xEk>6l0Q z>d5i+_BLvr{hMIBLWp^kBqQ_QA#EeuR)CMs>N|m0;HIDs4wVoP{j*U$tRdBBo8e@q z>HA)ppH1bEZHui{@}Bm%L5$E&o?cYTE_Q@pX)decA?6^vLZb!V>&tlsR_Em%Pg#g! z|He>Lq{Ycj<^Vo(3{FWHCqdo^-j|ka4&w{k@$8Q|ozoH`vR}ZD2TT_4Gy*W|_HlDq ziqetgTbBc`Q#&836E^a_>=38#S7B7~S8`nl0emNWO^&I`GiO6z(L%T5%xs^lkXe4? z5L-0PDa*Onv(tq{hNQRf@b2udi+y6PCoeV`?I+UheT2YoTlAQ(86vo665afo*VF=s z3#W%&G1T_IE=w_hEvLIr^3s{pzUhXxxh{4i0j779hV5LL$Mv$b{ zRd)yNDyDr)%rz$Z-Y{3vYh257GQj})I1R+z0`rCWqAuXtn6*pKu!hS%|F?rrhxH!) zbR0ezBXJj~R{&VvA>kan@=OyZ^1Ti$$4-v|=xQS{ex%tHDc)B{F2Ihn*yI!`=~P#iXq6Z}zOPb?A-qLt zjFJY-=?Ipz{!S&b{A@S}H5Q(4cfeZzTA$a)80qrPdEg^Uy`+7GQrpMOVsb2?TP92;n! zW)suHHbgGFv-Awsr7d1edaNA8vHnAmZ21=1J@cRLhVe29Wpkdo&z9W5mgxs%gqueA zdW&1#5x%dGCg3o{bG>GrQW>~SW#vpE3DcvWmm$LU?+x>WXVL;=hYH;u^PhCX#lI15 z17D(3%Gm}fYrOjg?LE~f{j=>ws3DW@ef?|;GHg}LmMsb4kl*pU~fpTQg! z$t6w!fBVtt<8AS}swOX8GHd(o1-Z%tf-rwvO?sITjSWdCGNS2kn)hW)6Wh=4i%voD zj!mM~nV~goy)JRd=el{cme zTAU)DX-}eb`ZAvx3%v`yQ?1h;r_j+YO(NT&9gd~d|8XWI7gjszsCb`E+;7=(KyKI=-O=AOv5Ksuw&EkI0w14s@LNzsvh%2Hjvy zl6_t5P=mhaVRz^WEj^Ix4Um1$SDZ^)knW^Ye`*_aEq)y!hdS{qM!88f>N8HQogP-H zX_IM`zACTqN^~R@E$r|-@5(amFPhQ4*am%)7O}J=lB}^N;5=R+`h)x$>(vRK$3~c6 zb2e~P+ZQdEvMYI+Rw#s~N;8RNxJHR(0d4d0hNL3=!5wjx954CVYXb-mh#@QvLI?ZC zM`THa_5n?l%E!prQPwt1V8N`x^){ynoq((FWfq3=frzviZ0zQIARQ7AJlkY-d7JY7IAYA%pb&tlj;TVoF$u(tJGw$?S5LY-+N$r?SEoIaxzpU$}p3PpG)+=2$&U*8>aRR{rHu4G3}f2w{( z|1?6vTg2G-b~G*2Z~Q75{#BH{*I#p_AZ7z^W&o4tLW&@>d;tGqOEe&`>- z7}p&tJBH+~LsC%L)_)5TgmH(-G6%d};V&>eCV5|h4Zd4YFdJDTMNNbZ#w{Z0Q`HWrXWEpIPHSMl_H-ov`P#qiB0AiQNLfHR_- zTA|Ub^HIibX~&a7RmMHPb0{1Rqg{i#WEYLG&dP+TW^MrJ93%uB!;f`!H z$M{hR_>FpPXHq#@63>)hxx*8((XW3=nvBOC9Ko@t$nxk2pZ%AS>}Pw8vfJ%?S8g#{ z`M{bY$erN(3VY`RHNvghX`Cb>z&Css+*1R$IYx38`$=WBKl#3PzZjmn!|S^w6bf}# zqxSKVIKY=k4n*wZ40V^F)z%TCFZ1fuFO2+2twHptQj<5e2hOh>bWAqCrN^2e)KeIc54lMg*xgJwgWBZ`5j`=n26VQVe2=Iw z9Twb@EJvoK3BK$yuaDFm@+C!@-zk=bZdJ4B#m(C{Hbss;_&XnPrlBaiG#}BT3(P+H zj9(#6$ZsK@=ua|5tV8I(y>a%ho<@KyIeG#VGSl0BOeA?^Rh2tiB56aOoqm_$J{*0b zyvr0Q7rV%t(-t3N2XwFXYF&EkKX%b=gI^E^Dd0CIxm8mL$E}4BJ}$|lox62(x`8wg zq{@GOHjtm1bi~;XHhf#qy0|225e`!o>JZO%c1i~uz&5l@q$U^7Zgqj)x0)Wnp`E(W zkxn8j)xGBqbvJx8r~8Q$sNa3&elIQ{>rFnJW0H15KCM@`_-x*65fbBOQTzm>()NKZ zmUx11;gHD`M`fDwIXGjZp0@HZ@vN47^mH)BDsjLS+j8joGiRu(<08x7MP&dm| zS|XA02s;;}HOMZ-Ftl@|XtE)j>b_7V^9x}%H?4w;Ayps(pupOl)GrXpjkC?MG z&8|G3Kx$?wMx%d?)u_#c7(M~00Y=O!YV{Y5xL(VNE8q%MJeU0(cE}b-crvWlXb&d9 zJJ-giNv`#-+>Pn$k(ypX8+-bf_^ax8<~{I|TT z{j#bAWAr_4$8FjOF$?dlf7ElV?@DQ&LwEF+uJw4sjJwqSQwp8W2&mG~o zDLZl=MhI~~+%~cW@nsFzn17Z6t=osjD+48H&0(1}JR#M%WygQ z!u{IAhh=Ajv2zWII|ftA;%$s3dSrVHe$-cO2A*=ybp>w3DK@&f;q^z7T&wVeUU`e`%5`k_?D*O0doh`(ii_ zFR50&EQ^(ErJ{NckHdWQtI}%31W+8TaqN#xF`l_k{oJd0FXlLb(7NGf{*qy-Qi`R& zi^p-xPFe(;HLA78VVkhFlTj7Pyj#DjpE|SICI|FDaU)^AuHi?ZF*W=g;%saKLLh!o zQ#%!c$2Fl zrrH^y&}ZM%{egwg<#2PU_H`EaWzwNqJwN{_P_Oau^Ij`bM*FkI8@t-!qsxRLP9aA^ zK-v-UbT7GdVB3N)q;2n%Q61g7I+0r4Cl1Lh4X6|2AP@V5BCAfy(684R;Y+~Dyd`RZ zeg2}r6413R5ZkC#LSRmweu?S*p4DZNE_lUrn_zYcU1sL8=~5kUd^B-Sda8wY4>6>1 z$1|Fl>CF=IA-~ARF93r{k%2&3x{-a6OE7vIL)<|0(d1oamiEbxX2`Z7)inC*buFG88B8zWCO$ZY)k*c{S2lSkg?! z2&#j)jche}-~u2`gquMpsgCD9>_d*pA)&pH!``8b$Jn~aGP5^;>3Idi8L$MD7=J&J zpk2n9CaKw)6vQXVEjSo6zR=I7%-Egcq_LnA%T6iN0*I~!3Q-u+DeH?&u22w-@N&sX zGxzU|&JGxg>j(vRNUAd?mpdF@qNSA->dwnECZS!iy}}0Jov{8MM0)?ggJ(v-ecj?s}#_uIt@97{X%6~(Sle#vC3f4I13QQdRI4pLxr$5G0vkV*I?)1`M)~G_Smu5+q236KQRc%^8}4&VJPTC+f;Z0T z6t&L+N`nm(-Z>S@XA*enS=S&jFULX zYMw8FwKGyC%YJ=vA$C~tVURw&OuJX5u)qz;Ey3>MYpTH7D0O&=@DSXs-^UtWoW-DS zmU~5+?C|KGwlD2nsPk~RYa0u`Xcei~#jidQW(|rnoEfh_%%1}I1mGiVPB|CZeYj{{ zYqCL1(6gIzZ;Xa^*JK;gU_!Ptv0zoScSO~XyH)Qtv6AGj|7;9%FcFHmhwb7)ssrGX ztzuf*Vh|iTBIuV!_lWX2`L)Q@hQ6^k%S4y$@SVVWMyODkVyPDoQ;0WHZ>zL>(6N9Gi4G>k!tp5NDnXw@J1PhQrB7-5KQLXM)bL*bFUf%Y+M> z;xh@jq)MTOhR-+Ka^?Nbv2m4I z;z^)SelmFDx0xR-88j&*hkIg+Y6273SqyicZ?}9>6WF(JcE8rfv1$xD_(JL9{}Kw0 zBDL^^?hG$a3JRYeqW>z$;1OvLc-?Mz5Rsi#gxIoT%1vQd}UFP2-b zQi5}3P;v*5X|qf|P#1}^T=&@mn$)&|%$iN`v6??#VScy_nr<3CyssrbaK$+yrAVDo z%%!4SvrKkC3}(x{aDJ6OOluSk__loFC0Mx>WpV_IDM=oRrzC6-bl^muqB+P``yja8uYypCu$ z$+WPU+jNB?ThB(jMZcJ}MPNBxV5~FJ8?KEc)bRBR3x@cm6?DsOPt4Ci{J!`7R79!D zAGAT9?(gLFh_|ooUzQpx`S;fugE7x0=^qJSdgw{MUMt@+j4@+IQ4_1O0UuO zp&A+wXvYt^oK7jT#Go}dAc&5B{hLzZj6C3ffM4wu;~Dn^bu?2{1Qg52S0x(9cnU=o zKruSpXE<}?_s_xQC-0@9aiGFfJ^`49@NrXVkYyy#C9o+*(W4|`^jE6*$}bJ-w?le} z$UI4sxOeI|AgzP@rs=A;vId?~uHB2yq%%W8%Ird;+?}ZW$_TODW^ z)%N;Y8|!|<8g(R4D+N?MuomVL6nnmEt6?%s^biYzJ3V-Qw8XYW7wXsVC)Zw(npx%( zr`RCYVULj5C{EA)=Y}|)%-0(O;GcQmb`A*cX%Y>u_zE7O1wub_(rzrm^F05#v)p*D zM)@6J@2^UaD6$a*<=FlGDzAXvjfp@A-r1*-TcTSGkXD^=fzF}0HMWOoLo~T#LGTwTfd&=(-07dqLJ0lR|xADzRLX!R~R6 zC&+4OcPkO%?$tr>;#0qKn&fM(>e}SW#-e7QDua;h-fc^y9#Lkg7SZcHk06UUniaJ= zhj>c)*FO}d``;Ees?$%-xV{!RUO*t?`~(1L|M?Qh9oW~d=a->V7G&ZbUMX#pp;4LP z488XTkx{abDzNMktyHtf?Szo+W0So_jbco-tk8(N3mO`_8WV(C!+Qc!{7Vd4yEXse zl1z5X#XFsNivBr%y(Cvp4|!UVzu<+0`oenwZzL2cn906Cl6h@!L76cE7VaK;s82LDKvo+K60rai8Vx6i{oYjj3*G{*mB9KGQ6j&|`= zi&AiG<X80euMDl$l2@k@e(`>z#YRd>yjlW*E>(8(WRb5cLidNbL`cB zcC}#U*pa}e=QWWrq7mZlp)T9>s(1I=`3c(9hl5M*PtWDSl!{a%-d{_5U;N87sd}Ft zuOC8_>7EAFkf&0$L&SCoL3JYsk-l;n_RZ}se|v8zkH8H6IB@moep}(1VxgFHjBj zC-Luh;PbX*t{oZfpc~5qp@2+c*_&alI0M;X@fI!&Uv zkLwj-5iz`R4KGqe-Twp;-f`S>T%(11W`+56T4&L093kAHk#e3%msT-rP@L)T!T@XJq4rs~>&5hOxc3lAH2N#gR*kv@M>-xOnsz$Xr0KV^Z z?NF~nd>mf3@4UD_hjD~)!hmddu+1<{+YSd;ecP0J81`*Dqo8@BPY((;hBc-=irwBN znAc#>y#wl$ssoxDwF}I4e|*`z{8t4R(Oy>7>BAH3k4NUwD!m+6<>vZ8A^jE|ueje? zgxpQ+Um{E;=Xeb-E-%inVvA6(U&B3mguX;T{#<}s_>wlMC=LgrnzmM#Q z2wv~A4b}@wwysZTQ<12vGJ-t9K;CV7*+}!zM|mN>gKW!Q)Ukmqz&_G<5ut9$KV1x~ zl(U3qrP;5?d}eg&aG-|zJ{DbxfC^1So!ShVO>(6Ke{$8N>dp|v^zrAf!gK;t&nSKg zHbp;}_v>w;CHO=76|QcDM(}?1oGYQ`Z6;IQzu6`+Zm37Fm;X>PTSI#S&BF>}Tj0Di zf5+9J?ZUrhw8(bmbODgS-4k0Pd-iu8zPCoY>UZ3P@_f%xaOlB)@dNUWvT153*226oTnzuM+Ai~QjxV@+cR$f7Aq7=0|Vj$A}9qNz$Nfg9dshsq=a7+ z8#6VrQJt94p-j*JhFOkKD=y2k2j?dOhzc&tJ78L)`QT3NhzLxr@JM?HG{)o>6=~cw z0O`f#$jsm_K7Fzm7p$OsvU_@dOu~X)=F6+GF>9K^&8{$OlFLF{s``lxejvQ~iTXPO;#f+mXw>d>Fg1g6qbwgH-t#n9(IP zr^e-*u>5a=ld})^4ao6OGQt@TG+0<9_+acS39Ay_SVjGho!BtnzPR zdqdg`j|m+kd9INDN@$d_AxwRu)^7=YZ=qA+*me6!4Qrm%KqnbH zM|h;y+o#78)#X%_es^1z=z(iT2$i+a9*E(<*)PtqK>4zV@$@wFT7zu&Pe6uD_vElK z9KN9^1nB!YwZ~-apXj=Bs}2{Mo-5h&z!8a6eF%`4d*OsiIvs6y2PsjX60CxI26hSNB3cal6Vb>sN5MGCGAQRnmd*AF?fsu} z!=t3J{9SUxQ+d2S+W|W!q*IFvVI>!z&v}DcD-7(3Y>9mSyr+U`QKFRQ)^)}>ZI_~YKWR*~3lJ2<_njDwb3b|Cf7n?4ycnD? z0B-TqgdE?Xxpt%tkG-6~pM2q?__CBHeOgI$>M`h3m_EG1@209;%4NeZ4C)~i$HVe0 z3<@HaxO}9HH_=XXs7VUidIZWK5 zJd8boz#rQS-sr)WW8c4IVt#r?^lm6dM$`bmTa(D(dTU_|Ms*v$qC4of-@lbqy3waY z8ee(2yWJbujo7k(?E&o8E;PUgBb}EdOZDPiHBZ3w1w{WTs0rMe!MjcRCBg)9-S7;O zm&J-vk*&4LJN~Ikz0Z9o+Wv7$dO)xVIe@(sCCsPvG%+1hfb@uL8rvgQ8|{Q{8v8r0 z015C3Zyf!{Gpz#(kZtqhtz89EtBuFoiR+g0uf0Pa$VcE^*TUl+t0aXLt^uuSO$9ht z20%?F8)a%}tQU|a4Zma7-5=~d+Kc=GXY51$eRwCC8>?hNqYii3k23wy^+)R$o^IX+ z@)GABx-yx25X@P#9uT@n)IOqE)E+L>$nMV+^APFsXOkU-;xqRrd6k-cB(tO7Y3$$Z zB&MDn?0?!6XcjY^%>59RR&|&wAYBg+5?fQOl8@oEvXuo}jPtYb7GYi~hM7$b>W_{K zV=GJNrx5N1g?{~BgO~-f>`{$&h?Ph*ruS}FxOEU9FQ)+8qBtwNNN(k`4$yA@pgQwy zB8>yAl3;R63eQNq9D{%KCohjEiGc-fSv+gx^X>mR!qu+u`& zLt??b2Gm;MXBSVaaz*AAP0p|PTcc(d#Ff66=iZPH-N5^MypDi6bZH&pbXi>o_t@TM zaJ?QFw*SrxGmHriE=>r6I*9ej^~D9uusZ_2Tln^?hp_Ziknp zun#QIa2zy9sFXDsd?CTJLN2Z!=g#o`!V3*LLFlVdRO!G~oB$1t^#1o_3YlNv=q}SF zL{-1Y8rk?>6XYDZf^~j^?CDorLt1lXA%%QbkW zlhO<_7_NN5M%jkcG5x67I;LKIr?T#G5|C~Uq*t@U66WzrTc8)^ zvAvO~jkY!;`t&2aXWkNz*xeEGR~Y8*>ci@uMky9Xy7O%CSRBBXZ44ZKw}rUQ6*Jrj zCd-jrl@#)g+wl+@o+qanE7ai~PU!gA{Q=*%Qz5qt9c=ek!UO9b^9;9LXMF|_@QJ-f zhU|X-d0%SDWWW)5%A?s>9~Ho&83eznqL z^f@}h80y3CNaorRb^5K|iP^bnpYuW$HL5vMIgY>S5)Uzm%Y6yO&ex2J&%_?I!~NvWQX5Fy}XbpG)jH-URabUq`rwQ5w?P zak!>CkWD-PdcS5tZmWYNmr6T7n_SljXYaK8PeD3ZK4ft`1OA(nzgwOLF)B|eR6UFq z-^J&qKx?MnPMV~6=AX~+fDyyCNDk;0$ER|15H@Y!3ur)Bq1P=^DLzJ7uaV&Q0mj&? z+UyKxnUY{+mo!Hn?&B9EO;;f$kw?E8?Bkc?6JVdPOwp>Q-2I`9yHC9Y?|?Nwh7Epn zMaj4p;Ncrp^vgUQY)d?n`J>H4pqBPi9ewnX;mx{^b(i+=S76#>sP6;Pa%kz9rwIaP zodj)Q<+dN`R0vI+`~3lu3#ZdFb8(qET(lruzFO8AXlF2J-N(pTQ?PxjwP6*9J7!2yeH~p|7fWf-js`3a>>bTFf`SA$mVb~mOT#VTqjB)vK?D+^k{hQ}98(a=uKZ&n%9vpHq@ zbkcllW5+l~k8=|{+-=$ih|clsnx?^4c)EYPB(NWEjHeARA=ci#TMawFJq0%9&#aA# zpq%5(;Gzm{j|b-)1+hJWW~cDRXjn&Q z(B?Tl;IRduW%$5xUn`Az!;q(4D1m*3`KXkyz$LI9<-|T3ZA?G+Fhm#CC9?+J2+Lzc zWS`{|!7YJizd{Z>=`_1iC0ZUlMG7<^lM{}j)@>7Qj68ivacUI4tYQ7`RmP@f2rrfL zZw5`?y;cwe?ecn0rZu^$-WQTS`S<*kSSj!A>cTYHt@V18liQ-JR8T+i z?Gve>!(prv#nHFJU5sOZvzL2(Te0~@mXc`oFp{Gdo+LYqSVVX-u>lcm$K8rbIpz=l zcjh15-th`n#eYiUo!z3o+lJbNIH?t;_kdsi+eY|!Wn$~^%9Pd_UM$Yt zI`)stOu(!F`NoaQhF?mc8~4QF;1C zM809>$+IVH3($Mk(*p#Rp3VVHp3a>J<7@O)YF#WL_Jm~_v^Xc{nV`Ob3uRJ7T)ya-2+dJO^uCSj9qnf#1)NRj9%>EesQ7K;rk9)kPgmp zX-S)Rn8u$+|KD+LsH^&dF3vn@JqBLiwv_B8xZDPiy9TaC7;w09|GYIqO6Z&(J>JDs5G2QOWZ8k!s z7lSvpIy}=7%LopBG=6ebn;yt$_cgCvG4^#cT@%ACc4M1a`w|68tpBqk&mbi#5x9fz z-A*Zk{f%!N!KF)zQ!=vYd&#)jzq9+$EL^3zrcz3*3PK;1BPD^_1Y0)PM!da*Z#Db$S3p3?n-k;ku!=OqWESHmbe?J^Sz4w=leC z)_KdSu(38O9MHp|VoGp+0&8Gf3()B+86m2g z|GmRY!LLnP7v_83C`Z3|hP^&ip<;$cv+9OelNfK(8XMD5mPj(cNn4m2;o8q?b|V2A zG979!;%NeyqBn(OcQ!d1LbaZlNq(5Y<(9_z$@oTnA&4C*tB6D-LsvfXo+ z>P}$ax7NJ9pNQBq86ebJTXKfU&!3rfI(>eg9G}avKR(l@hITGY4zD%;Dm49} z(?Egr|ClcR@&6ywg_5Sj$~C~1Y>W6mVNg;LjZ%S0jl@zduF&(;G!$X3{|S%cI_`;e znfc60Js$epba;AZ+lPn07y{~_w`=IJF+xN9_stgn>*x4(#e+Za2;^5(GmRc4?3Ayy+@ujUdDA~&5O3hv2A ztE|ycLw`Qt@DA0RC5mOqEYW8>^rD*AaYEeXK7qoe2>nt=y@Q~*FZZgHW%$rBo?nFvA33)YR|duj^^g##bS2L_(PWgxeRz9-)5u z!B9W@{R<1}RBY%$dbp=}C%MjG-yl%Hcc^`}_TJaAHcWG`;Rb25M4>Y9C*|V){ZDGC z4#$>n=s`xh&D~NXWQziFMQ0Q5fF9NDOhn^Dn^MahAln1Zn=N@~m)F{}A$f*sWo?Wg z;N#)+0TTTH8pJY%&A;DI&7aJDaHrqDp7#Z7f$_J@D){kYKvwqkF%k*=(CvT{-nc@G zV=l{q;5;+eDqe@gr23&!FF#95q8r$Q$)kopy}fSd z8t3Q?X;ER8>5SAheO+wP*2xU>Z&TCEzwTX>tTT^%cS|7HKPXY`{9JfI znBS-Ws%Kgq+Bim8p5YqKQw_Q?!(kZ|_5<@JI1g??aLKhgCTx$?tU})(WVO%y25F7? z44YwQ9gl9mLf%!l0l^;(j zO}sodutB#&{mGYUVUZz1{K?-GfmtT>phnmJ3b#|4xK8o!+8Mq_?-HGTlw)F&Gum0Y zo^~1Yn2g)AFvKx-)UbIHpMc6h=sWQr2i*oalI18F}&rGXYtbZuT zVHRWGo~buTnsbGK_AP(R%Z-gAH<@67A}c{2=U`i-&p~_zA3cSlo4bUtkC$kt7Jkw{ zAg=e~sy~_-How0+Mquo3PE4@>4obD&W=b-fBhE69xBip`9)haDGV#xf+!{)pLEQ1B zbMu95gd2uA6b5^hR`FKx6HN89aL)1MA?{N(^0t1%X(jBW+lPr2#GCOIT8xe2nZ%A@ z237X4OmyC$yc{A^YR<@(?f%tacj&mPMQUJEjh=5L^8RE!^H_k#s~FSl2#F(>X0gEH z8m+hR!y(w+DRHLHeFuDJ)#l2P_0A)0veR=4PE$D)cgB!bF_>Ns3Yd>T0LOTs;A>Dh zx*jn?#IJwq)=d$f@3jbOUF{+jslEIlLX^ z65Lgu@f;-Xv~mgbba(C-VzcXj=BKjY=`trwJ_a=Ux=68f_Zs@|u?kXxp`ApZxAd4f ztx!S#9(4sLsC4U86$Zgq5^eII!PGs$G&guvs0mZe!Z2GSX<0>E{*%w;ARq*=~{^U^hjk zrM3bDL*2tq62_Z(2PfyBK{>KwO=NwxTmh4 z`SSk`+g0TAB9!QEfQ>F_^jIgffKJm43TH$8KJF2o!Esj`EOZ+#*|4X9%|Y#spGE{o zx4XYu!fKIdmrl?bn43o}GDPr(Y*+-RPjZm~lyh*vz4HBeeulNd`1-KUvCf#|7^Bd6 zgc{2|kswcik?)#Uv7^WG8xzji8u1M&;ldB*!D`AijC}G%9tZCuxap+L;kO+Q)_jJ=NXRpOaG|fAjIrf_s$m`!B8_wn z>b6=ulFEvZl8YdCP@xw zMe*9Q)GopEEot`cQ?5~@YvqD+%yWGX2@`W7Q%7M<;zr1F#eiU@pLGh7yI1S3fmRWt z>eD^OnJ{0Z`xwVd^%UzBo^!ZI#H(tXihD4K;PAdWqFGldn=kK!cmMm9_tC+6t7hm7 zS;}AVuwD~{NJJJ|8y+zND2Bik_}uO!;xF%L75CsKmG<@`vXv%FKbaD}d5rKxvDHTB z=9?ONy}BTPf?{PLUW?D|luU>gVmpTBY?2&(?MIY z+}V+4scB|OdJ%!YSH#0Oi=toZFHUJF|3RJ;-=BO9QHjOqsXqN2-D>0 zZ1y!s2@N$w9bEMYXBTjcl`ETMwF?*Nk#6(%qn>S!$k(?8rdlmCdHk_U;2*43#{Ktn zKf`H(C*bQ8u2SS2qfrI_=;PlWi+6c}%hR_xv%pBYje0_6Xqm7?GsyD*lr31~Jyrbu z6pvfvi~t=}0>~MrcL@wKY11Ek(2YUaHpun~#zmH|vp-E;ykD^@*iJ1MMOLhB{So(c zp*p51rExjGz+k?9N=bfhK^~w(|3(= z3Opdxsovr%Rj3vVC<=8o4%6*ALf@?@GGE?WU;)yK|lN>TP1uTdqq8vm?vvB?ZJ@hp5h!~mMguBVZm1G z<+}Ybm#L6zXw=fp?~<+;g}Uw~>)cBgUBZ;<-W}=!Y`O>X>^W$tMHbq6pYVUO!~paB z{ff#5HuD8)5{Z;jt-OMo$3FNc6A9*JIP}B_2Eav89LV$og{n~wOP!G3i8`R}PzhV0+w!fzf{Wx`;kwQvw>a*8nUu$dtg?{DYP(b0cBi&&r|s0X zZM#j~sWr82+iq{}!~GL()=E}h@|KmHbN1f9-TF@@$GEshk;Ub?NxEL)A4hP|6a0Mj zumI1X9h!W7Ttl1Wt2x8UDSmU9XRt~9H#hUlvpo4R0X*hyhtN5{#|pPW+L zeJY%ZE{isOg`NiCtN*OVuyZ#sqsu>AuGI&2K9hThp_AqTBhX4%71w4LW{wb6-zySzaZv zzF4=&vuKL4;c3Rd$Ib&ZQwo;#BdP9-- z8Vq24?_ZDbk*;B1en^Iz{_!LKj#12aetc)DO@Q`_QOOg)vZ?y^4ZXYHCh^jHc`cIQ z9$|jkCDDvgX=dxMd7IXTdVj%)hSAy*2(*8$C+-+tEg;Gk-GF#?Ky*1Zhw!7H3+g&Q zP-cv1{m1$}8ebRQ`U+kAySm3VF}d!&0{M~N0LMYG^&G44ne8~nuFbo}Ub>{iVds}> z1>+<5mvLIX9oZJryc*kkn9^pUymif45l-lD>+RzVWhO&3-q(ibTw+my;q~~q5pL6! z3XSn**r$Br6SIv0M~3Ebd8OLKEfQHbOgy37lC|>^0Vuu!t>SMqFXBAw!L@BB1y_<; zR#~>`@Fs4_o456m@O+`n40qvDtQVV}9;rM{LECu_gxY$_6NoMX(FwJ(^zc^xe#tf* zOA*0zvn;D5ctaT0oEQi6o7{EI?FHV?`S#um{ zJ1N{OYrrZnQ>KqCYY$pfSRSKg{I-=o2jE_t2L>;Vv@4mU=M$7vH2Z@0zh z(X~qk@6x)}tS%DHeN#-L&ne`3y?yH0efI>PH2L_m(Xnbg8Phl*Lf$!KEfA;zptO2> z)f_E;Ge13V2TU}}yaqd>>{Yi>l<#UrFCz z3C+^UcBVv^X8eHL$|)YGXQkp@Y>pL--BSHsJf44JjHTii=<`(3?yWMD?Aq;k&u5^O z$K>%4D%$y$?T(N8yI3~=_Z6*C7yrFhX}cfhgl*jpY?B%IVwYjB2HevnS*mlp@GVLe z>Nfc~zE(#dpzBMtdH`hmB$%fjXw$~KiZGVXb&vkcx6LBCJ);+e*+y568OHSK(GQAp zqhD9bT&4O(vd(yeKy1i$6R8~gJNDrM92tyZvLVlyr(LN0@PBMP`v^Sb}Eb zQ;w~Rze3^+D)f|}ugcmPm$;+g2m{L+dCt4H~NS zQ*0g6*VMY+TIKW-^WU@@^HY0vw~yH-%QT6#V!w;F^Y(uG(JT~h%`t^`!n;JY%rb5c z=9ERba*K!bzSYprXj%@oX%t$-i*iYGB^thWoP;Gv@!zXZ-FpxosZR&6L0;j#g&_UI zj-Yx0ZujR{;+Sf?V3AUH`TbM%Il)QSIT*a>C$Rm)tA>YNt$LOr(v1-$DF%lfn49QE z_pDh_de>m52tVH|RxFj1`*T(qq6$T@KlxdEJ!D^L$fp6F%Ek5!aPM9~_ z2;1}=&(0_|k~7hhsyj=d&mhFdz2wTse}1#Ev`{4m6UkaIz)>)F2evjC`ZY^)lHE-g2PIyqYVr){+BRJI+bk5W>H|1Z~sstv4Tu!QPYiTXp2p8OlbzO#L96&tk{SEn2P*9 z`@F3H*f(Z%E8H2~mxFs^{uwz#y{U0^^ z$+NjUC3_47{;$^R))VY_ONW`5CihIdhvnFoltKJcuqaBA+k@V|4NNo6Nct4~eF;~# z$EtLSUI>9PF7B{H0(<}Qi+@wA z3eTbycqK|mXMxfc|7v_TxW~_R*FCQ?h$Ax>r@k-lu}`%=A3RbkOl^7({ZCRY{k-Db z9!U3)b1(BOP2*wisb?<;2v0lW5I!HiCLr&tSQ|7xHkDAe1X^cN&_4Mb*u>Ts0IdT5eyXCxio9g2yv{E=vDBD)~WBIQmuq|MSCWh zsnnwF7jI>n$Fv$Set*>W|N1M^Dbrz;G{$<*BGl+C6<^~JMZJClyS;3IHO)ykLO$aX z<9Qt-iN3XqO!RL6%DqG+dI&j0OEv?0ZI=2PooMZMy+P#=3CyNU=xo0%tZ7K0fotaG zHi(v76lWn;6Rt>o#qtV%I1V9F(-XdGXr#!PwQ2y1eMt5MpL#Ro8x>d|M+x^U zlUrcJmnt}vCo|0DR6HU!NdX*eQ)NUk9+8d#Ue#(bE-x=$v78gZE+=|#0`|mAYurQ5 zv9p{;-4_(&j9*#4vz!l2MzPu<)5MyivK*p(Av`7j@ry9b852r#itwXfFe)oCQl(R5 zfrk8UZ}nE8Pe>%!z?8~u^LUW|?f{Qo_2f&7H15SPzD)h@bsx(53x8yVu@BEX_e)#8 zQ18Iyk3%_30@!Zs4KP!E@@~BM!bBniK<6d)3jGeCS8t5)K&qJK82xLoIvDVWqN`za z=8JL7G4fN#AG=dlzdp}hLom!st$FAGM$@Cc)a4;cHQ^1(7}hlV5-q{lF2p>xR*Vz0 zN>C3@b1Xh%40G?5ctyr3M*5}5q>-QUyfg3qgCcqqseebS^};@?7Mm!?y&ED)l0U+$ zw#R~u^^CE;N3PJ_KV#fn<0qfk;>g|!cDE-i(%zt>-M}WYiYUna28sl8UD0mOa4ZqH z;B0e-%92bHK!UqCWIszjVhXMjd@ek)Jzha8Bob~89tY5d==?ek#v*GJop+sV#BNAQ zbD!;p7zd<>Y4J44XP7gg?aTM};NkbRO^+8-J68F>$ODduj0rin|xm20%^r>v0;nV{4&Vr!Qq@zFVQI%Xa?<* zjMS8>_@kI1_gpIKl@ZrhA0wu z9o|X^?B;cMpP)k`HM2i?nYPR%eUoj(1j=$(Mm*Da$9Tm1`2KbnrX1m89{dvj<6pkw z6UX|GXxH(MY*4l*5IDw@X2t$5@W2w`8T;-d&M$jkS>S>pv0E{>^mmz-uz#dmv&pjK ziASG+d?7F7;(slTAdB0r*V4#Mr5Q77Qt;1Y1@V5Q+-<%;%;ihJ`SuT7>YUZAuh7(^ zm>Tqcit3R#?qlLA_VfD`fATe(+*qi@T*Or5S`4C>h)ZODVqhLR9GxWpCx4eLn>-Ho zPMTY^ApjN}Rx@{I_SWvZ-|@RnwrXJ)C1m{`QRQ-8Ubi1OR*TjJfpy+%<>PmYVzpD2 zn|P&LvPalwV1q-u=&im+O{1sS76F@8v`t34>KqmBLv$d)nB<2hj*P`M<#hJOh2`ld42i9idik)!0zR<&2u&6l?Xl?QoMM;gb-u5mp(W_Nz@>IU zOr0;xaq@|)!yo*LGp!MFNzT1xc>Xk3`*XJKlyI#F6}YM0m7fI(roQ2trJu7nx1c^x ztEGWB|A+&n%2p-bnTDBvECm`gn?l_!O54AZfL^H^g5f(K;BJ3BGpgmz<4%ap4w^9M z6~8bZo~iw}w88=&@ee#T|76E0udJgea^7|bUYej2*c-{Tlw<{ad-|-CZ+zZ7_5M1{ z_)eOrzD}%6?v`C6MR4XqG0APEk#gES!?I_K(xmf{VVs+*^iL9YGE677Xp^6#e$zvO z{@uVZJ5!yXmt}7i65Ud#HbF5podQU{iSEt=)`*T$-hRLJGOUuGhwGt_B>#rK8mBlL z3D}1J9?bH9<)V&*k-E(8+lsN)5ks?|t{1Qm(o+@);mL#Wey!V0wfZ%JsEU^R*!vdh z;bPI_BjF71B*zYtRGsD2t4UXu==X@$MK4V}A`%H!2OCF=ul&>-B&&4%BT~(amHnab zSAQ~DPh`>e`Po1nn#8hL@v zs641MsBN`m+vKjVMYUB($-5Yi)KrBn4(WCq(SmK0WtM7_X>OAO069X$cr-0(IK}vM zN@JUV$cVQQ58a_Rw<2qZ0N89qB zOhACR_Kau0^huO{y|f#E0)^EQOU9ci@OPmwW4m{O{)Ju{V*8zcDMck(kHPq9DPobW z$yeWcGE}6r2H?^ImS3#((qt{oY~PBAfkq-v0J$gKTqTM3fB3py5Zu5+Cgt8ETyUhDy3dxhBEu0RsqdiE<2tmow@4 z1C&+zc>KPnZ&>P8#I(V(!8(I{y5H9O^so!`V_19ozOui?PH-_0ARhSXORBd<@a?IhD-D}d^Al#(bCR$SJp?H{NCR=Bldj>njuus*hiMRO$)h2~?;+!Gg z+Q!=_2X%heat&u%{N+PCDSGDL(l0qXr2S`7OS*6mEgjEwFBXxiF#FC#n)`i^(Iofz z^ZrXV=L5G&Mm=T@o_np`G0dgeQL+s6$fw{7 zBjhuvSDp;PWhsX{K|gQ37e+svZMt+%msI=IE8P1q&<9i|kqV8j!ouV7(r9EjHV23d zH~WbVqgq%LlC8f!zeI9|SN*zNo5(Kv^y8T4kp4RiTY+z>F`h#rD&UZ5h*hVpOhI-^ zt!R8ipUe~N`Q;b%1RLTl(WU%Bv2cpz8^|NtD<14C&ebUfx+J*#0F2Bttx>LsH^}w$ z^9wbS&P>juR3k6vD^aaeAEGm#CwT?=2sK}BUo*`q2oB6E3W~N!HG=VFm}UC}cnjAf zTz!FIzeV)I+z|EX|Alz*VOC&{yY*0JM6;(!{k}qoH5$Z^H8QNk1fWd(8VgmJMZ-SF zJ?(I6m7il8LN;1!m#Fy7^V-4BXZW@f7Oo8yjgjy~o6_6LA?x+_J?aTnrp>4tUz1`( zt%-k_Y=e7Xm0H^C5;G{EOInsUOTA3JP3nk{Rs+)|T)0Yy>+y~HK2))BEu&sKhIJPW z^y})y#ISQf(@$v+3G)WAi9MRbJ3|b9`gvVr`9=je>b$IR8K&rJo~ z>qxBK?)$lQ^Za-78r2nEnej8VQz*r@QCg)U()I8oR|)-i-{?G^3~m3MGnV2kYX@C>iR zK?vphzg6ZiwS9E6FlGmXU7HKh^byo)|6FXR{!599ZRfwif*YSWWnewt+kd)1pzHJr zj#50_Qmf-%VV>_=Bc5-k=C9uEFm2GQlJ&7G5(T*|3R=SnwcMfKEgs*w2y#g-&6pEG zdVHVZT)dFQ=f2(K`2R3I_^H!gI(<9|2GA#cyMxz1`1=XTE}LD%bPnjkx$fEjVd(zR z{qwZ)PR}6-ubycp#{2e%O%B1;5y2(;gD|5jHuO%^8pZz1n=Rb@G#YdlC zm&TpJFe}ofye}5z=5SM_k9jr5RJe5rDb~YU%cGDTG0u00Hy+co<|i#tH7bV0GgAz6 z*~a=foYFkQYvjsI0OGA~yH@>|+#l;1xLVLY5oaIhMFQJg^yvF@wY z^dp0Tnykuxm%29y6D_z1#+lIXAq_k*1esf*e5XC1SakU*u=sU#2)2eR7&M0q3PU`- z`k-Ir=XF5k=X$_m0=S2HhML0_*$^G6R@~rU-z(H8*48KvdcE4mf0byjGQ``A3fwL7 zEyo+b$_so(E1>mF;nFQB2N7OoE0Wv~LQB7OMgw0R0%*2_*OO&mItR0SyQ@u1Z8S$m z(w`j{5FmLU*ft=hl`N0D`~cH{1ota25~9BXfB9GyVO^VIyLH9e%(9J%(N3^W%<;BHQAxk(IG z$z)m{?w4t37rTVyTaO4-D$e$?PIAk@{D}c+HuVZb;Z}7BqWpW8M#Oxg!Mtl?*Ew}+N{j%SsW}QAU=*Uu=&}<^IzYVVzXKUSnk~`?q9P!tOIZI; zv-S}9Be!<7Nq|Fn*p>$@L|I8R7??T|LcMSw?X&N^kZ>*A+!3HpUuR=69cgG1t@9@E$O{KaF!LG*jsC4udWYz-M^-~eKFx`qCYQ*#qSQq&QxkTtj? z@J|G_luD&Il50(~Is_M_5_}B<9?AJ>Pbd?jq&h?=?UIcFJB&SoLGEJh!W>n`gql@y zyaO*NU^tgF^qXZ0feCic6TF0=YSl~a^Wuja>6L%Q5%d_u1=tk28H(WQf9vJ43(S&T z-BP^kCp;C_C8u0X|Cpck1>Rqf649PaZO%f7{KrZ?PW`&Z7Zqomd+jhJSNk{f^Hi## z+mx9wt-anKdcJ2k#uIGepJeLS$^DbIX_si4#W5YWN%$2_(rpr3q&S9P@7tt5^sWzS z`xGM8o5aE`YQX1B(+u08m(Vup@36+8Az4M^yc5g|lw<`>QdoyO#1F1LLK(LbjiKIA z&sQij4Uf@iSJbQWm247PMTHu=g!eGCsy~0M(_lKF+_%Yx`-gf9_XGi-zb5!%HXPE* z#c8($qLZM`(A*n2#!4B;NMwb2DwCLeI7AJqyTu1N&+v>BD3{>nY>M=E2*5v*tP?zw z+@k%VkAFOZpNG5VxaPRPu6!HU^b-ojk}Qq$|B!nzAvD21BMifQ-6XqzmiLCsKw-WGLuoocU3)HQgkdZ}1~qsq;l}(TEtj z4dG!CF#OAiFak)g!Y|wz!X+cjPizAHro;&4lVMhyP>^@~Fg=?I*c{0*EX{ehw$GMt zCto;4waC_c`R~*_l<3wx*)FPFZJu^r0j3ZN4ffHD9wfWAxB8tvMIXcuMk^8s%hxj=*1&qM1r9}t#UD#1NY zDR|xb&=JVd2>xkNZc{98d<6!YK~SPqQ!1&`ERRLAgY;Mw;9F2fNzxSam8Y=okoMR` z1L`EH9r6@OX0b;cQ{j%Bx^0W;mJ)PcI15BB;oBwJo!qm^^8iH)Wr~3UA$9o0@16(- zVV?Sh_0eo{lI_`smMLQG)k%dpg2F{P*QoWe(wxF1>a_ZOT9P_qQp+ka6PU`329trW z=X{^Ke@ZfU?O}n8$}uX$f&&7!=t;KmH4G{&iZj!EqG%3VBr1#zu}0ZDR}iZo80?>j zW6i62;oMo|ospf8R2Xs#@{0Pll^F#3H~OkHw5fnmGgDArn&ky~ zm%C0#;JwGVHmU96#VRE#>IF})KNr{*jVsNKee^;h} z{#_?2(;pFVOIhL+4SpQ+e*T+KFJ!1nMnNMO_;~>uZe^!gPmjS0mzjpPof(z?VTfku zi0JpN4lj-`ORa?Qeaa^a1dcDZMkr0+xkago^GsmkIjB|#^QbZ?GUJw=9ZdGJDq5!C z9{6!E%{5332&h%1n+JHO+V*ox)w4~xqx@X!5L2!Q@~_lLt&4K`yGaZZ44e@_OA@bQ zQ#dfqe&;gFRHkwEopDvH#WD%=sPyHTA&x{toTpuIw~8awGCMK{;xCZA z7Nr_!-=lv96=^oh`IlE~cvUjM%@nU!q(@?Hh-$4v{D(2;Fx&?J^N;s%L!3wOqgz70 z4gN(kR5;JKhS-4aI7b9E?*}&U&498WJwFcKERRntrj@cq$u5OLZ=6$XV}NmGd8Yel z(C6XaU=DGP@9KDaNQ-;m9G3+B44a@Y_qkTnASDa4+Xunqw&E4g$-O>J^M;Ubq~6ar z66?sRl42iom-9T`_LE6`=Rv63Gc?hScu5T`!%40W#h6lS04RYC?2?1 zC&+4Q(*h6e_3EHC?Dd|Tf4}XB^ae?^V~bI$^?189(HOVUmt-r)mY>%i(mPo%txbh> zky$X!Ce-8IZcV&RO)5 zyhnYXFC!yNL<(yYuk2rbgNkiPsZ@(nW|Y*j!bT$o_mfz8^{z>p?A;<8U6SNYsv+F@ z;gD*Pul>6u$Qkd%BtfFp{mnROh5jDb1?4)75mh*<1?dhJ7}MnSc6c5T5i8^mQvLs- z?OA0+`nD)or{nK*O4}y52ZP>!EmD^WeFH&)n1exmnxAiar)8FKuGD*{YwGPZaaD>< z^4?`#d`lEcgAviG#m8qVO)5=2N?;Cr_L9&i%;(@b)kYupAYUI#w09r#Ct?T?1^}}F z6UVGLvjLGUDwG#s|Ad%hl<5Rte(Cw<^c>N8V$lX2=$&hx>l5Hg_!{YmuLW3Yn8$(S zRh;?z8sI<7C*0s0^+OE+zKJ+5lyd8w;!QfbPE)F&-y2|QlPF#I3b)3xM2Guw&brm} z4et9@#w4+NW~N?Q8}Aa`7!#}-|8z9rBX>vZ-Y-lmh&CDE=#HEvdvtS*x|6gBTq zN_MF^+7O#Hi01%=1Dp^U@r!cEM6^QrT<#MYsh3xLW1i#|NOo|JWtyWpaQE$8vy4Xo z(_Z(nY_lg>Yn2c#V#85xJl2EV?w)Ri25*r(lLTdt36M!vIm` z7wReFeDbxVm)X9X$bIY43I$Hs9jgLcw)^M|pmXFYt$MS|d2yFtMQZW6(G`or>=e`+ z%@`;4~DD@KDDIhYO$4!%~(6(5I@RdjYG#d6A_d9I;+hCS$k>j(CDM~&4 zzHc{kT(b+=CBeW0+XBLjVj6X{st`q3uPkqv(;ZOo@A}C42zRh|pz9=GA5W;idoWbB z-~hWL;%hEZcL;Rz(d{Re zSIG%YkR9n3!1K1y4^N{ksMp#(P6-BPr*y;y2$UJ^chjg@0pwZ5|G5DMd7!VrQ@s67%Qu~8AK)igBzyjG zj@zdYJ&)(TYqP}i3BDT(#B=V|9F1}Iuhc0C2WA%ulMof8R!m^ZCrWdskHj`uW6dZg z)K1NM+&tZ)5$_R{;{?zWo;=??B-IJ=n-H?d&rRv&gYNfJ5iO0;y}u}QAbf-C(ySA# z63uhnW8LJ+Rog_%lMKULbDZEEP|A@4vh!@>OiCCy2l3f1vF zN??4wmu8)7XqmiDj&;%$S0A%?U8)W31&m--M7>xUQDm!+9s4lCE7P50EX}iuZ;@xvwRo*j)C*dw`Z$M5pnqYFp=OS6Ce%}bkJekK74)J^&lZeU7I~|3 z*sltSRqys~Anep^lp2%5z{c$K$H(>o@6g2_jE`S9szXMRc(+nzyBN(3)!G_~a9d8% z5I6M<@lGkoUTqamWC8bRNa*uj@;j*4BKTAO3%5$FNtkH7#Lu_!ktEFnbI;99 z_@%R-aCLZmF`|`QLg=AIO0;d0+#XG{DxlLKKh&>YHr?>){uyy~K&RAGPb*)s-8EX8 zcZA(4$uyf`Bf+XwXi{Jg*C&Xj|4VOrI?rZ?bCww>BVJ~iJw&HfBGWU);vU)~1W2AF zQ7q)%XP6NO>rjeO*<%oN{nJI0YLac7y+G>=j&#=;V?^B3b&Lz`?f1c-J~FLzx7<6G!aLCfQ6l~%ZYg0llU^$;EizwDw{ zpEa?8jW`xJz=zs4xk97YH^skA0snZLB&`aGLhiBBJeVi2lhVW92k0aG`BmhaF3feDA{BR?Ls?)t!q@nY>=_} zCay_|zA5g9OMOBuN&{5}yR3X8Wkxank!3;N)Qr!oHCChC&b2kx#z15XV1fojppI+k zkyQjd>mcu9zny-9%0-81ifw{*8Z?sV^K0MCJ4A2xTr-SgE{13(yW|tK#fR6St(xzJ zh;s_5PK;uCUiEuaCiMlb0guvXH);>F%(itZ~vHc zduCpJ6TPq@FHlITRzhiZ3DJ%?Lf$0|0yWFH2HFP^l5pC`i?u^~4G35!+oYa-;hG^l zv5txKfb%r)eXfKZ&`B+~y$c}=v7y|iTxmXhT!oVAmD`zUY}M9(EPy-n!{h= z_c8AwXH$i^wushGIOZ7o(XbEEA%mR9)}QM-q52qWh0madX)49@dmw!S4Z}d(Cge}V z6Rd`qxv9%NNnemuJUXzcSvAUze_)N)E5zUTf|_9IgK~V0a~bVymGHz_ls6(EFuO!~ zN`Q2-k7Xm+-y8w&5$ydjbBT?5qF;LR>=Ij=rB__3fqX}4a0|c02z}uY&o0F)*(t%O zq(gO%$st8-O!qa%^rPzuE!0n}ZGc|2#yIO{-(oiwL9LH*Fe@5}Q_iALe16?~@Slhv zgK|g6PXqCG+`~4BC2Bh~Kd;`XZQ4>LgnQ3FC-_3`!R}Xhb7WWes7F(r|6S5=fB~K* zhe5~r;Rl`e;qCP{c#foMON+5m=u-^DtYWA$UD4zT`Xr`n)#?L(s+GwZ1Xm^{I!$~F zV&f6+eEom(pk?vp?rCx^#im$$?^=a^|FVy7?|Sd@Q_Um1N*y$^_sZ7aBa^M1qSk7B zSrZ*P$Czfp4vsIT%^@Mp(W(PseY^GhhzbNSa#bJO>bc4_%4 zhZy0W_lNvDdUk~ku{k2jj20(%Zr5`~x&gcyF6?(Hx}r-g&&+^cWTSoCzi&t&gU~ML zP@_tW%p$4#u+CeCLV>l}#Ddm{lxD@Sm=4f!FiU>V<5W_MH23zY#`wyJE4=vpfvxjp zTW)rGbm`1Yws}pQOrT8+>~o38{|?KLi&6*1C&jup9>O1Dqc0rD_czmwXV5CSNFUMp z5bxhCvNPV{k0*o&yfWM}A|uvGWJg$c&^no)YSSev$@^_xt3+o|rVbuRzP3f;j1=26 z_-mC?hTVh^jNj)iLqNa#`q&bsevbj49OEBY&*FHDik74h=hlQ~VT;HXiQbcSF6GF{ z513c$MCodd$)GyT0?v&~(Lw03v}dp$%j0a(0KYt;(@?N0QQJJBecLqZo-HBbVw-&E z06)i=gG=82AR+(CrdWPaqiiMmyrRqfy-QL9FrN&+V4E9kur|EEJbMJ_C(u{#p6~Us z^|7c9>6C%BOqUxI>Vx<@_J4ds>_H}PuqW6kJIoU#BO-{5?Oq4k-y`XiptE^ccVTU;o^^~Tnp=lUoB~T0$96Z^F7ymG!U0+5`FtIl{zmU$>rTMkT*+UOORDeXC9IL z-lSTaqRX!`MZXVZJjnp(x5+B@(*@p8r(sqZL=p_-34r~kxg^*j9!W39sYtcL2EtCF zi}N_JeXVT|>=Q(~nP&3!IU@A_Q3Rzd(68L1PcdBr?tkDPD^=3W>N0gIfMOnc*PZ&q zIxn4GnMx?Tv6^NgIYPM}0rO;x1|FgI#ENY-st4$1@h}fCF42WKAw2W+snjhp(a!ZK zG-(0wr8+y1f6V>=n4&mDV|i?oUDo+Mp(Rg*qx{h&CX;K#w7%Tu7g4RY#lW&ovRxCW z%ur&S;NXn-Mj=NZRr%jmJ6O>3{~ixb|C@P^&UP`(TV1*?8n(AxZ?)rUT_umPTh}nb z2fen=vd3IKe3?&qUHeVDPJIFDrkj>LOzik2GKy_7#Yr3v=!lsp(^=xCl*zLkc2^~w zp1j^ZyGt@P#&)g(0)u%3_#hxwB_SZ(V6CuN<)T`^dOhGHTG~Sv#>9DVo{KZ7w9k*R zPf%@pAxwx!4X$>scdz!fD2Yu7jB64y%jW)3>3~Cgs>5<&)KpaR3+mNjXCIqK?o0(g6(2$?@10pUF@*GiY3=s<&hiU9EWw{rN)d~dqu`fJ@+++F14KpFU*N3VW+N3j$^Q_s2o1bqH{Q?WR}0$1B1Y_+`k-NwL|^Z;U>vP<9tu&P+9lfm&<}2 zDHqt{ZNv3>#~md`VfONl7d$h=vc{~6;9`$#LaItOJ-0cmi?2u49F1e{6|GAEzqr^9 zZx$43iHxfUNh<+<(%SiafA8RJ(L?>G7Y^{N)2dQNxG}#Zn#mT?O^A1!g|p2baNgm- zKgGHxseRH=AIOHE=QS@>D@!22V-vU|)s3rd5*!3T6irpk9({h5cgz}J8S&_QsBwPX zPuAsnCPiYVRY@@4y%=+lVq}n?CS%#}X6d%!R;j7QDy&f!V=cLPn;C*bRO$g< z>4rv`^P`_D7^f-K(hZ4rxE2g^)i@e7P+E8v4YF_9?NZ19|B$Oon)$EY|Lk;1-4d@M zN0^Tvb8Pu%J>v--ED}#~Yg8hv65VX0ADR4{A@19Bi+o^DmoQlS_n~L`Q8$Z~@Fxmw zEGx z>)RVT9hqDhT|;%qgDQkw?^WqzSy*FMCG5~q>%Pm*zMD=C^-1{wN|pWVF`x9Cu!zku z22AUe!yH;vns0D#omx6QSN!xZiuY>4_?LBEewpGWd0HcmPuoJ{3qP>80~W_O{yaO@ zp^a#vGz28j7E|L`n;J(?Aj;oIvF{U3B~(!5{VhFZQu<;8f&^h}8m@+W$WPmseK_;rCj&ME+bAp(a^qGL~5j zX;{Wx6qXweZBx8=JrR;z{}IV9@ejri`I1((C&XSE`@p+>k4ur4C}+I05EK$N`pT5Y z$o4Z@EU3tl6(QIpcHt+ZsmsKF15}m)xQ-}@E-;-f6ZMatLojb+7XFpS+EQGCBsU)Z z@AfLy+C+8@A0yfCyaHpPBK%XK8tqCBNrgbo5^E-e0m=o2jUi6q;%=!tedvoO*LO%O zDugkL;|H`*d+4KCi~|Y~vd<9O8zRtKhKoPH7(ey~%%7+r5*XuHsbNaEPvi+xnnU*q z+SS0Hd_DsMOwX*2x<6MXWfo)?_Aju@-@U>)k(%UL*`vBXS0xZ!!#OjkSYvM8_4?6k z?%j4B?DoChtd74L*T{N=YSPMdBmDO+iP7SXNL68dt_h8E%+MS%IR`T>waXuU-dI8< z;0AxbxYX)}iG`?i+?Y`YBP{+GUUlqI#~fi^0Jho1(=`t@HNlso zo8X5*i*LdaYNuS7%SqJ~nRJqE<>@oZa7HCZ+zqyqiyCKyc%J7QV0xMp#39%*#-C2O z!VCkWT$gNnb7Ucdy?c0qMnt!8NPmPLo5ei}dE!@fNLQ~O%2#XaqdbMvDuny1$dPBh zpQ%zqqcl|?*bDC-Gv@k7sf5y;#Y)8ml>=$<3KWD zMnbAPP14g@(=g*|$(md;>-t?PZiN>rPn z6(_lr$+(7*RRGi?y@;T2SFK8rw{7AZ)nj0QzmO6moI9E=jtzm))ZEyjbo0)IDigDO zP*>l!H>96uERfJ-k{R!)KI-Sn7Rl5+uVlN3NC)_eUVf!ot(rNpa9cab;i7JT4|i_n z>Vk)!eMqrox%-<^z2ZZX4;Apu*I9?)@XTdJ4A`X4wSUmLM9)Z6=eey#b00D6;<(-2 zVG^^6SG00>A=kh={4e_F1t3~80C9#+2}r*v)-cY@JJKaPM{W+bOuEK0HhB(rNCkVO z+=j8RFL=L8O#KX>f~t@!sL-%Oz#if1Nd8NBbGlJ$*uYRff2RiIa*+Bh`R3y$^8lYk z4v_Q=D$XM+@PF@hBQ}(CZY1#YB_T?QofhU0kk{L=;cRgE?a zb`TTm_&CLSdL$BVN;h*%x%)4|EZ5pTL#rXesZzxZDa(nyUtLh#*D-Nuet=e?>m3hv z=39K-hhq5G?Q`_qMSu9xV&mjoI@Q%qkEjDibYn^d$gI=!CL|=Em?c(h6QqYl+fN9* zL0IU!lG2n*N*T8^#-c4f_439ces;3mKeQ>y{0ks6a7M&%2={-VVEklXi8|pLFIkyZ zKx=lnKmhYMT1ql?tV=-d_hS^U8vI5AM9!9zOa+!XMXlxUsJc~J#rB~n?b|Zn{IWTo z;q{E}hUMCg1;CF*nOmTBY6ekywPx{zL}&)&Zf zXf;SI6mPjj8d7E%d%4t_jVM12u>E<4vddb+r|bE?EVEg}lZ^agrQ3>C#srlLajrHd z_phL4h#&dpL;Wjq%CsTg+|yJ1%k?04&7|Qw){(^Bh0In z7KUvu2}cO&8oT#lFzN6q>`eyTfyzq)Q*dv5@+m60TR+uO5^YX?O&GMkdY9sEinxP< zh?d8{Bxsh*tY@ZlMYO`6VOPWOi@#41T;ZwHjw;R$KSkg)F$lxj*U5io2VDT2T%zlg z4l8GvZ0C7B=^L}b8OT%^jyx6X=LBj18zzX4GoxTHC@z4w85$~$Lt5jPshJJ44>!=9|>5yMep}moD*4 zZIwCAD>Pu@o&5W&MDxeHqu37@inS8edP&-uGqeL-UQq+8KOJ=2evy69-vVW%+jIQ(5WutnxAW%|3P3yeu+ zZ29hiN++={zQ!7hOh2rxA~md|HG)*%0TspN;B0ve>!d3Hs#B3IKYRXPXDGH+WmOm`n#xLhy|)YAf3f7PUp!>m9;=|oSz2AdrV8^OG~u))`*q>s5P1;D$lTV+QXuc zoR404_HX($DY2{%{@xzM`+8Z_J-Abu>PdFJ{7&VyWseZu+AFk3uYTrE(R6=_svD$W z?_EMr7bLA!NZ0Siv}@H<1l+NXC(ZYCXuJRiWn|)9!lI9Et0Sl9i@mR`TZsnR(W1CG zAd|s0biz%57x@_Yb3gkh811ZWhI8f;%@kD-U;dSD$!>=6 z&Th?*VA&GVe^S+8-e~`RvvTD06D)d&&40LG<>#+|2VGw>ZCR&0s8h`jGx!Efb2sX- zFM*_G=&-U*HHAt-hY{Wv$bC#6k_Y$#^*307Vb1kt1>>XaYA@n%#7&j} zZ+Jt7`4w_iCWvpu{a`ojlgD>JpJZEVl@HWCJhL>)Q?P#@AIVyn;P29&e#5*}dKH>9 zYn~DCFT7Le#|MaH<03i5+Fe-g4V7}7=KvrYyk{WV3l_X*W{44MKkm#|6=pjOFdR{4 zi{y!gmc14*@Cnu+_9{zUfPAY_K7t*wGEH%o8#s@MKgf#2Xe6T!%`KXJ+uC;(tL){S zEE}a}ZRYGIo;iEZ#HjxPxj;t0b+-!9 zF5dixe+QRrStn~Bi@WO`82{NN@)79>S)`M6)iYGOk+*x1RIME2@C=K6(kko>59Up| z>JWB|GRbU+);bIPo^TuPCCwaf(jNVa%@`Ca^D z?T)aNs@O&=RHPdTx11xod5yCRY*0^J0-&F6!9(pu2m3hU9r0Gz84c6t>EW+IfX>j@ zs1z&P_`ST9>y#SnW&B+qVAHKB*I+MPgQ6_~`ePlGXxzYmPEWRkz3&wK@f-dcNt|7V zNtv2L%_NgXG2{<_?`Q|9rajzq6q$w~58)2Ex<+Y&ZGvr@`6mdT{zPkFAon2m;0l#$ z#chIa0f`o)EV@~WW%E>(3cA@am%p^WMC#)eZzbNq-^nof&;8#hGt*e1cA3&8beU4M ze26E?Il!$}3F(PsCd?|>7Z~;e8RcXX&(%LLP_5Y8*FV4|>~j>=4)omt?oY6G=?tA= zI{gCAz5C6vPnUR>3EOamc7y}VaG2X1RiU zOh2bY+jj_HSk1H#kobocQstlS;P%i%ox6Ae))Q=!?OY|d*=nU-zRI6O23}-tm#2}qw@d?&AFOWf2VUrZ& z6z0*db-Yc2S{dFh>)20l{oFXaXomsrFOdy0K7Pa-uA!PmzP{@u2{r(&?P7s|z<+WK z7iqc&7i;`m|4`ROD#9(rnl%!LA9A%ZPB_OZ6`mpb8D?4FV9lbpu+jFEi;{fgC(FnD?xr^z?{16Zc)gUWUInqYo_LI=1=w`qR0 z4;^L#aQONxa$Z6A2&(1t6wsd@{>7)CImBWae}v369Aj^ml5IXms*}>I(8w%To8#~Z zm}P)Je23e{K)JAq8Rwm+>JjAXqnR~IE7cL{euBJ#-y$O1vWn{B=c`fZ%C_Jbbx2Cr znia@1$Wj}luht@5V;;yb1oZz@3m_=u?|Shurp8rd`{)1SpP^1NWgD`MC0l(emT7F1 zhJBK3Hpw8Ke+NOj^NygIsg@$VegyXlI7h7#8e-42ZEmgb5Fis`d#X4Qa73vqSrI-cqp&lLM4@sKE^it=kzsWoTk*;zM z{Zb*weFxt#TehBbEy?N{QKq3%nR1DA?FqsvDZuL$6zw$7Q>e3Ewue8+gKN+_kz<%* z8T$Jc;T-L+Jis;dSDzo|P^qXMD>zDxnoI@m45 zEzQi^-`97XMZ6XG-7!kJ$}J?x66bIW-_JkW@(_ckQ?ag9hHg%)tdDhq?)AqE2h)Vu zAi~WWg-r1^4(yA12K)`lPOZ3R64Ddp9(!M~mtIb)zDGc%_J9CK?;Dg+foT#;KgG6k zeJ@wE71qHrRKh`>v9eqVwY$X>IigA&`)#o zkNCQZ*TcPj_^$L#x?Z?Sww8CsJmbT;N+rosic6p;`AW0AZA`r73h@E_DgGn!D8m_I zu3?jcQThS4zq@GX8rl6vu0EYc8i}kY%m?mCEi_;pw)Iy}{8g47X3$q+XY;*D9-%PBG{Z;pq|iCf`ao zD&Mw5G{FuE;^*lWL_d8Er~CCMw0(?0TAgaHQKdq^I7^R1j6$PSrCn^Qj$P6df}5X8 zqo)(zK4AYN+=*cp=W+pOjo^aF-zV1mJ2cmzL$rMi=Fu>RMzQEO=cW`BDx%wpQVr>vlPY~-Q!X2sR!yG@s$yQC%y9DQGXX*HR?%*0^ z*hl7Q@8E!d;%zNbR>@k$Yvm)q5O0vLoS_2r&oDO3wu_6gFVwP59OA^=2Y&+p>F)~$ z+@g@Lbc<$`3-RC@x`zk$EZXQ3FH@VTCDLG>TB@00RjTFhbnwwFjB=N8)I5o39qz_C z;vRK?$0Zo(RkC#p7w0(I1?eQqRJn1KRWIKmLNldA$01Cifqc84Ey`^lWswZf&vNu% zz}pqBARXhB8ZRIp!1D~Xil><*TOE>!H&)1(ap;B|ay^5REKUgsm)FQU#XxQssjRao z*R~OtNnfEk2A3EK4q_eYrxT2~NoI)M!{P21X+k}lq-eTPZZVEYw^|jiq2Yd>p=cKV z+D*ke4RF~a2fx1f7~}-df0Y#cd$={xL5Z1U&lk^7=L~b*Jo!4XcgIkf?tT`*Cff|e z@AWchx6t>vy9rh}`=*&(JyD)Qb$OZt?BQPZO0hPLau7fI*bXq*=WJ6RVQeF0n(8Db z`S(zFuv^4}g7J@S!i(ewcy)>_Q`AdVNvIc;OI8SkhdxIG_&NnCcA)`SYte@D0w(DX zz~Rn*K7(Aym(bsN`fC)3Hwv}1zZ&F3e$go)UAu$3L6~3;aXZAKo%8o*nyi^{g=8|E;Fb(n4ESYM4j3M3%`pP-9N*3hd6%g)hoY^FGiOk!#N``XY zA-qZk(0`s@)h=JgzY4~MMl!+JwlgYydCyFl=~_*&C~`ZfpO56UN*u- z^n0VEd?T@@ACT`rPYCY*{mhfBvz)WUfc{TCKT99&{c-OYZHjw=XbC$epw#F~XrVgA zwo#n7PmF25FyUc~JWnU;#Sk~@DfkW1dXV2MaJgyt7uKO7#RW2=1HLY&ls2IuI-UGQ zws#=#AD7sItvtQ>Q?c#_IZ4*TToGRWPE^}|-st<)s?{p>}N37A{gaL=JG6W}@7!&>~*vsZdU$of7TRty{*MW*Fw! zCiu9Ad!`$sTwWmC#DV>EcK`NinmxsgMZZNmAYVp)`IYa>G+-Q0 zGF>8b4{#0U7~I0=>+<(x8)_E8-j{yz3fRR%y82XVl?2dVyrrL~TOhzowqCu&-x~~M zno&Os`_4GGoqv%8;wQ-($EaW{@%kbe;l6Hqi|jTv^`d2rbI^z9K<@!|7|>wnG!wW7 zy2T`2@8B?J{`LtjuP|R*gaZKE{IE7>ykp>biPwM4@=aiunn zPOTj0RWKhmJBoVv>EzSIGpn+&wPzHh*1`TwH6W2FqfD*nI`_1R|KF7IK)#x{DI#?yysYs z2;$8iK}`z4E@j4o5$63A;hy?+JF7XlWNAU7PzOa^kICi%K56(MfMnKBI;#lO}C z5l&c#LY?WRIQszpH3HWl`bnYIGy`v+Zax%bf_Z@w(P@C!0uy_$L2iHx^d07&m%ng( zg6#ymdXs&GgP&OYFojR_3=8doW=)i3y1qeinfe)Gs|4J`E^(CAJ)(Km7|R$N+zs4O zgKCE107sJ52@(CAeT+hddsv=UvAS@(uYau5%XdKjZZDS<#_W1d$?QCt}^8=mJQ}IC9HjfpEZ))4RkYmH1o7rC&~>-r$c-M zJ4}P2u0w)od%#bh6C&JzLA8^va1V$olyWo=5Ibe7rME~K+K8@XI!QPC*$d<{O-I-P z{*SP?$i@0%E#H3V6&a)Gl9MWDowUyZdH4X7V;X7`<}%K)LEk9x_RKL9;;gbSpQQ|rh1CGXG)^AUF11xkf%bqedr3_EXPkc z>898B8#twgOC0vjIV!1IxU&fk0Dqi0*PusGz6IfEj%}Udl((;s_W@>&)F|r=m3YH3ifd54L^uDJosv)UG;5^UhQChxzeJ9* zX%_ujrM`lWup``9Cz7rqUV8*xA(59^$1tPh zVHN=0$Ny6;$IvbOFa=Br0li1To`Lbz}G>ccT zE9gqYJQMB26n)1mZ&x3Gl4I84V0WX;UUsE#W?9c~t^xDx;Fn;~Geoj=pR<+nx<$_6 z?qN}Hj_^(p53thg(O2zKl^W{gdl>=qk9uj6Q@lIak8Fi%B@gci-!5_bNtPk#@ACC< z?^rwe`Wo4s6GELWa<-8u=PM*XpzscVfaYlr(?)yBwcW#W^a6ojL1FG}pxt06`aFU% zjH_0VY)+H^fTLP`2ASfCu%udYi~;*O%NlRN)8!T)+nB#4{!@c z($CE@l5T8~n4wpx0O+q=;qSeN3k3A5wE+VuHA*-622gDRy*3KPxR~TfH7Sq5T~Zs`%TiZA^`$ysv6 z#tjPfGRGkGiVP#wk}RWZ|@ikY&+Crsp0~?P3Bp8w8Lnt1iNk?;GcDJ!Y#}TYm^w9sNW4TZeU#k zUchy01$%=0ziMTv9~1R6jM4WAU&3tBiPwF+&9KN(=N`#2AUHtTAl|K!-KOOl_!4si z4A8$#EY8v2&n4j$0poOlNo4rt=@f_On_ti*EB1c4=LAEAqG)e`SCErp1=CEfLA`vf z{1E*JZ-^uF%sAr&6UG(K@G`Al@-}Xqt!b%o8r{+#t>G-jD#Ce>phXDeLxHATHE%mC zP`^OBfkrmYA?OqBR6kvs?Gg*jpIaThe4naQzFa`jPiI*A`Ucp~)5O>ha;cY;tFnyO z%2z659kPx&MVz4D!n2NH9ro~N8R6|pHEj`AD=t&);>k2{4W6Ly;~-zw%L;Z~e3Wc< z4j<;oFi|Tz!W`gEvP!a=W^fPw99y8Xi2ZPMk@b=5I&d^&VJ0}Qs@(3kejJ1Ki{u0kSS|`ua$JL!;TdGAkMYD5?%{1&5 z=H=6>@(9u)$T)EW>k+Ed;AdB0CODu_Y9BX4xymBYTPMai@dU9;AUL9%$KSCBw@rt9 zwU0%%Q6D|#4R+&`5famA^tAzzIL`tAb?-4D%@|H&EIwQv0mOQ%-T<+2jfP$ zIM$PTzL{r`-z6g5mTA05mu#XP(abvVhgXN!23EaXQLY0aq>5^j*lsmzmyIVx1LjNpzaHxtxIkK5$3v;pnk z*UvTf4fqx&P5%;gmoiDWP3!^2D2sB5bxf^{>5q)_7QR+qxiZzCf9dZMD$<^0rB;S;lVpW-1^S4#)%Dx{nvlVwT|; zceX*3_%S}w>JIJ%`xA_4qd<40+Ym3}kwFIXU6gf~T(CXe1b|fTCMg7y-UhGbO-U_VxHA4+9BZt`3h;8G1FiJuU^(Y zeu5Tv6Lk*(>;xmja+Lt*B+iOr$s|R)Ji|7`nsVb3NxLY-8EL;t=MeFmD1Ymagn1lK zm!EIg7r^+NYcR)p`|;yVvY~TSh9S&tySP>n=|Yw%S2x=X`sO=e{Y+F74k)@UAz_YDV;n_W*QA}&(QPt=;g)P z_3)#dgS=HL*UNqrO|tUw%Q28{^!J`%{w6xbXqCjkukJi$!7;p?kd{qOU?PN95V zv{RAxT|7_-@Rw1#aMO?|yLkGU9Nq7TrYSsqSZD5@Hpxp=B5i(=QI5KaC=awV%7ttr zNOwqQ;%#1j9zjhCXm?xKSq3$--MkbNw|G}Dg?bO*Z&3ILOtZ{W$FL=a2Dt-#_Mv(? zRLiNl)SDiGL<;~q#1GEV3`^v5wK}MC{BB143;adP=?pzoxcHtAJz+{2MJ zlylt@3_Y0!yi=H0^z$J1N4On4dAddFTf}=fr0a0sOSCzMLVWK*CE7q<$d>9=2^Lxv zcJMz(Pt)As009Tug9E``+s2DEe7upX*rAAWaPb3-|9`B9h{Ij|yf}L%nft}9QgJu2 z=VV*EB|jDJ;gFA5e+>-?3`RJ!O0`J;@KZC#A((j@`c9|(1=uUlKJxkP08^rcewu6K z0mUZGGU^U?m=o_%uHq2KJ&J0IYhap#xpR~s2#9n!!hVLWOF|`on~Za)murJevsAVi zz-O45XB^{X?T&D<_*>sG~Fx>>56hmy@YBJ2q;fa zpqp_j*gf_$<`Ka*Ktn%oqRj>BX31Rr1{saw5Vu=+u0gHBT6yLPw~!x@GxUd8W301u zKOhUW5^Oez>t!{I&`ymr|I$C%!rLGFfN=`s&Ce$?Ot0_)UZF^{=oNI8o~@&oeVluY zhj1^|h+?TmovYs=c7cko%fs&$s#uj_Jklj!H&5@^9R~cP8CLMSZ!(8i;r3JXnPwS! z+ju@fHd%Sv878HgSvupaYPBNG)RVIHlk71Ly~6Bmcz=HT8tI2u!y?c}`~#XfH?Ki=`uScV^{-Tm1MCioXK>hmsIY@dv?0+{sVq}XvWs#e)R|=*CB5iv$s#YL(FUE9CCMA1`+C)JtyR z`Fs4mg*(PrsTM)r&QX3qrdY(;)hLXy0s~PjStifX{-xj$hgq6_u2L1oG2*p)3C=#r z`UG=>Or>(Zu0Xf9Ki#ZJMn4bgS+~FnIpxyFi(famA7I+V{^uP~moS)zJiR09zz@tJrG!DTZ5E(YANsQP#gK?BY|e1o@70 z5Ukg$LY*Ssu}yAa4e{*b#yWt2tdN~zEKu1;(yf$BVee#_IfZxgiS)XAa18?LmZ~M% zrhbvC+Q&+=2Lm;XN%-QN{0vejjx!Jb<`>t-_x@~9R4dV<7~oW_U84$jRwq*@TPsJj z3H$KxyBRLw))@rH4&feN`$QpLAnzO_eqLiFxn@>Li!>mw+QkEc0}T45J2-PR2?kx< z;E=gy8$?Hl0R0C!M>&ZPN7+AKRY|!=lMW)Di%&Sj8s$|f1iA{h1$qYfkk0WBc5$m! zW1RHxwTfXLB40j%e}{Ali?{vD|4|Nv$5rA%mLwO#Yc&e}d&x`R&D=Rm66YnWW!WHbHjLyRDgUm3>#TQ-Qk8qLwV`ZLepA)7^V4Jy~V zMgQ>Hj@l%_*#v(fSz{jrjDLgNa6d5*F?N0+3b(7* zR*CWSqI~!DF3?Oia}Ff9nWFDuk?z(mHcNea&C=r;cmr|`VVwH^BM|9;vmfWgycumb zP4x;~p%maV!a+IBHL#7rJ2b|yL9RG_&)9sSubpJFM*_X@5+U$zDFaE7{DaG5C07;7)Y7x@fp=Mo7} zw^9k^x=zC^n{*oDXCIe&T&K_-+yjhQ8{8e&V27}K@IKBTtFp>@nn$Q7h`&3XH%Xsh zo~Ma$VjbHi_?68$MrnV&L3o0gU>593HPIQusU++)Ni`xvi3`36_%zp>3Se~AQtBA8=ZoTH&!F4Dj{{LlP+J=~)v ziDawf&+owf++c5hZmITTblF-_?&7Trl%GmRxpH+G2m0i!qm(Q6Fvr-rCh*r2%mMLt z38&Z+?@+8$FE15$^+$c1C)prt7mKxO77g?D4?RY`1^RWO`v_5{a)z2__MiD1#Du%w zMCCfGq&15?Lv-?wu`;y>gpzFXG}G00NHuE+jy~=N1sq_Sh0QSU5#M4R!3lL2sRHsZ zi{t`briC)CSu)-U(}ZW_41L3RmN}igYxICGom`1FAMZBEhgms$0z5!~{_Y+;!|XE> z+WI-RO5H3)m{W!gOHZ0^af9=!%eL2L8aOx07xRGooU27L1 z-dLpS7Emku4xMfq=-Dm;`D1~4hMsY12OsVZf2UdU*KHt%X@}@NT!3AOA4QrjVFKM? zFXgKIJ@f1m9mCw#aXcMj?QoZ+1|HsOh4+x&{!xy9{}uVV3e`s_5D(_L;Gh~6-TWWk zO>z$KdAge=mx$<=gFMe6#GCEH@~kKp?V>P`V(hvkk*-GBn*{*1HHz>Kw&?ZJ+NBRs z6&t0R;|z{)=Be$Hb+ZifU!d@I%4AkZq3;8{|K9&fSNsUjWud3 z7zvg${P&Ov1_=(Vi^gdS1i`+IO5s+V-CwOT9M*BrRue4%9-W|*uT?6Q>Uu=C$a;89 zaGJ!}rQg72X$ka7*Mfq(2OuBr;rMyi$^AWFs!6aX!mmw8uQY-lR6dm#Q$IBFhC&WiMAGe%8^N;5bxJOm$LL(5*^F-RIy*#@4 z7AfCE)yk$AJp+T?pCJCdQvbUGcZ+$nL>XttIQ8o^L9i>$td|e;m1G@v@A(67-zXc} zX})fU@F?3jOPEWR5z>`N`y6eVnrb<~u3oM~^ygUSiLcs)TDS0Cv3SQLTt7f^H6gzj zY7cSlqn4{oF#nz}-0=WcpjV_R*;S}|f$Z(Kg(ujpQEQUym@-W?PgSkiD*XQL5L=`k zZdIb3WXG|hk*)OgoCN6<;QuD^Jo6L6Bj^!wq+{DBwxL*y9K%c4dpPIdY$M}5x+(q4 zSJ2<{k1;M#e!z40BRo*dgF@hM9AWf|zCH7`$aI1|w}@^KJ0;WzYm~3j5N_}{?UKzi z>X$T%7RjdmIhJ4^j`H*iL|cw?k*|lkNVN;pEwNM2f;|*#DioLLtdbm~oud7okF);* zR;eE8Z4qag?h+(ghkj!h-l$Bx`UF#>`Z@MfdB1>K-Xzf?bC@5>F(?qiW`uXP@hVM~ z1YrEThofJuR-a`7fBFIX_#Eg84D#gTM7uS$z2ZAb59I2Ttx_%tbuv$Yyor9Rm;JSa;20&;*~d%1B3GBI53pVG3F*o_^-JUt zroT5&Kj&QZ=R}iGZ_UC-1o(6C`v&QM=I82*b&zct6-1lrm#UT!ZR}H2OAjzve#N+C z>G={=FK(ZRb8?3E;Z3!mS^K<*HxeYZcThuTjIkTp;l_ zPP5BZYGq3|3HA1K|1;mmFUS`Z_!425>lxH2cZ7a{;T^O@pJLu5QM;%^dX#05bB5m4 z&)X&YGuIH#sfSCXJ?D&FVv!;s{yJZA&VE8*9T05iC??y|oQhPIX~((Ek>Z@(K*62! zcm6Z~`2)*1)`3#9Qc0V#LTRR+MK0B}ZA`2a#XROY_%rid2d7l?JpLjR$yTThH1H<5 zT|$}KK7JnqfPen6K(}2q&*TJoi?mIqpC0q*9+tO{eB}*flgKsnztNv`)j8bX8|Gn< z3kZmENvrS((=5%$58`Q&ie=n56aLmEjBb`{(Jrn-c#=uF@f6J?XpUC3{IBf%1Y zi*wvZe}K4$QY|_nNOBos-NUVxSS2w}Fw3o#33MS_s8R*gj&?jEFwU$~d4}Ma7^6FX zORD0`ZzSKtj~m4I(d zzEUd{GJBwwfLGA=jw*cll)cK$g;a-6K8!+mhtq8=rMh{#NJmHL|LpxRhfPwCNU72q%OMWg9P|&1bn)gc3D_Ix>vM#D z<{Yy?Z>_Q?=oyAyrV{N6E&FiG=qZj>>P(%^KhGbUC4oV1(atg50uN9o*j!@=czwMQ zcYCEM2NUfy3;&rf(7iz2Euvc%Y`;NGGp~^o;3eFaXJnq?kZPJ*D`Wcg6@;auR3pgO zJz$L4D)FmslPt;s*HobEEf}D_ZTuV9^~Yrr--t~82v=86n)xgvn*`)bjAI|ae~x|+ zAL*K8Gso}=x>o@5Wv;&HH;3qA4fkLlzj)hv*&BomlP{6{J(PjHx}qgw3aKg23hXC5y5^iTW=W`o>q3h9n$JMns# zuzo==&jqFjSZ^QD=L`eK6!|hwKc$8;`9ZOC!%XesPtTy^TtS~Fxd-{o(k5sD?H~NP zO5NMdH8R@QCCDt+sK_k#9Jg7;nlV{yt_| z;m#$RXK3Gq`{|b$gI%Wn7<(FIp?)HsF-)2!UwynmC^3EkO8@f@0NF;=8+YgfoHb%1 zjd6|zhKM)&c=BbWo3MLd4e#OqNr5}KL+nyrlY%LB^7#{VzBb2*43k7#n4gjjHIn|G z=vPiD1=`YimQFt;^o4WgjHq+2xOeB%X5iGSuFkI=ABBJDuWskTqB2Kh-^y?o}W zkzanjD}IFf0r^k-1Z$>A({!t(J=|^q+xSN)rwG`4uotLDn1@fL?!nfH$(G8M%9ZA+ zIR?gmHZjROc(> zWQ9zYE8gA;KHeI@#xe!v@*_~J=PYB8N4feqceB_jG{*4>2J*8=^>>Kh^VvuGd88Wp zIirFrWnvw0FASq?BCxM+F(vEm6B{LV@J#|;lXDDtdxKn@4sTY=dIFA zG9pX><3G;6dDbGcw{xIRxU+3Swdx!j`S=XoE$l6VT(wj9@A-Z{Woo8bX;#85OlxnC z1P8{2y9Dk&tOL_Du1WKZ$frdr&xlYDs{}8Poyv(OS|y( zydoiATSNrghq$g$!_8^uVDGiRE>it^wfRqPKNl&FF?{?!$BMVYJdmzw6{eX%{vcVe zlY@C+oJu!EImbN8Fqvj(6ASd@?=i?BT{Fme1+7r&6xzXWl7e^w*dFAZrDGqFYz}d| zhdscKa26jzyK?gVCZ}3hpzaj(JGxrgJMbtQN8d8{H{mgsV4p`Y`tbm_GNW^NxmM8* z)m;4?rimm6hI#I0{T#Cr$lD~-VeS?s*(#C)vSsIhk2`?=r(TMDN4O3S;uv*=N4_rJ zlxES(dmhct^caV7v&PqZxE#}J)JdyuyUM;}|+cTc9jZ{|SZg$lVuf4Di2783;Ve#xgO)M?bGxe;=HD#oM29$s_0| zIOEhT-QVl)L_F zxk_c4`5{iED~D*MDw_o6iF#SC!N2bR`}s6Vw@9R#^YjmKUSf8L8x~7cfIy1Xk#17r@`1q8a2j$~JSQI0uGa!etm;pd%f(iwO>X6ZiqWO?dyYLE0{2l0z}iFn0^{ z0sZa+f_$1l&>w@c#nW~ZXaTv@$?>N zi*fvS{->L+kv+g}lini_&{Zp?TTrhk)R$=C&u)-pxb{)+k;hvn8_G7oU1WWZaQAUN z#LPDM9D9!bfP8`x{RQkX!X5qqpua&b{;_l5EG_EUDIVpNZpjGy7$;9F`EiJ6FKd(F z-@pHxWJJD%_(`!gDlAs3R5~DCtbo1Ayy_7uTf^GBPVVP7z`)uM_C|8>9c`ZKtH}n@ z35;XP9_koJjf`^$>qv=_rxU>c4U#w)>u8-K)hdN=RZ1WyQ;eC$N>!w5sAn|_Sci^L zL!AFv0rF+T>~@hY!Y7E27di#vt&dQ_?j-AUvk^{LNJ5>5ShDpy`0};9ed8>YOIw6O zovG$H`*C(D7N+T$#?p;+vo#8T*@gO!eSmP&$Lkb9v3!HhIk-va={v!BgkGyA&}tWz zZt|bB=j)Yje1`J~dw$o?FwK*0T_Rp5eE}P1K)IP^Qz>4=Z@~_ly$O6;s&}} z{tSt8@PGSHy4EV@5i-UB3_eT0g||XLvl#EDRL3wzHI-<{J;^&6YVI6!gyrF>R?OZX z9=uCD%G{`UiI%JJ0I5+m$YqsWFNwCNTngxa7>8J=1!kixUI8>S- zlg&ZEf$w;G+=KtO|JMkr<>u+d>ibxjyB1&F{Ck9aV{rCBZ)#L&RxA>SST11QVri!* zX-8R!_JE-nr>f)!xm~=~d=Edcg{as2NHxP&&yoTG%e6>1q}4RGfepq!JfrdX_z{`$9*Wb+0w z#qt66uf5z7b+t07Cek(j9+e8Dt43*r8_Q&@!xu1_h7tBCN1{!f{o8-#Hg~X35WmKf zNhagW3#1l>6suaLZa&5pk|oVDfjZosdFrTtgmkL-ty*8C3hse=Iod|OxK6fDe4M#epiT<@#vVVB&lhSbwNJB=BB#wgZ4L)7!ZT?5YlBc0YM3XRrjARd`UwbNI~Xs2y+TO?3+9TV`jZegfr z_prMK82)wQpirY$M!u4(AL)qvpjB`{W*yfkM>^{sf_4_~WSK(w$J#Q))hth>u17|! zHTTma4C(Gq$V`nV@O*k^4|qCzpsKEyx3 z^X+?#eUfdR9OX`m`WtAhJI~}7kJmpVN_236JxLAv0qMvz{Q+6Ea)bka8+(Oi68JsF z)z4S4jAcZ!Zi|3smU2nBgK5e-L?-84OC&*voFT-}^fZHoDB0l6xvMuQT%S;*Tiu0PLz-_k7y1#u1& zP0Z5#Jt@{^IOnNbWzLWYX65U-`gYOs4HWCT1qinJ`-Ivbpw7{ft@p7B_UR`dkymIh zkex#xfCPJAps(P=+zXYK$zUI6XoR~^uTP18f+m=>3ai!@XnnY;lBe28xB3!XE9R6M z;Giax`B=kmS!&T-Y<>sFWbeHb44393Jy`axC4CC^`F%7wxJ&$Vu{r6q1Gt02yWr# ztC}W9+H5kxKnU0VlD7SUyP{MZ?n1Q~?84hxq29-98PDC^$(v}Npr@PvI$EM7(qe&d zgr%Fu`5VMF;(3a7gdJzo!}s6C)-F848R7Wm9O{HSZ5=tu{JdDEszx6ERHp6_^8nH5 zJKNO#^$sHPjztpPs%i3jFNm8Za@!yInr}aC;E?VaW$4CTqsN-wL6iJJ9pTP2p_A`* zOb5>fhGsU|j&SdbPlejZYv`x4RjR-GcuQqH-F};u>h#bxO5HXE|X{>_G5#2Y%0aUdvakdJ9dwdW!5AuAff48shRi5Aq&xf?Q4H zQ*XZkjx3!Xo)eS}f0vD-oVbISj zrD*yB-@AXQ62E|cT3ILU^65p~4NRp(hBp4*J_h-i{dcO_fFPxkaoTiko@wGa@)@bR z3guKif=wt0mOnT+PkW7YjMWa&HidLqshs1FH=%NsC>KuORI;#Eq}t?~e@i~>|2Si= zu53-Ea=c}{=^z{Bl3dM;#9nT)@mqMwYLlEz!f?lV@>t_4$wl&A%uF-X6Ih6L0hS)| z<{z)ACo~hEm3N3|J-x!{;y6J@z93&&$FofQYLjYGEiuMcp~2IpT-+q@>)Xk+glU%8 zu5yYc*ld{8EmXrFYCX^Ju>W*Z3e~G*#CySRg{nz<9g0xLn0ruHOC&!nM4Oi=@s>S; zIXjW=u+N^Qldb!Dz5a9yNk9A5fq1z<$23{CWCt(GdY3@1>KJ*B@%r?O$L-yqNWOZZ zx?Z}sH}yi5c%88CJKpg@4wk+Z@^;Qea_r+5-vffMx9fP{{J-_LvouYz)p9RGo25nC zW(hllTSOoscCeX8dAkMMqio)ME>de1{;llgFI(*xPCrSuN~*xNj4E{g1b_v(8+T6^6M$$x%0=E7bqw1eNB?thP1O^ zeScEs@AW9t0^RSR?7umN53)Ob!Z>`9K)J1xVHdfBlw^L2yh4wDcnPreovQn>m4 zW*f^OBS$mF`VMxO^A1X(q)fhtp;hJzzgfUIu8+g$XTE+PM}(796I(}+J?vGxG+&Ql zx_N|FZi{@W_&MUsME*|xcKLklgBHn4=oAw`U8WZCdX>N+lX~F}D%`$Cxkx3-_7nqs zNufSZd71tKZJ6yA@)XwBCsA9x#X3={Hq>pFTCTz|=BvF#WuC5EXtp-$rbceLbU&x) zz%VnxxM6;n<}GZYru`?+HwDIlVG}e-&*rJ06}*mOo0%tzF>U2dH@<)%T>@VK z>fX<9j7_f8JvhYg6uMcWOuYI@;tR-Ajgo7$X_{HG398p$GGF@m$^J$@8Da47b_sTf z`mGjcStFBT8E)UtlBSFR!#0Dngb3*zn5R*$E?0}P^U3Aro}=$oJnAOIEniQKa;Cn6 zuX%Ei-zn1T2${-xdbJXqEeC(}J@EdPaUVUpg&SmC{gX}K1uo;R67OSz8ZOrlN~PkB zv(%jZ>IE1F^pnM^YDGRi3=@LwB`TnjO}>(0B1dcb53M^(N2ye@o@1a`m1%5}UL*f) zm|li#HT$4>f^4;0aHcNKj%57_$^ZxQX}BZpbc(TKIQk*|WRuwA{v)3lq=A|cFMrPf z^EVgAYv)a|E>dmfLpw7|K|I9T_j)(Tbq}>b!mtDh#WEq(6k`3fO04Z^vHh1T z*j{0=vNYX)oPX*-?*z*_37*bIIf(0B68?7A5WLM73AGY1mopPg^jICmF1$7Eq zMSLAc$hXLn^(khFrs~Pi0VxpYi-*iY%(tdjdbMm~P zRE~4pHS|?fiq0q_=^D-0Fh>W^0P~Z|9pZLQgnxiNu#Ti!MA<=~1-gzgTKq)3V;Y?# zALROBqgS|tp;&y4a0I!a|v_V9m_k-8{ zjck33Xu4L7O0>1YuV~#hoIE`Qc&*I0VbG9JcZ@U7GCsc0&B;~kk&tcncdeH0N9a2^z1-`6$V&1>syV){3k0$yjDxVZPs+UgYGeR5kn-;j zt`iIk6r1=-rhQz}wLe~V^AfK6z6bgMxYL?Bg6-^sB`TV^AubaPu-70TgsTr!{blHB z=H_ZLj`#3L*P14=4?gTa=AM^7XFut3H*cxZA-YVDZt6KK)Gg-G)BG2)sE6dcW@-J@ z7pOWVCdS0Ss2Cu##?8>woWVyQwb>wN6%DH~rCSN7y?OMaWg^w}oXLk&b zu;0PUHp*33EETU#u=VpbPTxj1j!V*0FLC)$C4UVQ_Zn}zjjdGe4%WpF^^$Rfb%=CX zu6U2CkvHfapg&LP8tUWU$I02_?VsSVMzus3r@KU*t#b>tND=#5`4{w&cfc=|=Ovej zE#r(B|4Bv=`wGRkNX6mO8NIYtv~R4Z`!a{CVhgmz|}754mjseYQb?+FUbG1HiC z<}_`Khc;5SlxODM-bf%hn$Q};x z5N(FLN;Ood*ulxwtba;3k!p^=ut_q&6>UMVl&AUod5Ma6t$jEgg2B%yL)BW*YKihW zrr@_Ui~2ta4#{Vh=qzF)?L;cdl`CX~dtUws^-#~l+ZkXY-S{QdCF2&-!!2Cx@U@3e zE%O4IWjsUIAjAHf*ZV7M^cCWH@ctS4GK~qA!yKer)lb|4=*AAPmvLYr--Sa!r)jR^ z-yelKj&NdLJt?-2>EdIUW$T`yDpsSPi?&d%Sw~|Vr5PKe4e<2{gTH{eDNt$>>EjV? zxP~~w&eVlLWE^j2i?&)PWS`waTf=LT5FQdQ*GLX`=0|`i!lcDCF>9_=og)X zX||;s_fVFoj8Z7a;Lm$F3w2R;BAnaB)G~eTRV%;xn!m|7-&GKN39Z}PKnkB=so;+Yp|y+A_N;SH`BCJbk(vYDsI8eqAMg6 z3#LhJLiXQqc4TT)iwo30xPEa6a`*N#`uV}NS@aNno)Qwm{%e-bE_SVSzQ!PXgM?fa zf2U;q=QqQwG&5$2qRk(jBW?Y?B5fJR`#G!Rr0UL)I{9U4!2Y`jYUKBGhQ15%w2l1W zO19gO9y0J$3y?dn#1qu_KMM{x2jMG70_Xqi^1%}Y@I6FVA6ZPoEl}mT=O@97(Q75inGRjK2)W=#Q za0&k=EbB#}-7d}!q3ibrjAF%nBbqhp;WptGA+b6@{~Qr--!YMP!r###e-AEA`vh00 z>+7qR-xVurMDNk{(>eul7KXVyq#K2dVp;{G?47<1a(sLUsZf`zI zSB^7)^S6cf$qnOVk615dgU~*Vv3HQ2W#k@GskBZiT|Zral^Ee7!8}`ggoR`U0)l14 zERkppX!vtf90P1aW{FWYfAEoi;8O~_s zi1hdz?r;xp`@<}5in^H}>UN41;@0VVC(i_vd?nGmrw;_wJjv(RpWo^gPBL_}%QsPs zPz^=e27OM@)6XYbyMZ`HN4Yq=*374w-NdEu?~zS?S*VG=qm$N0rrdKq~ z#5G_Nqn&D03VZuQA89|($N9?-JDbq&?_dulngHWK9KU#5@h*m0nWsv{7-soLu>P=) zds&|4UL&*$4X}OisFH~_6|Yw)uaypSgMr81?B&{`{_#ShDD!EzG}%rIca)`OipK}K z%|7N`61CsT<+^E*cP3Hwq9sbzvXBrlFBGb1m#_|m>IG}4Hg<4jDo#*L@`aj3I}VZ7 zs9+%&r>Z1EUN2H=W_NSH`6SUCYx~K0lKkfG4&ewL3eMl{X?C=gKpS^Y`4hqe_poaOi1bChzQ_gGTH%OGIJS+UIOg-Bu zeu!T9Y?3}#6Z#hI=mA+aU;U>MzzIt;;OQ|dy1E(Rwf?AknW>O3xAY4MQkNrOcxs%K;QB;{EWe7wThU1l@=?rx_Z?|}MCj(mJflWLys1^TQ{amuU)w5PvD`iSB$N3k z(#2oOM`(SVzn_XVPP0Sa_OMFzzWSQ4W*vck9czNOVE3JP1?iS{X@=w!r$v04xcbQ= z(Jak6v06r*6ePs6BHe7t*&+5dD!3!%svwViUCY=k9oCjun`nEMzI2OzF{EQ>uTWR& zl>_V!PJza!<^X{MTP$uUAOC{7Y1-W#4?>#WqNL`Qrpds_t3g7l%12xhk5OS!#&}=Z|$#z-tWR zL?g_B9x*Svc|X5#{z$mKMKMLHpE1f3`2J;hhs++PQ_vlx?N5VDn!(7oO}uFPddYeE z2S_mY=Sa_UWLhWaps%_(X{I3m;m3Lvg?qM()*<2LzYBwN81>3D8R5jw4H_!YBUej1 zYabixW`SUqZ4>(fD#fB(kbDDXSEB9!)9!nsjnn5oj`x1N-6B0jihj<#EpTu(PqTH9 z_pV^X8da+7Kgrir%f0tZGiK@d`nF3nO@9UFSx(>w#Enc7*?P;!n1AHx1iN7zag7sf zq8*k?bM~Z~sn@dgs-{_g!aC3_uTW@}BwKO#FhQhKxI(O30(0`_t4I&VPK5;9Ao(Ks zn)8<})JQ9w1HVA;P@KcJpODU%2nHD2`E3$^7(0EVS`73>Kc$$&TkjLxfy*!)Vm6K^ zI@HSV6b`d7i=QV|`$r{}P1H5=yYD&~90MO;57F?9H3)6vbxP{|te0^2;~F2MOfw=p z+9X3d*}-YywTZfd=IVt%GfGG?qFi{H^&InL|pze%*9$@HYun!Kg`FS%;kS>GSm2%Uxz_wr-8(}fX4|cbT z@8*HIVegh~R4+2jVjDO@J;&IF%P^lJEmd<5^>gpw+99rxy@%Q+@bI3az}SEM7lglN z8JS@b9`yI#gfG_D$p2=`GJHU|i^p#UA%uSpj#?g!KP}jed zgWU*sk1%2kKe>>tMmuz|jnl+i<`{i(Vw~-!fq-S7h&DV$ta`eOm!+3wL^91Z>Kx`9 z;OElMdW=guoNTy_E8h6{{xLQ)>@-sgw39?(?^Mc>ukX%%y!SA9x+Oc&PUMSwgesKo zPVkOieGB#*=9(bm?Cy}T53%}T8K+i6Gn-`2G_guP%=TN2sjXR&Xft00_axr%SqaKH zN9!O*tgUXIX2vCga`okP^lS3r776TAfgYozIYR!nQ{+eb^pk5OM%mpWG$RtF%u8&O zM=)7N*U;`h1AOgb!47R4Z(@SqE0^rxc)IFjy9M;{)rlEo>1Gx@4>WhOr8l3gVks8J8M}Fp{v|_Y zgtEjA^C-wpFincE>*bEHvxqNHr<^}SqMG|d$Cv#4My94tY8w~w9ulHL zzFu*>Y9H|xTlIo?WYJ7HN8=axJ$`s0jT z18*WKMag#GhfN5Y+%qrIO<0Z$y+pu{``pG3S#q#&QPM;XZNtahhKEF9Z*~iR# z{?D~r|2*uz0o*c&FZ$`*xc!`DOY)V^3SWN>@YGMY|0Y=vYQkY|g57MQVy$|)A@5Shv;>ZH$d#v9qk zWay942{+4E{8Gl;|3B$#<a-toh9)55cVt5gCf=;+gKUpnh`Q1K2`In3TFIn5K zT1ArWsru#ew=lB|!LBWQS8&Oe9OKOGvbAbeYQOv0{DbMH$>tV`#uz#T^CX1YCVA%Q zScX+gT|&>HpH+Nx+D3d4BT?_+zljgDw|^Z29O}iKonK!*uj&+O=PpwjUTJ4v=;}zoPx3pvQ%MmtjLqEL#B~3NMIE->4*!nK4LgD{>f64{5-}YafzPtDZ zy_0STx29N&ba)wk2~R$cv+Lzstw1&XBsbEDdl-EO?Iu;5tACFC`kuXCKZAVJIAesK zZQur(axh1WeiCG910+|B1I2Qc5~4MV+cs?l%?DNxc&lW5lc$vMD2NU*M0{_p4ya;TQfQVX`G8Q4Z@Sjk zw>BvquvIL{=ehx?mt zuE7Bk<(foQ^y@yRb%Ja)#x* z%tfLrc*$0!GIy^Y;jmZhq~Gjm=0jiia+)O$vu)s`9fUj1Q~W#nnY!IP+Id-83gwPp ziI+Tr0zF`Fecm%oz+4%mW$Aea$dxITJulSGY!yu~D^fc^H%)?o@OjTZjBt5|Xp$`6 z)XyeWrYDPO}gAjNo<7<+e=xk?Un05MJuayLl^(SiTXF~FIxzD%x@Il_#;WgDfH zdkurTc@MLJU#MEFc8<723Ul+nN*>}>RElA%$gigt2)~qe@XO_ey6Q#G5O1Khv)hEG z=zQM~{hKZ@|6h$v{dy^ek!}1Iu@n=Exp8KPFAAl>uKw>ANgKqs@Mxz!1O9ivzd@>H zoK>uLHn7VBJs=@E_{|f#`2Kfk{_`MM|LCk#*29gni?v5J`zE|vRzIC>=>Hmd2;0bY z0$(4Ee48klYJcxgXPn&{8MUJSd-NA5dbxSK8YSF^w)PSIw`dVvnfdY+zZ*c}|WE9Oz09ri)-M*dEuGqxe_UczW6Sg6d7UEUh?GAx`Oo0yZMt~+S(I8p>_=vQKHxg{D6JqTVuX6Vitp#{a z(e-oIN>|ED)=$$uE0n8p3>R!q*B5VGAz33jK`~F@?Oq`nVd3jaG?S|W*(BY(wvmYE zxtbLUjp9FzUj9fj-N7+UY83{ZDt57{XJ@I~gh*D}1ryA5vhp>oqZcSdS{|vJCP~*q z-V?4%)hU$qi;mVL}2wl|--d&Ax?P`v(% zaUjx?VE*3s>92apRKs$`QRaQjL^Fm7y$n!qC0CWB#W8@n&)*qsJx^&Jy+k&^(ZzR+ zdJQ|uyhilqGwbjHMv^Ja4bBd4H`5sDvTAX>#UuTF%ui0-y&*1gRmi8qthCeAvus1G z!0$6yEHRgeL`)L^`gxZ4gb1xlJyb|+`T+KTz!09Xh+1WyxqLrFgI*N zd|lMDJU#T2yxlA#xZAA5+`aIZ@R!%Hpl=9Y7uFtM7g+0I1@T7EB?5DwW`?^LYfmrZ z2+b`xOGlss_8R*3rxE7CF;PPz=(@mZoVt1UUPP z)XEi?$OPLH&8lUe6^=9V^emBuJ2s1wFQOl&8F>52Rrz~0i?)c2G9#V&zJELcJ2=TE zY(q(=DkX_#Tzw8-qOB$C3D={o)rxYo#G2fLYGgJDu=eIDoj&biCz@Hr|4AQov<-bn zHMdCa7M!D%t^GEPcDi0N$h}q?>W*Q;G>KtCBR}jd!A98=$@-7ZBrD3l)rxkpIR@w_ zwX^G_p8k4Rd3ykC7sIcXDm7pj->#erkMI{E+u0s`e^olvyd+Yg}bBU}`zY2@SV`1p*l zh&8nf@^*9grt1@I{CEj&FL)HoHwZu-$1b*d!7es$H`qO~CiX$JBi3Qa`)gRPKCvdT zrhnb_e?0+QefyY9W5TU`UE+;^H*od?EGV8HtUZ=S~*XDMcL@5uM*!w>Zi+B{?GL1s9waJ zpv=%bi2I>De;)XD!y zzngb}V}?dQT_l2h(>09V#QQ7Jl8o-@`+^=DOE1M<$JNn^{%%ii^EF+-e z&M+16ypvz5E??v254(sP7>_`~cBfA*BKw%(j(Qn5J6btHZLwDSn3wQzmM?!i%-6`@ z#-*Fm$|+S^B2zB_D7?GaAYY$uim!`t9PymD``_>V!z0jvxz9Gl(*th5Xfwe1=NO=y zLOX)H;_SbH;TT{ZrJkjn$2ho!M!2|xLO&$f;OqKl?oU6-F>nX9hXsEr+#xQvkG4KV-olfww2hRjGETwSVI9uU0|-`; zwo0X>%QZ5uzW-b;V~}=^SfOB;YMxM}#xU_Nbb(@# z9AIk6)QC3cYtT=MH+Bd-%-+KD_kw`f$Hdw3^RATt`dTyB&l~cdzZ0OZhdY`lXy&Ht z|7ZFxA;~7U(EeTr7}&ef);d`pftGPBBi7NNCi|09hF-a%VQN1o*4`LXyP#nzKx8;Z zMLm|PdzjtN342YjK|QOT{WdJc81kNO3hs)pOQ3^z74UEF-v4y>A0MGMw4+V@E4V8- z%>6qkj031U%K3Z9Ej*3^aPx&*Nte0$z1{TOzxM#M@H-%`~R`+aQfq_Fn%(?y$6kDJ6=L{y6{ z<6v&oihjHd^pL7ENygf{g(g{fm_0@38Q|p)b90OuZB4u?(NL~PKj{+kTe(*H9#T7d z7rR{$$lm|-Y!EDw@pn$s2D_=0P|aDymnxYi$yMb&r%Hr&??s{V@CU8}$OiRIAtv1aCiouWekK8Jr!G72#Ha4yG~kMS+gL-hFU~ zSw@(~=%#kDadzM@DHhlVsb`VSx_Ob#1lxg5hRA zBi_iURcyBQDD%Tyl#?fAnYwC4s>P(sK0eK& zxZBjT<%;u^;f|s2N|mN*|LXLCr%sA)s*6vxI9uE4(=w?`2>s+Ge2TGJ5%KB*g`YQf zFF?41y}pEBphz)(8`jHxj0%v89_BiRk2C6Kq8~PjH;H|5(8&^O3U>^4D^d$_X%*(` zd-M5O;a}5VCbf+OGSw=Ua{lXU;?-EIddVo8IjUFRIs4_RV6S_4pl?r+iPnZ$l}eLL zHFE*N&jrH6+%=*UW1%)5pKV;i^(Ha+OK|65Zm8xc7Ql)?qW|?H)P}bOba#RciiHaV z*lU^@v?Jbb#&MuY2y~Dy(oNA%QqAFQ(aeC|XB%24WSDrIE6~9_D%cJ*LV*sXvzQmF z#Gl{%p)A6iB(D*Hev$tT{e4W@Y4*X_U)u#gI%nx5n)&$fcF$73{1I!Fp=b2-68>4? zE%Y$!8j)SZ0LQEE;*BmLQ*@8|UzW}cjYLDF?FZK-vPfIcfF2&u;jEKitO>jc)ZKqW zKiZmQgm!v>qe*OutVqo^68S|YQEH%KdcvO#c$v`pG6%sl$n z+(*9BJfTWXtO?w=R$>{LTItRiGonF2FOuQ?cA8szU(z^a}1p4C^q! zEP6cueO$t=qs(u^@HfX9E#rdS)C<}LSw@sf3!f#KYUQvE{S|%l1hd2suH=g!oh{=) zU3{uxt|sfS!3m&dOg2#u^Q~glibPsg zi2>?blbF9(xMP*vdtbRK>e)oI1asZYzkYx1Y>9?MGs9HuUC<37#6_av21cwYQ+I

taJK*HA)OcIKdSn@)n%l&uon{)NnnO9E znxmWg(*hT10TO~`M6{W9TC#o*YZqI%)%AmMio+L;{QpE-v>E-7WF^{KF9QN%k(|3% zFJp;JuBww?q@_x(UJ?T07P>&)JfTuvypeG{+FG_6)G;QSu@1{u7OOUk9$-AI!qX#D z6YgjoEnD5kMYaU^p?QLPP^<8(@4Ve0YxUnh8u`nlrAq1gj^Xy-0FHB=6!~J6oVTBB zwPd~1r)cX=eu530on(_~+UI#UFae%G&k*Ry)IC92A;H_KmVH=-c{E20V58Sbog;b# zO4bjt!C!(?Q7gTV$<_Ct=<8-y$#wEOh9{dC{bU;3#5YffutPjgGdM=I|2Dx8XGuSK z4J%WVVl3J`L-XV1Ep)yH{H4)P-}jyYJUz}IG4~%<$ z9}o8u$bEqCBG^tndyI;7#y$wFKYtX%Lo^2LzMGuLquz+$H%BpcSLKz z79?AGv_FMgf&NcD3v+92(DoWhl zZGcC`+kJ*)mWXnqUSJiwPRKke(xR0kT}wS%tZEt8#aFJVQu46cIU-*dLwxr8`-rCt^Ps$Z#t67J&v$t{KFEI|rn8q0? z7DQSw_fL_NP1pw)$rUPIeXo^%@B8@;)!f5s#i~*DTZ8pGS-?Z(_^ALQ;8X#o}@$%=TRU_0$J=00B+@UsCA;=}%vFPu=A-m?$>C;D<#S~*j6%D;hs%-<{KMS?lPg=x|ye2d5kONGMsSH0Z)oqSy{VkqZf zZg{(;>MG@dEoG7ntm$ps53U^oVQ+1s1ls}D`~n5+^~0(^jkI#Kvyo5Fkg)c)@c!!C zFHoE!N7}lC@bst`d~&K#AX{n{efn#LW}23#2cX+-;dSz-7+1>2S^juw6ZQ4=I^i@e zalwe=zU|7+${RA;xw(7zi?}&F62GY+M`YIKR+TZs>MxW)v_@! zLf ze^>c8^sP&XpEu}w`RK=jxk)oPz`)&xyW;M3`t+aoU#y9%59n&(z6!R}PqGfP58`bJ zwK0w_k=?)ubg&PioZP@5ov{v+E(^9x*3(VhL-OEDG#h%eaTt zJNf;+j?j`#idBJ*`ajWEDlJm`=&bx(riQD}B_!4=^xY)AX%hDC995+}{$`2FJmno! zzQz}aV7E_BS~LuTWT1P+L zHG+*NW$%3jI#x*fxag+-C;HO0`svN0Wlwl|TtCdvbn)$DvJEjzRLicA46^TI%2sFU zs+6pdh&F=`x<_a}K66yuy(=W)jxaaWv%zj{LSszAt*gW?A(Zok>;7KCtsyRc-rc<6 zjt{FNT;OkNXRi}(;;$3_Gynb5*UR52)LkrwjBLv->*+G(ynu0G(a;~3!XrC8wX zM?XY8W*g${Cs|<{6K@1Rg}%kvp_u`Z1m13v6~uF(1AuOF*t!0iF^K@RzXH{hY1Bveg0|K0YBXMn6|bmdL)@w+U(G z46>UfdjyKKoFk^|ry727pr33L%F)u!?&4Gaonow?-pL>K)+`b9)#~EwEFsZTFxII_8t5^xa%NR!`Fp!0&GIuZJ?#YU0uOZEC760 zPzO%7M83#83Qh#@_#&SkqGRuhv;e8VI?UORvxBoku))U-0S2NAPGXUufSf)&40v+dw z2N)LdhNfVBsZ#!6IjHGSV>9AxRV3R5f)uGdRGDN`>fd`3UX-J7e~ z$*=qy=z{y0KaFy2i|kHg1HSX8>nE#({P8ix4sWCnz7CIs1d%7$*F@lTALqk!VQQf1nTav7bh-zPkm-ytsl> zsQ6}|VE+A8igA)D(^#A(Kt__SzJbxmhk%H-CSQ!OOE4c}B3(`~rk~8z6>T<8xPqgZ zVI2-~kG39Tin39txPqgcuTU^aCR>WMm97Ok@ic8OH|XV+qlLGnST5Fd4SNgi@I|fY zf&Mppl@gQWA~k@?vxUdg12lLb(|LLj&js5l7GSS|mVJT(^cd`2_)C%%#&O(joE?}O ztUbnY?p`3jp>IKq2kqz{5_=bT4Z+@V_p%Q2chXMNPts0b!vcE`#DwUkz;B`-g0uBN zpT86N6l)LR;tYv;mVUCI6ZD>CnBeSBGbnpHQ5S@9Hc(sS;oBblWNDIcn7l&DD)?w<|XlwLCz|b@UZngM@S~h~+%m-zmnd!{dy|rvPQiIE7{gf737()SsLob@Pfhetxq- zVDz(#FGH_RO0>CAe1wIo?*`@!X^71*b%w?!ie#lyev}#R%HQj4SiK~OzyXcGBw4XM z(pIjjNet@lxAON_ufNvFe6t4#>|#x|(r?3VU@~<LcR@skZi-@IjRM;J1iZFA%`b)`;LQ_b~yQ9_lgX zKK3r#kYKw=i)gb@8&40;4)9I@Kd?v(K!&@5yM<;ReU$&8j{F7&_znPn@d!M?;O@=R zxrK(lZ5E|i_~fLQ@yW?CoO0eK3PhQ7vN#4lIpu4>U6~}ajP&s2XubS_d|IK zsa;SjhqM3JQ`~L*O}woN1@yyd+Gy*1jW!|NZI=+B3#=24GkW`lzO(-Z-Y3=Y*VDIQ z@Rx4ERC6DlALvgoOw#*%Y2*vH!d(Ts#ap}$ldayy&DE@tv5K{bKSN41Ge`rSvEnQX zpY35u*B+s%l+06F#yu;HwdxSS+wu$mQNS%c&0N~)az*0RG=tE0B`V;i!Cw-t6RsQm zG)Pk{H%Vq1g4Xa%{;)UXa?91L)@h|o8uls}JZ0d|m8= zJUu|;!rq0uLOmv2zd+y^;O&NhfWIWz*u_RZeYF38tN<}*wjr)Qs5`BkOZe}vT7_AM zh1x9Q;jVNuOO@a+13cRW70Z9T1jrPg0XkVSHRFuW^A0eES*vA_QL%Szq6XPh4J+mI zp3_gh`P|K$saviXXIY?5HD?!rvqQ09k}T0M#74S2&bWi4Qj%&|EA8ivyZu1_MaUqi?oPJK5DEv*TxqHYYQ&4ftJPKsV7GAMx zlBx3V08h$!kH7-;Ql(3H!FKFjx+&FS;?;Xd#d5dc4uJ~<>e+ryovZ?N=Z^qM%i+r< z{1sde&j!H*{U>F3Tc$~9N51bDD13Z?=No%>p0YyW2<=4-&Q3S)CO-5nkmsw!fgX2I zs>SDs-hLDdKVDi#YiEx#2fO*c_Xw<)Og52dkgo*zDnE@H#gk1IC~BoqPKMY@R6re{ zL7GH^RqO$V@^7b49Rk_fCdnHFkM>WhpAb%(2Jn++?9Z@WR=nefO z_AdD%!vv5C7ze!FVolh);8ak~(@hbsgD5_CFVGEv2LNP+h_sL`-M}29Lf!*;4SP*J zi+oBw%Q#NBeu~UAM!X6v27wOFe%|g!{x9ChF@U{$3k|FWw4-)Gu#*OeJJF8V2Zh=QHke0wdd`r@mV{fm`b1hDeF7j)09bhRlXzQaNHa96#0(R((?n~G z<9J&jngo8%-OD)6)km@dBFlefz(_Pu&w>mb;3rroY!Oi}U>sK}{jJP8+`|+4PN*KN;Pv`LK-9jJbx?4T77;) zwp6M##MZ;3k&m}!oC2&FhcB(dL~F3uXh&CYKnMTeI>^pGC{<^cn5p~vt5%M9W2CKl z!a1T_aI`hZGC(=`X8&6`?|HsPgk8)FwjtA`OkJ0dB-4-1o&hGwv($^^5A+Awvvd~8 zOO-TpSBamL{WOZUE_*__-XgMv=N5begS!oSalQAojl6`<*8sfI^#k@U=*ik8^}OexLl@!t4GjJ!(A$~D=qE*5fZvQ`0ONqOU!;Ynhhc)Zn|+XF zgnjTFk!^^#8{+`zao{He8yo{-P4trp7s#jNiyQ+?V~pbf0feWAcA9XVvmf{af#-m; zpR*s~f_0c-;?e&j(E$7bkoPDjz#`PivWSPj)X2})zJ|@#&U%l~U=`UuQ@J z8-CuVNxz=XQ<^0AbB;5{TeJxsqp}UzMF2!`;?)iT?%pVyvM1l{NtgRMqipUWN0}q+ zY@)Js8YGU;g51O20#riqP2Yy~aXs$8PF98<$AEn0^E|Db2s`G{OL)xvOx;)CWonFm z!d*Fr>tvBHI(!jrE>YRS3vnS?Stoo}XcN^aUZJ3w+a$&|6!Su?3H>m_?t^Q+B>tvN zRHm+rXRt3U@pL|!9GH2dNp(V$i|$nNcjyDixMHtZY`cl({@KfFA6%(g2|~&T=0U^y9gOhP%qw7-sbdR4kvOvxu*kjJ4wH3iPO!WgqMi z0NEzs`RE*B=kTTMiCzZL8rB}s+BqW88rW^X&6!7caDdc?y}pB@n&a&jY2ocAT7$Zy zSU^4I?gc#pz+Mw<5Nw`+Jx?) z`nb#!#u?iM)AgT}xrF3BFH$=}(a4W^5$p!O=q+^FlhAj*@3VBU_9zyflpUjfe$&IF zlZCUhPU!q`m{q*-5}tUqUb2siW+uTL<3OzlWI#OHpP)CIWB3BaHg4!U>|MMq_aOUk z@fM2ZMQZq)5q1%FDaN4xHtKP_1@Pt|p3}^XGgix{7!Pnbe~h(CGpJDb=$vdKUzx4l z$)99Owlql(`1KjmB>l@D)w0W^VQ($s7bx^HeBTGTgZPedO0e6LvT52!`xAH%=%(C* z&XClKK>pGN!aXGEGRPgHoyOW*CM8*6AB4VTm|z}7KBb%D>=$fj84>89nxmS-+~*j0 z$Q5Ilz&HTj9@uM&1<3n;PLdT6)uo!7q$gVf86?0XjJHLx0OCYcb38qNYX89gXPBT^ z0M;V}1nF|1hfted2GSY9M!4f9zHX*<^d8nap-c_gQi}*c97H=BWVek3-352CbF_w8 zRZ7}~-h4Ltsgvarat8&_DglS2oWF&Rx9|*@rsWs_eaJv|-Fx473&-$v!XBPl>1NSo z(!A#n^uNC{P6>BhA`@*sLW6)vHJo6$f=ky2cFPQnw_i7JfqK~!%>71j#Pdj7@P+p= z7s(INHS*bpkj|uQTZN0%8YGHUS4c>g@wW0cKpqj)9pET(RoU8QPn3V79bF(efAsNT zAGD1WZ8l4srtRTTEC*PM5A+M4S;nCqz4rwk&~Qi6WsZSk)O}3c?E?(Eh;7_mZ0y}V zETT1vg(^9!IhK)D;SK?Yi4@}rhAf?8)qTtv8r9-)Mv$jqobtg{q2j%-c|zXv5|y`M z+1lQIVQ)#713bStY~z|GUc;ss7puPhI?m`8401#YpFPkgTt_-fGTk6}7Yc4Q!3N6+ z{UqZ!`XS>u%LwB*&BF# zV>-aV+Jn4DJ|$b?>0uofY-gAt*Z{f2xZ8mLgFFGiAs$Zv@E_m6VC}ID33MD_P|d|# zjId#5yLocn3`ZNUm0)FB=+)0rY_#r zqy5<;QlP$zZ5gMVshOK>f`0h@73jJy(GcvWn+am8o&oies>N2ZsK?5`3D=8NgWRj+ z1~|$UV_pEgl)rNiD_dK!Jk|J1td*bk-~i{7&PHN~I_#)v^i| zlk};E#wh@iGtTmXejnE~ZQ-*J7oj%GxM5a|1F+LT$}^7RZwhp9_p%L_zBHX~BAL4H^k1|Xk zo>MFU?e)+2zhFD*GR6VO9%UVVo<}SVPEZQ@7R z0i_89T>wK82R)o2~Ogc~5%k3VNqs2B9Z?TPAqLTNVYOY94u1c*4{u27OUGRfz zfG6fY=y?Eh19GRjc>zySDh2sTmT@&QOJvs3+`SMG&7z{s)Uz%jq3;0p=_EbU*(QFy z9fq*bh0r9~Kg(0>D3fB*xoN%|>gg}>-QD&T-4gt+v zsk$aH;9akkW*Y0_^Y=nMK1T%o8F_j>IjI*&)~l4{YHH-yN&Pf3PFW`$;6OTCC5F2D z{N_c>o6jpGb`cZ{nYzTQBP@>Lo&g?#Lu_^t{hU9I9_X7T%2vx(AELJlk}b6gW9w+d@92nYn^v8Tsc}19vZwFU+IByU02WdXAhUYUL2E znI!x8yoiCn?Bc`O0oj2T@tL~M^K>&g2G$AH3;xU?Xpry>xIkDVQmC+r^7BqG&(!tz zlCCvO#oPy2RYPo&^*%o1jDa2l9N~^%9G(@1xR5T}Mn25#<~>IB@>eYP@-I*aG1Le< z+sLo4Hwbocek%h>O|UV*p$lXZGLTd|oG{o?Rz&{cwWf`r*gRXN4b~A@AoYTSW4nhdY8@H2P_pgn0fZ z2bHU`j9Vo4_j*=HvhqAHODDv|B}Dl*!vv@+NY}rD)6R~0afD{{)AfT)4b4oWIPEld z?_)-_X%f)QREvR}hri_PXB+x|+WYQsF5CWpyR!Gp%t}UOWtB99WJH80BC-laB`cK* zWkp00A~F(E5gBDwMzS)q_pHp{@j5<-qx<)Lp6>hk*dIt_ch$k{){*3XHr{_Zz4Gg`T7MbL9=OJ#96iqSIWQN@pk9! zvj*v{!kKz%MNXladSgtMafEB5Y=LwCT(|EPG-=(uAGY^$H%Pow;Opw<-TdX9!rjvi z5&|6(4VH1N!)A%uI@Pi=HUD#diH0Q8%U6y)Y7)D5YV#Lg?~B*`Jx!7~e3zXN>94vyI<4`;Ak?8~^A0Dy29>Z;5R8nBg ztS4UG`iWxzJSCp`|8#!*b!`8zO3c@V6t5rar|2ja*oL-#VjdN5q?}(R#>%0cW*Nci z00Sw}0R6zP`VWW^#lkeLU^~_t&5U^h>u|6O^=yhU(k2hQ@buTn@8Q|<*)+-D^LJXz z5a(9mRpN95u0Hevll0#(L zDcR*1*2kq(j#FuZT?+S5&btQ5R*y21FT#KFc4w^B%l$Z;&@~9ko_{y)okFKS%o^;% zG-j9vWf1WyI3@FhB{HK_wxMhthj1v#jy|5Gm#=)e|LNg0!!`WJBst3V=Q^B~uRpX)5+*0dHCioM(!`jYjoK`F*fV#KTBji~SVx;B2p zE-ldU&zcwYeg-9KrXM824zpKQ{_cj{i6 zA<)}H~ny$9L-yl_I+>%G@6Sj5{$1i41qJv~gg8hVjc;=8AzST5Xi{NaxG`WZLR zqZZ!qonrvcNDl@V`)+zkmM9Wda@RezFduMS z!@PZ==m~dd5pfRj^#AAiGxX)EmdLQulIi1`ek#eO3AKvK_Iz6X(j9N1&3nmKY9MUO5g#7 zXBf325z&wJBr7sCiWT@dl*_;W0G8;u2`{3eE2D}8zs9U?H(O-3|l28TS7+pIHN;2G$L@- zGLIg8Otw@dH^$@^NVqy*1I`51;%VADXKtQf_Y+$BJ}%#bs4gVwaB)3l*Z%cQUO zGE6j!-f%BctCy^k(#)Hq(#!)J@}E3`=LZea&)o`hgf`;iHjjXB8!h6YrF0H4OVrJp zp}FBMU+EOuB(~+Vb`DN&;^~RCdU$-ze{$jaktdY%g?rxbh_j@em#r4)U>@b}C0|61 z{-1b%(EX7uK^=tkqFlD|+ameaPfF!*GXGc)4FTgg@MIve3h(GA@ohjC@K^n}SQ9u! zyp?W&iWO#wsQU0kw|xHR*-t!pzoSOxjInX7O3zJ?f@tpt7RXYfPR^9eX;89 zH%wzrp?aB{zGmr)H&!TW>B$lB=?3XQXW53p`!bLI zC+-i`Vug3S-Kg<5ev_=1uVf!2UtFM|on{{8>RX_grd=k*ej?U{{||qtU_0Id;7Y$% zHXLB!mu0JEYWBUFq|edL*Lbz>`9YP^|K#nvd?mtOwK&YNo0ooakiAyASoP9X@BxK; zJpF5>hu9t-e|E?&lE2f>%ipt?yGYGC=Im|R>U@ngUln?Hjr<(#awXTGGk30E7-3N> za=+ma-pT*;@IQOMcD{|Ydw4w6h<%V_z&XS*Os)#pD;QAb(HQHyr+c|28uk>r-w1br zCn8r1cmNkc=)SxA4dm&sY5lzXiqvkn&r`MvTgCy)fr1*2_;`z78tLDU122kI`8$VM ziHMv+bF@*3!F3SiYLNcu*a(YBGX6gGlDyrQuN-{7NDhAS?&%ccw>!Ie<17hxxOk0n z{`B2oms;rtiDA}WZpnI)7K#Oyk^jW`OHl8TFLL$qb~BF4)F6X^dRC}Sypd`S_rMc} z8jxv>ba{nDtcha)D*(u_VEbR+|4mHkC{jR$@{kVwQiP6 zuuz*rxK1{3+oy*k?K}dM%hvsTxqsg)wjq4e{5@x>mCF{%OI1{h4bnOLtzx_Q(hN27 z*ZhAiB8}qrP8Fzs-vFm45mCHFs?jQOqd3keSkuV;e&}Z1J-y>S+fWZrggrD&+dk%N zWa{Z<-ai@cpq=A>BSZi0>0#EB_X9k{nw}lHc5&;cI;pLnBJFs3*51D+F(^oJa=Nd# zcFy$+-o8v@BP>H~K$5W@{%-7lS*-f#Sd^_!ws>QnrfRWCvVFujV=s4z^Y;yrb~Q4r z!$8juKJVcvQ{Mb#lzEkyV&UVqJWV8Vuklaxlg|(O__zfge|YKlu?MHXNN=!8;(n328rLI^L#lrRvJKpnm_H%+MR;)l(!QTmm@WyYzlmy$MGFZDe zkOif3nHuoQb5uiYiDq9mLmdg#{F+DW-w(~aP^UP{9q&t34n6DVjIduJ338RHJ9RJ4 z5*XXT=T&kG6!VmQT=bKw#cqL7w#}kt$}!gRm32}yGte**?hO?#3cBc(Y{xHUOC#!q=W2gMd%)mJ-T@wUYdT+Wzv1GT13~y`Pb&PV^qhm)OhdT(j!u@>rv|5pDb&*=LD0lA+&AD4(04V3LT}(9V z5U`IBZ60Uz@rk!st3R$@N-&qKhaL{d=R75}-0f~I>GltT?MMcR zw>W=unpU~Y*Sk)Nuj|nqv;6XY6aU1%kbb|vg+69-$ zDim*@T_TgLzi{0=!8v4_mUcSU3Yj1j3-pt8Q=R;T`atKc}Q!Dzt1I;4-$de3x%{;oP8}50U(zWpxS-L;gvkq(JhCBH9z;~CgaqFC9 zy-Bi0ez*h9%kcDnzXPn=^Mi(I6AY$FYw!Ps>o?qKW+Ls7GIH_ShVS_rdkVSwiqw9r zUnKwi7Z9pxiiK16;8eAa0q&P>U>!5c?CV{!Yx{>bp+nE`{?JaB?5dZ{)VqAe&+G9~ znwe(NllSvAj8m>(Skr$@(LFlG*Y)gBg#D2x#woxK85+j% zO<(Dz;QeMAqo3URiK|bh2K&PH53|(JrEL4iI?OS^)yLn7o`A3xl*_;)tlbGNGVGi{ zfzI5ilJoaG^sGka=ei{_j{w`KHJ!#^hhC;z;3%_Bwn_4lCk+z5-as1cBEM|5jmpwB zO&VrhB2y|iPFeqBg2C4tXIR%uHjAbiI))YQaSENM6l;2X^x2`8`w92z<}Fvs*HA4c zA`)sVRoU?U$dgM~&)oUGA;kIIE#g(4o?k!bU*CMOrW9k6mCILN?^P+y(0{#GsoWxd z$NQV-72ZLki?1G3n~7#*O9x)`a^E^<8x`iLTo!3J%zF0r5}8||NXy!j6>M*icyU0b zv{pLWhI~|Z5r5`*ujMFjfBe$E{2QD*gmT4}<)P_{6q+W*?lUMfE|vI>KU{vP3pZ z4fg}n*w;;QmcRM{qg0pRX4W?qhVy1~{@Z+7QvP|aPsdf6Ob)q06MepVs`R7V&LDiWOddO=1)a z=Wo6^Ks#NyC*Goq4|r9u%PKL_3jXSg3wDXK%-0BU=ILpW@btfVUbVPE!rQk|oMEC? zI>!3+-Aujb2a8pWQ|_N+9A6=sr-Yu{A|9yh*G;X$&krV=Ni-Cw%T=v8i|?EfYJgY~m6u-pJX%^%LG_BsVCPlPxig!T&>e<5i2n^zwG|bqTe>sX;wUISI9!1#eXE=wTqfRh4NxpZ=$LH0)FvqjE#hPC4 z&D0BbXcmPt1?rXwhO3v5e35EYE$bNO5WeZFRV?K^Ul;4JObx>Xv=?jn7t5sIHVU`; zdnTCkchXM3IKbH-=IHAk?%*1vpW)-9R)mwQhuDH$jy`^;ppz|EHA6$OKt1c{m8CmJ z1%9!glfQGCmcR4O?w9)?oLC`o2=C?2(j{5Z%7u=Ee)7`Q!%ug--%}`CJw+F9F-cD~ zXBR2hUZ$L{L74xY0(8v+9q3|#MyDFZTFp|Y8+_kTDbL^O7T7A>Ay6s5N*rxNx?C%L z|Ky1WkB$kqLPbV1gI(yydbuk3$~U`>QcaTcHTpT{s9b}X#(cdq^^l_TX18dwmmkzz z;*HRyUc6SUI?P(3c<)r<9>V;Gp8}JinfbQS&kG2=d?nPHc#=?n@$_u_2rVeydhF7o z%?lLJ@Gg^b4A4#sw{HG|bRUIxVol4W;B>_sIR+%_p$mcwOr;d{;I@yW%s^N8r{UV_G7+;eP9!V7qZjm0W^3`J!aK zV7p@&e!}k?QjAYLcyc7zMX2rJ@j9t;r8Xg(=r#QVTsa~w&LM7rXYP3WjlT zbhORBSKz0iiz8hgVvDivxFw%i~YQWTlW;E8RA-w0oGxaQj!%UxfQFzgHf!SYQ)=(lOvhNNLE@z z-tOcW=;Sv@&(_J;n4-IXvRzQJ9(v1Qmxsr>`i?wV_cO{iM|aFu1%-E<{rg|K1Y5_DFNQjWIJ@6y6#u#j%5&sIDZG1l zTq_rfn0E?tRfnFzId$tC!^Gt)>wXrgL35aBR-uS2BG;fxSGRq{n?XCBr)d@Y;KZK7 zc#C|EI;m76!u(;5#wqz4)v}|^$ibMT*UT%~g#E1X6K&f^pnvj}EF*9mLBroJ zh@GFimt+N+FzABT{oL|dtO?%<H{kMI@DdNqdjpBIAQ2)Wr zLO=Pds!%FdDyN%TA%RjD>hCt86_Q-7%U4=Nf?WB!=qEpHKY!CcqE)y>M73Bm@6faD zA1dWZm$!UA_0u)uaV!+sgYl}N2X?m1~VZQMy<#>q(YH^ZdJ-(xQVjOGMUzZV-*pKdXN!89qz)iz4G?AAHxh^Oc# z=|60@i=>_YvU!m_((c@?dP$3Thj6(n^91_{=a4*2e8Fy?m99lPC-4dP8`d$&CIq+r zsW zCA*qM@1Fj-4!iX*t8iGBNC5?PRIm?O&wo*=>DFWA2E+m_Er^kW-ZB^GR- zr=*!d$2mm@9T@8{c5U#s;ESOIhQ15jrd$=6ARxNiKd=n}6JsCT_7P4HTmei0^~JBg z68aB#10@<*MxZ_I;Q@nn?pCqt@rPI&2vQm)D-`sIH8jB=$EWAg;6In6xv0*?TKW_6m@I;M+{a-N_! zT%bU`Oi*A}%5VJU=ap(iveF&Fp2VN|bUb|?V0{q$}SvyBJ%Q~i66dG;u z#%^Bs8$qszp7rotz4T_cTG7XC&LJhcIt17U!5)S=qKnJc!C&U>PVU|e{d&nIGMSqD zCuga1v=hxH7&7%PUfcgN*yZl&8}69jED>&H)nfL+y|3?|gxXiScH=krP&a?s_ziFH zmd|8MTR!u3QOAb~ZxuF5?coV?M3r5v%G2}c*aAh#t{d(t#;!q0rf}c9Q*a9emshGn zGt(~kdartcbxfA7r@v{^1cO8PlOr-U*Dik8PEbID3o%V<7UdWScR&qv@tRR8bng|4 zZh=Xrhn~3v8>AyI!XjRzg}aw}wo<-U`rfI-Pp@9e)JrugRcVm8dTE;W@|9?tQ}=p! z;PZxCg?GORbc?rmry$xq zLv#D=p=SXegX}ulG&9yQC-3`v{#YMv(;~t#0Bj=JB-Uz#rBNKc4H!l*KhkB{>bI@^!B}TrdB%CiHPXI3FJc_e>lu~?p8nNxm$!> zLz)?A;2#}3^5n=9(q%aGc)Q{1U-uKqoy?ik*|!jJ9*zQZR@8-@ldBKxzl&O{D773d*yy(kzA#8fdcc} zM8j*oK!H>?)?vK&UVaZwj58Lf*GUv|f zjyx$+^9WEYinI%NxZ!@~GAhagFBr%1m2Hr?b}`IxnzmU~Cp*Y>{SWP&c#DJ2HS-e9 zkV{xCYnUckZ=Rr?vqA!=7}%lRZ)&AOoO88?*x5@kstqC{@kZ6+ zZ6BfR<`|%#M4k`xD96B-&w}m9Y=aY=kWwXGi!Z}GrDXlC5~;djR@!OuMbT#d&QWII z{Yd3Dcwi4`d10 zM$ORVY9T}D_(P-_JUC$yk9_n#t|7K5IzKO(8Q$&*h5!$$xd{gQ2)Dojb*1uK=MFui zoVSgNv{NrYKb&sBFmdYMwTt>0&ky!-`FTA%)FQ&)iT;Oq6e>TO8Ou1sG}LF*Yw2l?Xn4PQ4Q`$4V>KJ7IJC{n&yMxd?|ZyaGESrKZ(PLCX6 zWKy#a5)qLvLRp5V)XNQ=kx&CFyaOA6gplnY^fFh8J^i60HcxN~Hcac{ldBqLRVjVB zA06oJv&*D)QYY{0WLL>`^PaxD@!O}Z9szp_k+J#k_|eC6RM9pyGAAB@N$~U^;7Bvn z%mb5}r#ZopW|*m0tcpx#(Ppr9AI}TaE5tupR0EU`bG(gJInH7WE_ce{>Qe zEp$_;|1VxU`uN-}rm;4m?;9Q-Z;)Ugq@T>we0)@-1uNG$rA})5hin~{QtUJZ>cKAR z1!0bSU6?<~bbw>)r+keiGMC^)GtT}S?qf^=9uJQ%k=aIV`l?*^Wi##cDD$2|B+Z<^ z`A*^G{v7Rt&kwwKwXaSJuD1?>SSx{!Y#qJKT_tdssTEPrI)@OisuivKS*C1~Tr1tj zrI&f&MHe6KG~HB$y?KI23;zBM5@bu5Uq6Gd%O)B%V?XD`Ye)r;v*hW4E>AlL{(>0m z0gh@}v&5h4@-;H_eSCyl54<2=-BaisvOr-GFVyDaV;4z81TFw67g@TFVMiZhhoPTL zGy@7ISr0}YdY8Sg6U>=MI|NSOHA?O0d~tx_B&(L4r{wC>$$olRJBMFsc_MnrYNapj&J-%Kgm2Q z+=?9U?;FG$8ON#S;QNuU1ee1&PDJ#51F~QK$_|0a-TY;e9=z2&<(ALzPT(z9c*i!x z*)LhIR4&j#Igf4?ogjST1P)NPnsWZfdhXsXKF0BTr$kx;JW6)C1=3H-)O_9K80H+3 zWP0%$@|~n>FJHl%NjnXl;Pwx>S_>5DZr0|XrB*FYHo0;+z$4kjIV91{K7wuN>ZRug zSw>QgqHGz*72cUAlqshg6{)ofw+W3g|*2t(O#ONi^%> zaR}$?6K{N{U>7+@73db~G{gp1?&-TUGb|&qRv)*Wy{(;-VjN=~>@r37dM^>tD07io zrrrpPUZz&=Fl(G;q8a((rK=<>i{!|R+ws0kxlJg{%06fvgEYwpC$@aPaNQ<4R|}^a^l=ravy9|xAkoUxKfohXk7J-*NxqVK)HMj+ z$Y+Pt3(#4Pu;A;13Si^6Z6D<;vA6Gh3tiT>k5C2z2SyJkQ-f;mU)>-`jpyt~@&o?b zK!bm*r~y*AK3xmEs+sQyb50k;TrG(JKu8lck)Ab0@OG|KhX@TeI%Mp(^AeO z|EfYUPxIU@*Psw*)?vNOIV#JzwHlT%Oq0?K8^!k&3b)>HN1C!$E?oL0yW%Z8{au2= zJqWf3c<5x4F55)!e0%af$x0vBoijko)eBBM_`ZR9_Q?^lr7M?_8%?_WW;gY$N5F{( zW{J1Y3bi4xVf_!cK(4-5`=ID~bj&si`1@b8xi#|))3SBqEeiK+{C4L|Kj$>2?NWOt!5ttLI(U#t_oTB$p2y<6>XNO;pu^QQ>h$vo@_Ni z1G=jOK60ELv#W%sXZ;Vm$Y+PHUINNbIiICF#)PcOw>ulf@n+aX=4v6mxMY`~mreA) z=CY?4i?om}jj*%{4Y7$gB1ejN)hTp@rAiLi4qPhv8mz;PVLd!I+-s#B!=T&0aNRg% z`-e?m&)hliVvfonU8Kdwr&ZW6%_JFa<5Tyh==!*j9&hUyx4=**@hxWvu_?M}8{4Q$S3hj;;pyS&<;IC5u0dM4 zNUR%V$KMYLKE2#X(GzL|y7ObbR2}dgnHr!0zkm9K6#(uZ2+yt(oEx&M1XUgs9)w)D zU#Snj{6st7LL)@DdXgS_6t+>k-5bBX-U|%w<$frv4AS2zSjRYrP%O++!(?CBqEbHiP{5&K)Lm37RE16MDhF2xx_-Mp3Z+Br`T|2s_pVaQe&tNM90iTQaY znHH%{FkHXzbKTCjx>+I4bW_L%33oVk4|-66j#MLW-wb`Q5XT>$y61jFGp|VP_1-SN zbOZZ{l3j2*I)v|g734b1%Gafr*(eTth-DstuSA z-ekfP!`@6_fB(({_P;Ysle~QgI4)fG^BQDtkN{p8X;&%#{2*sP&NRr=)XDzu&aYgy z;X5=ZWy+>W@|9aYd;4zsnr3JbZxuU9AK;-_@#|~*-x-E!5%%{^^>YfhLNCeR2_Gp~ z=uEw*hu8lgBKrG;-v5o?AG$6=UryMa|Gne$zcp^3rC6A!jJNRfLeeMI9FW_!lal^l z47*6AguU8loI*cYraVi1`fifxe{urF|JHzl_08^!*E01`F^n=diyEi=x7XaC@n`%Q zf5xBjXZ#s|#-H(L{2717pYdn>8Gpu~@&C{GKjP{vBM$%o00;m800000000000NRWI z0C=37{AF+*OSXlJE-_imEQ^_$EsJF_Gcz+YGc!vTGqc6aY%!xHi<$2B>(_Vpi8wdT zUOj)VS`lB39J4ZKW>(e#4(hpWe3fFbC&@;GG}ZDof>LFG&lwubL%8cBG|i%Hon^9G zDcRZ_{Q|9i?hav@YWJ5V>L;jarcU8K{0$PhTE}S8^;Pl?kyY{^LSk*9?(w#B^dNvg zp;g%Z0HH#mrPqEsFCDAo@D9PN;B73W%}m|>di z_y`mFA<4km{|;NS(;*ypYk=qfhX>#vWH}7+JNYk@g!rN!XPTm3^oS`m@peWyNi@#W z$6GeYPt$mWfBCV**78lZP`=7NGSbdH!Y$4=EW=8*T%~@I*eQAkOTLw(-y$}`bCo>Q z_W@!+P&QFCePbP7T zRA`r9+w+ZMU7{RXm2*VW8bmt}u?WPF|r- zuo6sp23M*oRsM^wTF$&^mML3NtJ=?HlU^;IVQQ8b>?SbAJgJt?-=|q5UpK~8A>|rg zs%DY0La{)51D|4X58KbTOTauuyjd$Z!x-R$x35;3ud7ztDg1eh^5+2WZlR+QlB+$& zOXP=hJn_*kGR?G~k62HYGRhUndaB;X#~lXv`}>DX+v{7MXqIV|$1LL*yJ5y6X^h>! z_$rlpHOW?N1J`g>NjMDyFao`M_+Ps3VKs^ecuUlI2WsSzE>|de1-OQdGk>8wN6yisKA)im zJ1wx)i(Vq6nipz6!lpYsJk+b#svup(TL7N33>WFaKr3W^6CA_AKG3g_trw|7KH0}9 z6%UA#u6%mA0Z*`odZ?A+ncBxyt?U)7l*Hcq|KkD9(Q3`fcD+0}`;6mc`&rr>cpBf| z5%qEjc1+`0e+Jp#!%23T$G<~sWh7WItyxE->?;*NVtB>02%4oz^ochN@|eYi2>~cqCum z%^zpS*WnaSw+?>$4*qrg5Vg<@@=~gbeV%*t`CX(X&5>!sKLY%Eg!2;5CEP6vV}p6d zJ&be{9AuUP^dZxbd+6W%5q5%u6lc{Mx>@glY`shqZ$F#ZKv##1Gi0sr6YP-By*zuw zJIG_~WNTyWc5z{D=cpkbTHmpb*GZKtVjLz}MmUYK%2liry@F!x?_opTM>t;~4siGJ znk8c#eh7uTat~E10RXY~-?h%rcn7kKBw8L|C|3UMJ^(YG>vS`* zUgwxlyKIv&4iJzzs${EHX_T`l`;E`41=Tu4tL8b*;oX8dDFuco=PptE#5*_|`J}7= z=G(^NpLm50@DK3P_ph*!E)wj8`tc2%V|9EHXo~i4mMK<2zF_{z*CSgVYp+w-D!|#D zYuhccgA4KC5v)@aXIUxr3;7jNy8Z;6VwY>$E{Ln&Hm*$DBf>Lk578jkByE)I5*PVQ zv>oy#&{MKOy1rB_)^UMJtLWeSYeaA`-r+pc7<)g@X*#q6qJvg>krv+WMH;l<$rfNx zA)eer%S1${=)1pAvdtrGtkN`VDkTxlY*Uyg$TrhWFxPgdJd$jqf1$*f$uz1rlqveT z*<_?xN85}Fku1_oqTXPf9^)w&&2XBe&eAe3czJXPJU~sd{hQw;gL~l=Bwvnu#x+Mh zlVxlfiSx_N"cZ9pj1sGon7_Vae08py{i1M(Clq>C`!9ic%&<_oB?%|bl_gKE` z?4tcOd?3q~*C@c=q8z^h>Ld(H1v(KgwQGFbzUwR2`djykrC4@<<(!>lTA{;VcS@j{ z5p8dj2n+D_t(9xz&o+{1)yf;@Q7XnfXCE5n@pPN!6zKb#U#&DIQmQQ6@d#F^JuJ}A z)BfcQ%Q51I7{-NKag?)i`ENA!>@b%DlCK>ib=lemRfj~$MmqT>xx6sw^&C#0597^m~3ay|DDsg~EEkC^fekKlZrqb$y$uHkB>OVp|6_plNz zgFLU`tP{qWj5DVgWvUJ_!JY!W?V@OBF%HTVA|0#~7AZJ~GmNYgAb>Ye5I~OpGSwN{ zC@?LxWA-~0~YA40^N<7_$w3$%+guHlx+jo*kjK|X5a{e5!`@b@}} zYvp{xznkZnkgk88muhf|K7q-y%hiXw*dl`jYZTKccZ}V{u8|U+2y^Y{%F?oqlI~=g zvyM=#Y8MUmcmr)0#W{R|gt@O!eSjr75Ni5>*vDj;{+s_p#3qY#fNq(5Il^g(`w*u= zwo21Az|H%w(N=ba<`+KQ4AZni#V#p-uVVQWb)?VoXRCx+z99yd*+EX!-*T<@A4WM+ zt(%`eKJDY^<;>F}o|kG!*3--%V^zu*XqGAC9RL6)7=yfUx1k;wr(}B;vCrV4Zh!OV z>D?1hE?{m)*cKQIRXF;c<2<9<`MYG%PJ9ElDfKgnwoM}9T~qY3&Dln3l~&lCA|X!% z>#*)Vy?#DXE&kHR(?@tfIipycX?XpqM`DULFz6ZDDGKghp)yU+Jn`<+Ag_LQfN!lV z2&hpu^Nc|M3_Wj;WzygIC)QS_B-MLB`n99!t70K6h`;kaR-E+->hrs6l5J$BVWsXp z!na(vuzOg$IPlk52GDoq3j5eSeB=wOq;u3~$avcp38^Oi+$zOos(rjeoC{=%l~Og^ z_;=91HU5ch!dLKKffb5cImD~~d8J37N$MRm#~{jyV&xpQP@7~!r(ly9>S>*ncL3$L zas}oI`g<>brp7dPgq=aQ*pEWpe%@V7n*_nOX4zwm_xB0De%3&5(+ZURXK1z3KE7Mn zWx_*3`Pv34mdU>n6z*3qpjjSgmTSg8$uJ<> zIQt}5iTT9UrC3-mALeS2^0(4dbIy@L?j)OioOs*+)bA5iVrUx|W0!8?5tL~KbGb-h zT`pY#{aW;mf5ai%J8X<4(j4tvHHTsA^-;Sl$-ym%x0|CM`${W6$T!Etu!z0y>)`7X z+1B%$ZA^)=WJA4bqsSYWeFXTUT=fFY-=s}qk`3gGFTKl@Y-9haU$Vg@soH>MXNwr- zOs%LvdXs#f)~LWEyhV~~F537An{%|%K&ZN1RIQYCVwXU*tX?LGHp#MSPK_O!a?Wk!TicOSWX3`Hfm|mQoHbg{t&}D+$^7R{sz%GVHX$j`Ma8Ed%THu&F6LT zCiUW7oHuCgszRj#E&dVt#wh2f=LHIe+5ZI(0Qmra73uiTUu=?T_s!BHZI6*Ik*gKD zMYsk8EjH- z&=|WH*qu|K5TlJ=L->hkeXzxc`mMHcqy-L-?P+L_3$M1Hj`P2D#IXB)g)WXvZBQ zq2G`maF5;m?_k)+5zdDBj*vw#fFwW4=!QEk= zsF#>zz~3y;lC7nh*UJ65uYVqOGLF$tP_5!M@&mk(&(#VYBBvNtit}`nEQdI9weO&z zA<33<#dJT1`JnE(`rBoc@|Kut6jAPxZsaRx=vju^C8OK~J1W1miN?BM+*?LA3ehb7 zQ@&-&1-@ZA{;7210_`)HZb6AE^Nf$LOoL~zm#2CD$HxMlYZ&}lzsM|we$f;3=a~r> zzPZ+K)3o-0T?O8@pfJZp_#(UUn zuxwqc46v6b8QQs1)Ie|T@&yKz{W-n~#s;|vTeu5QD1(fuZ#*M0F0bIvu-fUNp1Bsx zL;XVa(iH2Yd*|>tJL=`S1*P%J9b{WTk>b4B8(5z#@lZ6w4&^+Z@djNtt?@MYq@-rBuUjG|D-W73q$8>cy3saF-q-{Q@M* zsrCni9m3_BFjw|r>$G3%8|1!qZs1$TEK~hczCj-Qgnr>3Zk4Q2j!0XuFYENjN41Pi z#tqyBdWrlJvw6H_e7vPf`6e;LEXapg+t)6~=w?Z#Y5iQ%b(+O|-8{WSYp^%g z;bhBjSEb4(DPW%cINKSLs)bD-^!|4blqLU~jql`p2i?A-HfNV_e-nbfEe7{FHD8P4-lQqOzTQ*%D-ytIDN(q z=R~w4ushmaU*~*1?g@cGwNl-*Ur3X*j!7XN!fm|*|6G5757XQmsB?-$^9SewalR7W z#0o`#k6of`RD}5xw0~%+<}kw!g;3`)uF>}%;rBOJAJPrpNf+N#t2Nf|D%S{%lY;H< z9|J;aW$@SQ6cq|Q{T)ImXaAg!e!fo=?!h)(%RkG>GSne4!b7k}H~Xy>=E^c(E6Xy$ z_`6&&>#$&teQd5i??9YgoL#)_pLN(e;2<)1p9({KF-B8jI-T7My?tNJb-aVx8xpLsTc;@KH(aM zd+ZU)%@^;IZNlHmJ-R?gp~WEp>8V3hFAMha30k`O{T}`9ubJe)KKUelrC3O~Z^#I9 zmc`3Qs1M~b%;go_1Kb+X1Pd_yC2INRk4N-J)L%C+>XlTR5KkAV?~lZr_h{fxAn!%$ zT_Ru)Jzt)nk**211qW}C{hTM*kS;ILT|?WYOp;P;l1;d~t5sUXwM&2S7!;c&sT2fz z0K?xTu2o65xJ}2lI(B^at$O|MY?Q}xPkBIdjrcf zwoEQlZ54Np)X(h|IKZt?R;b<}sg_tzS`6sa!6%R%Z| zCCdWlnJsk8HP6^@t$zOFyh1IjDNt();_~C4*d`TK&VwvOc`cq6w@xDU)YD~*GRU0=`qQGymk{tImmB0c zBB_%^yqIHL$6F(4Q5j{&_?>7+Gv3dc>v#t)RRInZze6m^&Llyvv|WU*w_D)}k@)Zp z{5Q-jg+YmQ(-0?bt5`STAxlqMl)M9iJ#SzcCcOd% zIS?<}h3LPQsepA~t|r?M{M9;ffmXCV)*j)yQ}_gPlH~$$I4WD7r<-JajlwWyngI$FKiZyj$DmNQ z5o3RbWy(dO;RDM_T8 zy_fobo%j5I#}E(3E}`%rCh>O_h{71r+4&2xJT-ZY<<9+NfzD0IP?4am-Y{! z_%P4ia*|c#tEhJzq2ZkZ~_;1ztE2>Q_~=^3&>XN`JjsfCDvzTRu zX;!F5gLsY14fH0CRG&)SA_?>@^^#mo?>DO?KX4#?g+o@} zV6zO9EI07hi2}V1($@%fak2K-2xn-@4dpVk>|Wu*t+ug^s@=S`aycd}qpiYk;DMn< z8j4j(#%209P%d%t7E+~`2*B|lU`P09=DWlkjrp6HabOz;SO0#7#nYcv+aIRuU` z(Bqs41=7h9=$hh0w`CtX%$I1pk9UvUDE$BnxDIj6FvnXjF|SkB$v2J5F`^%PKoJ<7 zp`n@(@3l>Xx%YFbmZutubj@%G3we8-rwg-3{tXfsdAE)?f@o@|zZV3&AvgG9PPy~Hk#WinSk*c0KJW0YYQ_Flc@0j5wp z-u7FgYMEOYu>Sv96U00@z&%IJG=73={AM5P9BG}XpNo1f*h8`r?8!3O&$qx{E#)3_ zh0rayOuvus8@ND4yb1SangVmPNaYyMG-4HdLU9kaMR5U+w*@TSI9s_bM_;;DzP3_| z@Br)7D@L+ri1!@h7Q!ZqZ10r7GI9??qYV3WiQ1?Da8{|&CdV*PrL{x$3LreLkY`$4 z`AoOu5Xd~>lAK^eup!t3EPsRSfcyj#C7XlkEufv>8@XJj)i>`@m!)M!4~}O8q6%`3HpFUJDYkH^B~^bB?MUh3T4N) zSHy-d$!5q8@m828y5FnBZlIwc&+zm0&ftf6H1fN+!rdOBnWk+Ly1okb>=5z}yo1Ws z>gK1Khq`ZlW}SEkt(U<(X_9Ia+xkqp4!r;UytkizqoDjwvCuAL9|Hkw6V}V*7_3mJ zl(&o4%god1<)OSdMLNal=Yv16PB#hFNy}DIE`R?0wXJtD!y_n|BHbmZ&Z|;_a zx^#`*`8>=@w_ut^waPRs*71(OHh{g!xYWy4qNkg~IQjm5jbxe??v~*A2#;`sHVHV{*a}g zU8ArFS1*aT1$|F7uTrF09B2FUw$A|X8QL>sn%SpY)bkVz@zy_M!=KCm)_;Yn6^gH2 zbM(VpztH*nK5r#i_3>*I2YTBiye1i1mL-!T&Dx=WdJxQ*iqnsx6CwL;A(uTr*91?rAy zDLjB`wd1Q>R0nr}5C3SRY_?Xn;1cx$b-S8)Q=1^x>C>lP`VppV8??=JDxrS08rCV= z3E-+f0KhIb%baWS9_|XQS!9&}90U|@A2YytnO>vX+bzV~!w2>ad+!`arqn)lo@JUY zOJ;@0IfG_ftDJQb!>~tc zNZ2^eHsyd6e~Wg`H0m7v^A6h@M`OBan%NuJ?Wb(RSbLfJC?|$l)v|H6bkje(0FKe0 zZgcfz>#&b>^QD@A^*_USidn2J!$iCA1>zl)WiraiCjj<93BO>Deu|m$XM;5KV}{8I zCh~O4yjtvJ(O^Lhj@*0gvaY$P;iGR`~%)9(K@hv$CwUj zjNk8XS^6f0B&)v>H7mKs!mTk*m6|WX53oTVI5u(&+=HUsy#kVy_{X)%SO>u0oKkL4 z6>}8Jml@+M671F~jmjp-hrb-49ive#0?W_Q8{rh`#{BIOQT7e><_tX`Fu;2Q%^~p) z;T9F)@*Y|3`z*^jsAupA<|xMtM3v$gyJOE|o>?ZLsmPRqhsC%e+s&OXf zNtGh->LoxvXqR7L(=0i< zz#p8WFs{AbhFQI$80Q9f6>9B*rZ{b5h&R{i-X3M@ zk0{LoZ?TKi$(O0O1b)DRl*z6VRBA2K9w5zd8s?nB8x*OPH42+01Izz~F5U8giNBqr z5#se-gLqdvt3of(sZBE2ZyQgsCB!?*W{G5+I>iG1#xz~FF46jjP^vlV`3A`biFoS) z?j4+;AKQ40!!Chlky}`hS06vH{*SS(P#9-6OA>7(T_Rrf^HnQ|bVxT;D?~X#yi79% zdxpA0yqsXC+u)v5YZ<1&-Hex5vC>~;AzvpnTWqJxhoxM$lCnM&>z zl%p%yPmfyJ6l;v*e*Q8|ICrma2^PZLct-LRFv`jb8QOI{pN;1<+dqpVF!`{&>E>U_wA7eU4Fe+53VH)4T@8h_G zLwim)J%o*L1eVV?_(KNg1pHaN32$?m2KR!$!zuFdooo92POc%t?h+GltyLK8VVaJ7 zp;+~2p8nU2g``r6bloMQQt21^DaI8dUq8jl51}7I^m8E|e|B<#3qRjjd!)-YF{>o3 zW3e`)tR?EtTZcIIv3Yv53qL8%Q~mtZOM-)&q{alJTx+F@bh^Ia?}%4;MY0Tc37sJb zE~J^Uwa>CF(J{_C_%Y9ezX7Y?BPiRX$PgTSA9;g1)FCvWRy^H&k`4Z()Ks{)LHrJM ziR=nVqi&rhMxS)`0dau$3NK&t2-V*A7v3&urg@<%;uY=6FN_Q=c<@a^#66B-VELsg z_{S6cP|q>e?V_vnqqHc;B+KpzpLZ-$RLgz{UxW0CqIjqWFn>pqtev*emGg z{RVN3)+JbA65y~#nrL+o`U|hbaEmlkjULF=UjSf~eTJ=G-7#>3$UDI>gqHq88;8lT$3L1C{cv&s59vbQvZyj0d<9E%bB4TpJ{eGx&S1;rhA$zU*Uv zD)|3q_P;~GInpF$kut`Paq8!1m4tnS^4s6HkAIz1vq-X;b7Y7c_Fk?2TW7w$eQ2hx zMDsY?I)l=8v|lmS=h)&6^~%znpAJ#)$QLJ>bP5VIfUUj&0M^Mw+giyTVxrSCc(4zp z+Gv|3hhio68H^*-tbFr)-B`;GfhooVipQsC)C>4cs!BENoo;S}#1nk$#1^3)vID$I z1O$b`6pO7n*~PsTFK51vDB*r+$}-{s_jx`dH~Q1 zc*VTWhxXAPk=F<*=IJJU!^{h!HE#f_N&6hR>Np#oo~KU@3bMt(^M!ugq78`-F`Qsn zrx~VWoLFYdRhKK<$IsEOl9G*Z%#$2Dgn&N!`Q;c$H!M@#!PUy?=cby2zLT%AkG+A- z)BQ#PeZPZ?aZoQg#kfWQ-hZa4L!4+w&)^q`0-Y&l=Sb4^6HKb*1ecEh)CZPf~E6iu?Xu%bP2HgLP>XJk7K z@pSQe>mr#z&zCmf z`DH3#AB(Jw-xMp>D76aEFDeylMYcajxCZ%1G~%z5?{5?FkBrg?_RQ0Pe6)!j;Nlz# z{g`5Ap3*GBIh1HoDewB~8O%AtGWoTOcYtUcc>f2vhqxhLJcH$HXci$}3bg~hi!@us z+eMWt1bZ64_45&J!{4|kmMCqJx(9z9)=5vYqTQG!OtJm0+b(hYsZzt=m!o%>{S=3A z*Uy`L4tW2;-+wYL(DU{4ca-Sn=#XzYCA4xQTpf{uKXeKotCP&d+QWtnT)rk zo4-PQ2mLdu*v3CYS|-~hG)ofh5bQodQSJ6|F)b!Ka16UfbNBKO3%7&cm#K2jJ4MKr zM|o&u8znR=(yw_2;x7TOzeMwlv{XeiYmB`}E7>eKK&ymiMmKASZ<@B)6ztU`i*U{= z&am3uM=R?TzeDWPQ=GkM*AZb4ccxaHt!s3Hf?(?nmao5d4(Hf0vQ8%O`R5tH+W+w> z+wuT0)%g(~cjp%37~w$v~kXgmPs34lm8cZ445ZyTRwn5DH&HvGjWXiF?S`f1b`K;Pz9NQJkGxY2&ve>h zR~GJkgsxJ|H17VQo4-pyzS=IDWM!Qw^n-SRVufHg!A7;rJ$jrm(3x#{kvYk!Orcef zZ{QT?CxdCSSv>QkeS%8vAy%kQtV@I^(;)EePq!HFMms&iO1}``7w2A}+92}`j(#TD zk*6`sY!}HoO?aSL(k-Z-B-loBzl-;^TQlz({>x~%C*aW}=lxN=BFmh9=?C90Sj=!P_DtvvyZVLPp0_hShg^1gR{+nU3~@sg59uwkuQ6Po)SsdQmu+L z3bo01m&li?mgso;r|GTIQLP+ef!t*o8D;$tVjDNihQC=Q-@^w0K0vy@inT#La}7&3 z4Dcpem#ZjMF37m7ChoyH=^#&*(dTo~ zrbj4{k7JZl<3JbIDUf%WX751ZAA0F+67InV=pPRiIxJJz=R(cE^I;wlUhbh5Nl$TG zg^NtQg3#A>3W<+G9eBHlE+?3+69$AI0U8w`Z++a}URg$_`O7rHp5+FZzjkpaIQUyH zG3b{FSEtC&;ZdKRLz0bw=Wmj<$sA*-6ysdC@_p;EPNABnSnX%4kxg@Yebg=E90|5Z ze>Tf`hKO;PVj@~Xyj~+>{Sg`)=;Rj0xXd?*_zdz<_Z9c}5;arPGD`zggDz$eQ{xq^NU_h5lm zwM?O!cr($OZ=7$Ka9g}}7gw;i`zzxt{HKBu=X`dHPe-v!aZHWVISw2d0M~!l^JU|rr+NK{9P1BYrn?4I65l$9pzjcYX;cNiUzlBG-`2aa2$2uQk!ri|>&sJMvH%cVl zS)-CE9pdHbon}CN6M{$Wu_OnMg#f)Tk7n^Q6(|~NdU4(3QofP3(pcm}z z&kpSbt6khRLWW7UVYcBcgHzNomS{T&z&&Jx>WErX&0tg*v8W= z^7o;gm8*1r=@IM{zC;r2$u)9{#y?i87wLjMImV-3re3=HbPZ>ja)P=`>FbNNYM5tG zEHE%f{IwZ){b;{y^&F!x_TbJ;GZAl6O&*YxY8?{Sh+0LLD7gD`EgwONw@VZt-y5U? z-L2EXK3+keKyxhG#Av5@Mwyp;c(*YgVMvxczO>2PB(CHCH~pW{clqX9q;F-W=`|{3 zKZRP~;KZ8k;)Xd@N(3g%5`&$+LaOvUf}k$?*`Q!&7{@sDawS_98Kx-pvX6*GTB;<& zUEZIMiSCe)&$+vS=XVO{nlsJvcX|e4T~n=KAB?b8D;(i^`M5;6h57h6r44c0N8~As zwzr9O3J-A$cTO|i!HKs*KMwHX?}fYm>9>0X%~Ojs^Ym=v(@lZr|D+(=CfQh~`h||S zZ<+iC)*xM>TqirljCu}x-zL^3_IV5TUbn15*(q5!_xVG#Q$KZ{u3A3I(=MH95aw2@ zqmzees6$)mN4;XCokckC&)*$9G$hP zKS_d}D)r`RhM3YcACNo)gZ+Gblg;CtN0?RWc92T7dW5*vq#HG|%9WPLfW`xadP0+<*V(lGdh7_wyLRA_L)h zi1`LYy1)5rn3+~3(JwEzP&doWuT8+$ADN~>{t9&(42C{HoFh5bVJ3X*QnDCQlItL5*@Gkxc>eo`NZTF-_k8=;LOIh+z2a8! z9qcPq_8%*B0U?6J`UT*34FZ3@@iEGgWVJ#u%K!j$e@V2?*L8^5$Gb#A`F({*xbtUj zSSR~u2N(GEUnjXn@blXx@D9w=JH)|03UhmgB-mXgH&4BX73r8@b%{VdKcsHw7i%ie zI>yT}53+wm^$f3*YLrr{+9$00_Jj~_+aSn19qkwB_kIVw{u=rEZ&Ed}p(`|CH|`N! zgHRu0wV4`%<1MnfSpt1<*N6RIsgSs`sbzAfe!XaKe z#8X^T6q{rquOv&rKY!CKed4O$Uto_3A}pd^<`}Hv-=M@=lkBNR5iT8rx>eqw3v~%KDwI{~Off`w=;ouZ1F!!Q5$0i)fn_1u zS)#E)f_?ZNZH%dx+a+LxcaY~EqfEKL0ArPYhHLn17t~Yt7tr?>iC%$ReV#$Vo*aWb zy;?b{<=ansdD}!zQSG888NmB*n1#2mSv0`=0ArP8o!BeDJT=UfVB-@|q**Tm0+^=_ z@sO+4Y5jP*K*8K~4~w^ly5yWM(`FrzZY5oZ`#s8GRA`*Ej)i?O&U%Y%77u*;hj@i~ z=jm+G&@T+|fPg{YDHrQxGtJ1i=x1uChkCn*O|gK0E|Wlj%uo;?e0qC^0KJ`Ls#Z72 zELFWkSfgFTN4fs=JKHwJ>>c{)g|!cO{WftWswq}TFHt@!c|_|BV?AQY_O3qaRi9@V zW(3FUw7L4-W41693X)vcNcIUBR;&^f8rsB2m*K9Z8#^>LK1MTm4)x?r8;35s~LQ2PZ!v8q>q ze07$=HlB2Si2DdT*^+rmqnKu~UgjONS3o}(c>Mstw}uu8m%>msOyddG6U;0(m}|U^?|Q#b;@k%W8l@u5v})|4D1R>Dl5C+qJR*F$%hm?G zm#eya15dw$e?c6kC;WAeK0{eAdyaI36cD$ERiWC?M>U<`0{*s4M!EI`yMrrRpJ;kO z;1G;_atDC80Y3kzm(#3RJH~|=H&Ts4-I5$j zbhrnHINAHP@~{tUwR*oai%wI?H>;=STglbkL2@jrZR_PBU)aZD9n;N6J04>_Lz-l)lcN0o*4Qd8)nuIc-_-vaMQvgRIoL;NXU&qB zCyCbA2$x9asdcia7z4cTpduZh@9U&A+xpq2acdmH?GDisoNC{1Am-^lucz2RK92~= z)@T;&5Q5!h86(_5T>{UaWu)2KM@4vSQaVCp?KCR%4e^bw7tGh=7`#ChA7C1lYnW%a zeabQ~G)Xmig7Ni*zr;R){K(hl>(wfL{PY|01xBN=PmFy1OAG#?TnX^)k8o?B{tL`0 z0}2r29p>s4W|$(~%FzRQW0xUY$GXJd=pLMDs#jYs*Pu|WaRut{bApwxwTx3>{6ZMPEhEU(v6_5vP~j95$^a0{JqvtNBHd0=r&%Tml#s?)@c?ghFSN?SSG1Avi`{9B>as3PCr#EGyO6-D2&NgQI1 z4oWw64P~Cp(jzc?UPZ%Q-U1Ql&V~Ho$v= z$=5%|F5U{f|5HpKAW2qlVA_R6nr~o#<`wla>|ogh_2PD4UqP+#WF&33t`I^v=T%Ew{hrf<>+N6rM4-4ENz}*FT zDbXoZ9^r9}FivA$33G22b&W~1_4DND7V6J7oMqQ76=|!LzDDv1Rjin0z*`IS(M_S> zz&_t4QYpWO$&&*<|K7kBnAwIvz)iC2WnIFIa*l99&HW<+Lih3avB2Jz2u-tnT)PCY zb{;WmHGCu51?FhL-d31WjRe~JMA3g!{4|Szde7GP_f{>>)5G5Z8V@i_x5yUhJ3w=b zc1k$FJVHw{*kT3+BVRR4M_*asvq|yw!aCN8uaP&&NU&KYXB!W7e}+^oa}TBb+0Q4@ zB2#aX@&v`#Zf!+@=w(%IJ>LqY@Q_NS0spcx>;IDt)EAb4r zPE0VfD2lbQi!3x3=z_k)I^h~`6Y!3B_;gN)wViHAv_DT3;vMZ=tu9pr{PVZ{8R0d= z=lR1q_)EV|u5?R)AKk<_zx?+|Z>EuV5TgB`>^W+SG|(?@A&JJG@n^{2>HrXF4)oK- zYQ+-#0~H#h%wFLD>(N3H=-DE2AE@}J~o^0b>J3Kp5)wY!;e^#yx`e#F^fAANxM z`j@N3+K0OP`${$w?5dVkD`Xo=HlLx*FlrP7??3aTpPxjFM2nxFWb+l`9zNp?%Vd~a zk`?}*b)sXmON3|e85++d<|XM&g?i6d#5233o-gTUyF_2Q%M>iKl`6l>iFH?~CfY`kHO(wJ)!2FA^lRqtq#f3o#^Wl&8!2r=ycPLLCxyLdOL&!n~tHfjqd)u zBQH>pAhWEQ<~0&gwu(j596likcW9^n0o!;VU~-l1e8BfVDV8;A+eGRmJQIYgU0*9z zij}^VZZN-r60NcQ{CLDVw~hLR3I_fFet|yB(WIPcyGTa9iFCS+?-rJ8;u+W`vPkO} zlx1w5+A5i*iGB<`{~4^%fbbIXdKbq%tV**=Ss^dpVehkCZI;33UAVgwM2cgHmdp1E z)E# zouimXeAP|^yq%#qCT?Q^&nI6qD#bkxu#9tqf6>aD;Pnq~;pt`{5Q2YD&%!v{B1gMS zwJ(*UTj6gDbvDc0U>xR}rx@j8nAj!CFb=ma(JN7PkJKm~V<|Lwc~i{>8V|rdc!nuf zd;C;rRwK$d^+PJcMXH%@l4FRy=bZdojd@P9fK1IYb+gP9ibno9PKH6T`tx&z3fjp} z8iXs6kvPkHh)JFR&t($Q(=IN^3oxMh^9-}xr)Z1={(*K$A}zJ@QjNb*lC33LFmA5l zH_6bBK0O!7SjX4Nnq*udLO&L2+r_nsAz!GKRw!!}Q!Ou3HA`BgjBu8!0RXMy!Jfdk z|8HcfWuq*l%OEfOJ@t~VuSl1$_jL0=DLsRgD(UC;@#yEq*pI0ig%rwyV}iVWybiG$ zhJUglA1X9v7%hDcbsJ$PJ`$@H=&8_rgVIk0KL3BCbxJ=#BV66WHz-A0*~NIrPBA<{ zpCdei>t=Z*AROEy7isO0`vkZIVf_Ah_6v!&3vmhb{n7;vu2)Ds27R-{6zpBDMzA+e zr&v-i20XuA+&zi6?G)E9OuF_bzH0M6TDU{1b(vnD;0B38Da?Ifh*8P_3&VV@%N+>! z!~t$#D9v=Z(;&+PKjLMzyg@SQVTkdA2zWdH!(TBHrZ+!4t# z<1xw@C&l71_VCvjx6kvm>+GGNug;O4!BfnZ$-4x5_|}O$gX3(3JL7EGhQyoucvQ=pzqy^hv*cW zUBX05S!R6#d<|ba*O)ZQ6bj>=jk74%#QSI$Gxd^;U4wu>{R03T;skq_>2A=_Eg0mN z$#*}J~GbTKUaPOsSQlQv$j16+?km4TIDnmW~1)E{FNJTpX0^2V3apxS> zC)OfTpxVm|^WH7s=?gqR&~JyCXsc9Jvg!sF;R613m@Q9x4X;_bMqQyI*9c)h%9pth z`=*UE(KNvw?xF9?H1{d?7)_=b_*1pY9$KkJqx?2@txA@Kuh%8Q%Pa8yFHx|K#rh2L zYE?c#SO>cVU_OlVj&r`eRw>W1f;^K=9DjZV{|(nFeuy(qr&>11!!!5>Mz#Fs>mRap zCF+zv%T%eBdj$w~vkhhH{~PxqpAfFi(ykD>hd=;JRJQRA(gM9GzdJ@ZJ!{awSy z*!A)zgbZ`_GGlD@(zL&;RFZCkfNE6erT6flUCEaJhHI1Wm5sFX^ba!&^#;EF(aRg< zNwyFiJ;JQe*Gd0Y;utO4aR;hf>=P2`UoQIu9b+5rM!!ill;D?PwoDN0Pcs_lG{k)h zFEoOBAlg=H;FKs{aZa>}^OIU&P%R7i`qLu$2{FOTHL66ei4XTzvB8)25+&m_*7;(k z6}s;x0S;+~c40kALllwz8?+fF`Ffj}F|KiDtK@E>0U^uu9Q}Nqy^Kc`JM`AEun)E& zz}G)6QP#9vXr zcM@;5iWBVC$qsY*`WI?Lyxe|Ls*G?U+4yhV{}VNGvUL-zhS|`M&yclpD8CPIjj|YK z|9l}Cp04+`&*Yh#-Uj{+V=TtDt_kW1 zs(Ik)=jiHxan1w%Gxgpf=9#5xT%(Whsb_Ql zANJldD$Dij9;LgxySqCC0g;eU1OWw6LZw3qX(=fs6i`qUkdRV91O(~s?v(Cs{_h%& zJ@)TC|M#4CKYltN_I-WWV<3aMpXa*o`&w(Rx#qeR_CU1?1!sV#*IR6^+AjfotD$B5BSCD7O;{zgC!qAI^#F-|VC6d^O1R^G`67skTpGortznuNmgfHyWh+cJ=vVqRnLr zi<^UF2Hq{ z_*R-leuxKK*V$=~g+wLd_$!nanSu>0Q#wB$KhIY;&;Fu>c3iF2EAcRTn%e5!TdPeB z`k50nr)cVh8ijkwFC4?3pq)N`9^oq4Ot3vqbBe|}>>hgM`w*9Rpi~pV_8-*WKcJrV z@%j2I)To!9px=Kx#%3RL<$Kr@#cJ?@w0whc{Q5zuPL1#pHZh7ps`VSOj*Qy{T0DJ( zClu31giXB11hTbD_>M`p3aQ4KMiGDhv5w8NW$K&xR%l(Kqa9`$P%tsiPEQxeCfK_; zZxjxS#68f>7XA_R6c4Fe#x-J$lX6tJ(KF5}{`%K@?`O%p!Uy?ml49)q1CG%?n!Ywe z{QG|pZ&(oJdv+e^nWdX~vtPvggKLPNuY5h-0?8)Mp6Yj|X~8isR}>7}x54((ZF>Zp z6zRrF#T-*MFRhdBzyGMmI#hh?hx7@iYcMi~@*n8`Tcqyfb+J1nH^`K#Jb7HN^+oqa zVb(SFL9dsAE<6)x$Jf5B6S4JNAnWHjML&E+yrEc)jI@nUx+YuSCbmKzYu75igWty| z*5(niO2#vQ`2O3)1bTZ0XWyJ+66shc(Je5_RH`!0h<5sL$0!qK!E6(lr49(K<72IA z*ZBmk5##RQZGP7l>bX`nMvb@b80QnvDVC%A*^qf6(eh3z!th9zZ=d;@q=tG82v$pO z6Q$l|8)2VQ`OzX~A9c0pzh0?iadrn7uWUDn;+$EAN0=Iw$mh365-oGD`Gt*hd{=yH zYxvPRKI5K1yLvI*;-B#EA)ZM#eBBcqf~_TLoKqg5?$N1t2v_fYEYh%f{fpWpoowTN zibr6;Gv!K$7>pC==L5WLl3wmwWipK%qt&YNWy7rDPq0tkSy?1DbrM{WsG5k_GaoZPsW{Ic0WIYjo*H%tYfbq!2Tm4F;C3WV;}sz z+rEDJdXmkQOMmkIzd$O~Q7u<5b&5tt;_W*{Lq-a5-^KguFJ;|CMxvXGu`^DyN~W7< zAI3a-6kDOzE_N>^UvG$Avi0+IqAioOE+Mz)mdSCC{s10{bnWwX*T^lRJYDIgAkQRA z+9ks*{$Bo`QT7@7eVjVE11y8wMQZ8Bp9-_IIY!^rkdXa+wY~;DjkkRqb}t3%Fi*!b z4Cx}>INna8`A_h7@lwn^L(NiCZ_75hgqdX^U-Wa&F!}_{(l<(fh_%>)-3&>)-3&>)-3&>)-3&>)-3&>)-3&>)-3& z>)-3&>)-3&>)-4D|JTw0+UWuI87jjJ+Ze?%#|ZTT!wlt;M2m2zT%BmURFinCXgk9U z=P>S`XglZdD7#=c>p1H;=P=tC{p=Ru9xm1)*(&-8{VetY(-g@%?jFs&bmOI;N>#9= zny3~9dU*Ti=-5Z87Nr}Ns-zob8YG*MkY*T8(WV)hCuQp=So(PxW~vqC>QK&2(<)SQ zuS>KP=)z=(d_D8`+XS-pR!Mlf&QUi$GfmYfw2Pjg-~LFjU8p12ZJL&1F~r3%^WNMm z$Tp5=0Qur(_6D(VC+)BMZ-3)kB?Wo;`&KIF>%DZyGL)-3LH~XQ)W;w0sF%KUxc`=7 z88k@Bl^Mn|4X+=hSRf(6XLw^-sy@p8(xH#fEEV&Je8ndq!~^^fQ!EU#0({a;HH+2C zlq;WviMMJN|G3;DaXr`k{r4;IJ-mKUtSQ=l>yugPZ+xvHBqZzu#p(bbv9>&YKfe!m zlB`PAw+S?hCs@u=)=AD#rJ8{JAidQeane7pBipJMx zAG1I`$&9;Kqi~3|NCk7PzFhMPdi|hK=hZ{5A(e_4d#j{(cSYOPOUKx_2U9E_zWR;- zDBdMfFMpC*phvO#*;CeW*?ObQX36ZE=qE7Gb)BR^rd*YHgKZ4^fcBSkqhhsayF?4a zjBuw^6X!7ThIFG)7u*9>i$t6FJFMf1)soHF2V!kQO=80E9BZ=`Fmm3G|?vQFU%v8^spzn*K@Cv zuUz@=9vb4&ESYX{glQK`x%5?=uTQ;HxO1N7FZ?pKPT>{uEke0EiIyYGa5sYONAas< zREv4~SH9QDnWS$LT_8heN*`aTI`)B4=A-x)3Gr6)l_aYYjYF(5wFj>)QnGI{P4)Bg z_2pidubpJxA}m#Z>99;ex^{x@8u97Y2C-7rhdT~0^Yq2qMmRW!ef{HX&rz;?|Bde) zML%1qyo-msC((j&>={h3{oecl`^zwEYx~VTOHFpoe=f z)9Aw;x;gEy(~M8TxCc?r7pWShF^^>Hk1)H00=?yHHH$NhPtcbrHH*vCyn=!~6{`($ z2)8O!zFbQ;VVa7y`>K6CSGn>xzV=t!IQ$)=P0!$Y8niy5wJ>HC7WQ8uk93$v%T>-_xd^s*AV8B`FpjpMXIOIL^^!^e_Upm zStT3csF$^iRVyQ1qg+xib$E$>GR~@7Fu;>&J;Bn;f9C`08EB<>2EyI83D!yWaqfIT zzG#v7a3{-fh-(Kw`QBgn&^vMK)8!wD){ZY8Kd(_J)Dh?*UGoX>41N+O)D`4Kyz%`C z`3lU{i+^PPUb6Y~4a}oL9qq4^%#+L(Dea=KAB=E}vd2F{zJM+&@4!~^DW*>0B&#N= zMJm>DwX#z*wX2@1a*G4$#XBlR=h9p|xOrV=XKVch# zp|=7(N0`JL93%X_@T8xiinWQiVjZHLVjUh~^7a#NFik1c{Dlthf0}uWW9CVo|2kuY zx)iIqhG>7SlaQ{#9VgigCyYQ3(WXrT)uLwc5Z45YOv5HotGI5#ySt}oIR*sV5w53b z`gt3~->>)t)XUz??&BL{ldqMnuU2%93VV`$(>o!WwD1$)k9^e7EqI4(_39Wt2;A zEI-~h$cc7Zpe|P(XLXIRPV@?5nZP_^A0^&6L4Oi@l1?Gxv_?s@WVNE@n`uU>#lN0@r7GQmJ0B>QTq5Hi z5pTply8m{Fi)P+9BhI#u5A%p@)z=>h2|SqC#!$~#CIq{s8$~*J2AC%gvDimx=26d3 z&INkJ+GHBU+PDWdhy{A+XSoMO+p!P$d*Q#Zd*myk?TphD%Y1z@4FWyzME~d058prf z3C1zT@c}l_urnQ+<*K0v0i?GF7?7b4tP;s&mG}_xdbB|xz}guSIJt%ZR2zbT_Sh! zCYjMrujl@auUjxrW0-|?==egYi)m_=EWoEn;21-t;)SDkpr4<0VyAG22%H$fo;C>| zZx`r>J%R7eE2vrW!E5fpOF!*mKi;mBlWZ>0SfDP^pr6$!=@JU@cwt2PPO zb74Zxx2vaUhFPNR8YK^2^Y>;M{*B)(3DdKXkX}8sN-EM~9mhWK^CMfee4|?a?CFiq zF#n{NA8(g@#oxC@;^(F7x%M&IU$bwHvS0pj5Eu1=d~Lg^YB|BSXuWcOBW|Z^okD~2;d~p6tw8+=;_H&HT&r&YIDGg6F#C;^|$QPW$#~38*H1k4T z=P2~E;0Y<##xNt=4$ruJEktvQ)w1?uM8SRv7h;$9*`~+Q~C(|g_PPZV=wqDjd5NCgt?Ec$g%^C%?(;+UbL)u@G&2)1= zE{8qw^}n8bf^HWp)9~KBSd)8jlpW)kVdlqW{$8rZBTR@$UpQ)iz4Kw1ldtb@{2QMm zT*cac(RK?GZ*&Ul6iPRC3zn-kOOmY)bHca$`hi8t+xrh*yM?ciD_5GP9b?2lN;grc zp`RV*lx|!j{dvjZW&EQn-|b_%gt~;t)wS(N9z=atu_=c%0(f;Zh@#8Y> zFN2&b-#tRW6<@Mhp~fTR0-0qZ&2*hau{!yl`TG@e>qI0Zie-hGb&?5|4|lAR60Orr zrx^*hRm)}TJ47D7y8L64Xn==dCdq1=e3wY%3x}7b>P1=xIbXG#q__vGl;H03 z^V7?(mB&0P(A^-WUXX6&97a7OUE}Xntd?$6sF7$vImbF&rZ`7ooL;6tIVW91zTh6@ z9OfPrZ-rByZceJ{Z;an@-ld=Nweq!aKm7N9k*^i(7V2W2BwyhkB-~mj5$+Ug;~L@~ zq@N{QrJ1K%6l;6%8YY9)%f{J0etzwXawW=nptn+0jlx&$_vQjUEEA|_`FdG~H1kH8 z8YS(bn?w&^bqbrMGR)lg{5Oholyaq0v~AoVcd+MwqQ7u_`m8~QzjuvvgP42p2y>EI zKTosx%6IF;_vXT#%9Xf#;cfyw)r#6*trIDhkuP$um#GbNlCKnL{k+69HA{bjj)bII ze*bN~?5A7L9}{mNUtk}6ztSr18ZpJh-}^Vt{j2s7=7&3c zeQBn}n&Pc$Wycur?oKnVllc1oymb3xrLs!Jf8OV6WvgV>iWtXFpBZNTC;liq>6%4~ zN`*(r4t|7dj{r=v;~Bu&?+{@f$K6w?X^^RxJwZRhL_1}iW}0G|;O)oXVIO6jW}GHn zBis`1Bw1f0o0fgu4Gv_(qulK7XIRuvE)kBDn`^6eLgC7SU-`a5PCrY$@ju~T{kBdb(ej@^A=rlKzE=K)<1GC;NtKdR(ke(v9RR7sz65QccJgv-E=9 z|MwpMe=pvCu{N0hK>G{M7?}p4F35Cv2IT6b8&S_t&%6V#ek0sMKbfcL5=yjIFU{9e zFP)>KnU8kr=dG7TJyR_|K|e#yFc$7iu}HqhHFWnK@Cg5G`2;w;Jj8O28st_hBicO1 z5bBDtAL3#kwMqD@4QKBhonUv8RX?vn%^2Gu7JqNp6SlD$g)GC5x4DMo>ZTdLUn$T% z!jx|08iE{zee`B_r|`8e)`|Zde}vF3@DcrYQ)+wj~>NG zx`?%97{7FQ_7s>8yxkx#n2F>ZrCuuC=oW64dNUjHqLf#w-n(_`b$`tOr@fqvT;pM&LGt?=jF}7ujan>m37mk@m z8YNXqlgw`{!=9{=zc&weOE-CA=@u^15$qZNDA-fI)GKJ2qC#Z{|LHT5b(@4fzJGr2 z>*pC~cm+kcx8dVwt2 ztXNI9x`XfQuUc-A@+e-TGk>p4gM2M8JrE;8>>$#?Hb%IGzeBjSOo4jl7XJM43&&CRR&j$I zl68@eAuhhYCaDyQc^c9+(RPSQEmBaW!&fWhv-G+Jhgi>^o}q3NXcgh^p`4SfJ4J`O z1DDdz%Q-C7R4-euI!8yo!Z?j~YMp43?iLPRw|73Mmh%ko46KuM3tszzd~tycvv~eF zKF$2kOUjinzdgi*bPZ;>4Rao1RVnG`wTr^vEYw*gW1b{itpW zI>=TTr}1`KCWJft_)yMof4uvyNbAeBVa|SDm_n6hSf=*)IppP@!KY{yDw55u;`Fm2 z9tJu8nO*(w%R4a6c8tw7F2`V#NVU9D`QfV?1-I~f$#Qkb7swZa-8BmD?w+9I?ZULn zbfI>44{g2~0VKa#9-4*U5PX=#+u{<276nJ`U51plkHSCC11v1Wrz z^1bYvz5EO_;ckK6v39Q?1bL}cz==N1h<;L`La^-~>K5)4ty_S2G55_t)Nl!B+U6Zd(HM^HwD?iT4 zIQ{BjnyFYD`>1=UVOEJoq>E}fBIs~_SSJc~xkRF#!MW2VB-HiNfohR$EZj}8`Uq35 z4m#3z@cn%Uxqn`I>0pvxqOnBz!m(4BXP}QyvpCL{_Lp-Moc;a0uOCD^y*Eef(*uus z|E+7p939gX!%U=0lT?lY(-hax+xz^zmT&NPgt{Of8{rV@`gBV#|LHTx?)iIfd^SrR ze)2oF-D;d zFb{FI!JhQ9EfNdVyLenfG7X%=IQzW)A|3cU7{?qV%#+{)2e}*h3U9wm1Iq-&Ziw!_ zVm0$5(-io>F;B9Ni?xxg^YuwJ$<|9Y)BXZZnPmcRSFk(Wje6nMrwG?fBi({$PhUM8 z=G?)D9^p^7unq~fM>ra#4RR`#Cz%U$pFTqj9|j*w7(jqeFAFb3w4S$W9(Tb#@H6A9=;l5+rdA=bPx3iA=rNX zz}NqcIqnMVv?q{AiBCGzck$Rezg zG)lG!N;Hfz53o6h)k}H%>1X}?3U$y=xQ2)~Hi>@GGEN_3pq^nLuuM=avrMd$Tp;uH zG0dQzLB0ps8u)@DdIt!0)68>>(EdU{;Td2ZKSMpnz&M6#6o2m#<`yCMpky;&-yk*}*?UU7#jk;TdQbHOvy}fc#&q?aFuTgMQxRd$&GaAV)hf zO|gx|*vm9nC+^}!xITQPQS#rjtN(qan$gY402V>%zBJtVK(!caC)Q@2h;?X|dgp^- zmcz?xMR?*`#g(dFI>^-}S}#-7D9F~Yk#-6{eMUEDmU@6qwu*dl?MsY(KkppfJWaaE zjnCR&2Y3*}Zx`hp_6X?`au4+ko@U&|JHmYWEZWIFhGhNcCG+Zfy~Aj4(|>o(8AAbR+vH#M@$RSchV5i0=QTpO8BMcZ7cOU+Gpa+UX8H zf3H}ZaHl}eDjE3-u-#X_2YV83jk0GMhP!nOS|ydMxv`@E7B2bcj>2}A73Aw z;l>$Qhj%_8hX3i-jn7$zkK(Hpvkbch{rs+c@8=z5hf{}Zs71m!L$y4?CdYtcIm=MF z@~ieCmRgzR8_nWMW$mwav5qeUdgN=T8P`b5)RZgb>h^Gf`#}u9R6X6qCDJo^jBSgM zYB9j){@WA_pMWhw=P0POK7Y(OU7@00ny3Hj;p+$9f#GhqKhDt|VZw>qDg5)2bR*9| zwPNzU-0OPzR!NH0E98~Rh~W$LNVL4Y?;dK9lV&=_#4$oM-y?v0@l{*5Ai(DwWsyqz zYqS&f!YLZfJpK-JX>SkSC5AT1fMZztp5TTty=7)X)RYjpL{$BDGsB>K)zk1jyd@p&H9_EBT37exk z#wb+}cT2QpndlHvu8eZtBnow(r59_nkGcB}QS?nB)^U!Jd&$oq^9;0!HA;uOc?aJ3 zjC=uV7pbNU<1)2I=@ay4Pv713^JAGX$RS(x4lGk+nu@W%^T8&eN@;~$qohHmR(_3C ztB7c`MFLTL-2$iR5sp@It)gGFzbBz;7Pm+=NqGly4IN_LeRnSz6f^@oSceQV@PD;V zl45a)b%a@3;D_rS0A5H7vlH{HgUFvIzwEkX3Uepo}=s^Z_m*^ z34mywKeY0<#qW!$IN>-(0l0L%m|Ezla?<>x>S<)<3s!5|H z(7Rc3k~vRbra`8`D~NNLX-clHMS^(a*;AO(0aFo8(=PvT4|RAc)HO>l(V|-3%TKkq zPT~{|r|<=GjD3p5S8YV`P1A0F9Oi71DAAx=1U4Yas+T|aI?B1@i)&vBbwWHmgExqQ zW5POwDxgA*WV2kIe646Z`pG$pK#x=t`U&;{{to0GREzARa&?H}D^?44QZ0(NqMdS# z0Fxut#4{k(#5A>ww@z|`zJt%(FWP>HCDul;%|2=$Q?B~#>Gvyx+%*cL?C2*p2}hVB z9po#M%qQr;P5K19bU+k8{*gdWjRL&?OEe(=^9;s1d=h4pAlCNAQn@nz(Z}0ZhmYbR zKO^3lV%i`+!W`m)X;@f?8YP;=4llO|6Rj`*c=nWNvr0+5bc6#@{58^iJ>rdhoF`$Y zXdNQ29+s*X=mNhh&@;ip-#br}eD54(g?xkqR62~)r)a>wLu|H9kbU#&H`6r9<~h0; zd*#XonRJr}uXC>>ihudX3A#{Mnkm$T1HH}P!?&zeboX7oEbF*>DZ@;OhEIT06Zd*RuaY-X4Nr3C1T zkT3Rd&rpdsCRh%!xQ2`}sTaBh%~EUSCs^=yY36Mb?tJj|k8lOfnPk01qEom{?8~*+ z49e-m9Ecfk?^|G_{L0&H%F8>I1fAuic%r)Zi^HTK{a>4Fd`V3>!G{+Zi z;UyYHS_QfhuFR8$SzSW6J_UO|c&%D~iq<1Qy)eq&EQtv7_j~Q&E7YK$l&K|JSE$hb zQmLp^o@Rs^Op=vnuufsAdbi-MPp==ig-bUsQb{+Orm;*simy_-@wriYi%>rgf5$tp zQaS92QRdxukDoJ5A^!fePBhFSSwBT1TWyp!OPyx4Na+@A6N6~@>Nl~r4|ni(are$q z;0fjJXPzWk-zESS2I@bc0F-RT-D4kxe2{&VYv@ndAK7~91^!-!8DRbR`VO&&ja7|6bsK_yj_(F_0kLEI=MB{V~ll@hp)t2bFa@Z1bV-{FW&n2d7$@` zut=A4ljr(f)!;+_R_f_T%k0NjFKq{KF_yup8zu7wU{~e7xNz7U=!uny-JL zcaRsN_@-%<$~*)0vQ1Lstcz64lhIB^TA*tT@u*Na!lYWHT6_|Qat;yM0yWJ%`N}$p zP}dnM!8Ry(C0Yb}PS8c$MLGm}D3{1rL^=?E{^9&*o)qk6n4z1aUZ7Ye-jHk-Z)G37 zKn6uI@L$56Diwm=?xEla#x|y(ca8!ayHCIoCf%G>(ydQPR@c6?ikrVb!UU}!qUfRS zpeC@3wS0ql6!s+AX`1osH>svpal2TnB>g<+s0i0_R?@XwpTgZ_OJIk<0OQL0wsz~e3 zhe>9Qk}0NF4+nV8P~&WI_oSMXD_6+d#LQA>>EGU8qyoLh9A>6lMGMg%*AVNtPNDYK zUVfBwP%d5lwvUsqr&ZJ@_U^8IjBOml4EG>Rj?Xam4wP=3qeB$mDH?pNFOV0gvkY|$ zUN{zMHA~XXAtAxEt4Nn`S3wm53@QH3O9#$j(ltN7Q1>Ou+aF&)sFxk#I6;T$ComZ? z!NwwG7f+)EQGDu!LoB`gbQ6{d&=H==Rv7(&$d)>lcIOgd?H3CumGgR%b1lvtgY-5Amw?E$g zs8Iq+V|c%-m%g#Ijr(vX-2~+v^GKvatc`MsV+08av>!P8JOecIp!5-K=kG;70aYi* z$lt2&f4(5rgYOlx3y}`_TB#<+X^dn3UhD(hJ*FwTxk}{$o?iYn(jEc(m>PvO(#OvS zxhqsarSabU!Rr@}Z|`pqXBelNEmJg0LN4J#{Yx}nIxtT@eU@otlv$(T=Lh$ChX~Y(eqI87`zSlqW%Beb-^?%wb?N0J ziVt_x4nF7~8D^ZKGmL?MJHq^Y1317Ck0)Ws7a|>+#hFH};+K9tds-{MNQJxi>}jC) z=Nmi&!<@GJLdCL74fE(1EmR0>5<)!Qn=exwVE;+>%h&hD^3DfP(7A`^7;q0J-_tE9(0%-z zxBm=PFQ08}fJdsyEgV$4GYmZfU$u1#6Rp`t$63c&zg*kHb&b%^LqBPf;u?a9$>b}D zd!`ZOEk>C*`*3Qui7ivi(%(x)9N#7ZrnuM3c8F{cLl$)7^ATpS zXO01!3aMtE!HL$T>Y#1HIuz)UX^^cKZU0^4muv<_7UMMgC{%_eo7YMDc?Eh9$Cqlt zJesBF@0Dr-b(wsvc+ zL%!heZ4=|~y`Eby%iC}MKFMmDahU>f{6y;+22gD0UcZ@LtXU^lp@MQA_THzNwhFc1$kZl)+&yEl4SMvKKV)?AM!v{UzgP2D_Uauc4P{VALa@9*e zi#0KiOw$^r?PE~S6sre#KHW0P{O`)rf3{jAEK+EH#oBcXs+F~hPcvR1kFn|Hf4d6R zCA-)HU8^KeMgjvU*~~pi`)iu<7cJQ;FhNv{hghQRlFd8=)CY@32v9>~;4dNVw=Z`H?I)z;# z>1Tl{?Bi3c{;Q`Akwv)W5yCp2W(r#BYDLar;|z!^Ki-bDW1ei3UL`|0uTg**Ct__d z@7CA<@$;}J(5vGdwLz>~uuY&`>F*0?AzHpSU1K+fr#U;kphF`>wk#l_#(~p(=CWM+r%tVnxrI~i#6xygu2?qW*C6!Q>ubgrU$PnQ9F*ou zbms%XwnfS?r(Qng5^%lHRf&4`?W#|}1j`&9^#b9RU^n9IyHZtw?wt?NoseTtD^ImJ z!f}A@9M#9yBVd$ikrMXAI`PAub&?@2pMZCF1$so=W$W!?3w84Jqn)&h^z!j`(@fh% z>E^Hx%-=(g5N|)?`1?48I>Mb#pJ^4Tmo`d6FN$fJLQSi<VRjM+~D%J#@ILi4~?Hix}WdEm_o<3ukX_3$@R<49j z#^;Y~6uN{4c$%a@Vc#MV-~-xov{TF@?!i+u!mSNrrYYWjzP@7&VE+lX2)D>qrJA6p z0}<8d-%GUp0-1i6uMg``ra`z9`V6ESA;yM`m}Nq|74kt)0TFJQrTPTu6b5=zE?FnK zL?&68r50&{5}J8ZvzT+(F80f{LoCGcvkakoa1R&i?aGx4)GZQ_bBMQozVZ2nOJt-A z^c@vzE>gXE81DA?`4m&W-Vj%g0m(X4A-e^k2kFj-MJl$jbQ8Hc#FR(BmsFEZ;oWz@ zsC$F}m*5j1((%F(YGPANp26uRE99)>`gz$mQ!MVj;~9ANv`MN>OfNst`U3gE>k*DR zxlUoLB*HC?64Wz4Kg8K@h(C!oKi-CFdY0j{r{$`(^2zt0QxKTR2-h>zeVlCq$!4K0 zaObX30ELcF7tto>(FHQbv1mIe4?+8(SS?p4*7hgwe|X+mCV*!G9RTP`dHeTqCYh-h z=x0F(AkqObMzbWpC9x^ zfTHZG6mV{CebW?mk`5@Mu~EzYea-= z^1aVD^z*KLfqQ^_%sdGS1+g~fN#Od$TP0ec zTXTZtxB7#>cbVcp`(6I&0^N{I1Jruqxra_u?m_0seH_q%P%l9Bn|y_4zCq@CZkJG~ zyGx{Md8*m#2S=D+wZVtnDAWACQ?yEj!^?2DF*c}RA-aIUeBtOCLAhjpTF~7KRY0i!LANL2)<0L>|GngES;vJtDV8yh zK<|fnbch9gZ9180G8|sZ*#@p`SO& zY?yWbZKlyUt6u&Vp+Qch3(C2D4D_I78K#?X4I$3HD^-nfWEmz|!33NIYWGmnw0CzW zSOUGPl)|0}cBh&}xPH22lb}_^J_?$C%Qsv@SHBH$y|J`Os8Fd?PPFb81eXQY@o1+t z(p#VY^0Yu?Ili!u0R>^FaIxmycS%<9k8-cyOTIv!r3dXL)H^jwh&JK5gtHjxfRG7r z4%7acVge@*r~>l$VjM$l266T0@A@z064fI52`E6Y4k?$wodcK$h{|N^q0;CR0OvIH zn-6lw**Ztr#VXWj%o#_`3apG8_N5;Y28Phjpzo7frZx2p~>$Jl;c4s|!m+#)nd*UKN_ zxcp;@a-PQW4dVE^1@58d@B8>XgLm;5r=y+V?T>u1gD+QSlh7m3AY=aCIx*CJkQ+F* zXea*ObrOLdti$_n%~H$MbPHtb8Ki*n_)FZy|v%Cq!Gn2pkuONirx4~y=1Dz_(!Ac z_Av+8&~ef!Y?2P|8vVRS@eMMi>JBei$45A-ls?};zA#I*i!IhXN10%upG6!$!#LdS z^#h_!v{TBZbCd$zCMlHj=Z~Sg(L3Q#aoXs@pou{Z4siMa1UY~0%wD_yN}b$&oQD%e=o_pRMV3%^Y^iKc)NJJG4|0;5-q`=Y-1m9A7InWBVUxNqntl{ z1)Z*v&4^b&l&Z|%yGE>%)yjj0pLhdUuLc>PfJm2hl68_oohc@=Rg08ZJH9^A_Pg&q zLRcnpulERa3+~`UraZ~)6A&^w`C8fWVk4h-De z`*yL7()xMyvo#9PyUsAPP4M}KQWa>lGmOVs1AJ@}!rk=q&QR@Q(@aG=GK`y~vTuI4 zgE;kbbd?Rl^>e-X9 z0Un*g0UoH9yN42N4{_n_tCbONfX{RC-Mx@L0#|Alw)Q7T*3@dZsCX9)%j=PKYIV2KI3%mk765CYUEj*`eZ+WVK0jj8UXTvVMpK z?`YIBr|3C4z5JIBiPoQQ$kl-(3F7$eqVLVqOluSrY9^T*rF#TQG*ru7Bih8=!ZVHV zcdQf9PfXKh=@V>#30a_qX*A`kQcW@Tw7*u#JcE}hs+6h~Lp+AK!rlD*B3%&2H_Uqe z_|vUBAJR;}T*EllDIDZhEw7V{bivy-O9eLwmI>pGYQ>w`lFekRlgve0{Jq8*?V?w| z&C~PYY$X$?-fJ1;7vs(~U#^ftl zhr*rEV5o!0A+?F-!l#v08DO5pngK zQq?#s+t@tKF~%@wgzJsZlg!|Z1{f>k4_~>3dj~F3aSyhNA7Nhl=^RD1NU(i`nWx_% zbNi!04dzkq^;5I~o?X1pH=qkmpyyBW|4gGZRNFZHyb_HdFC-*T)6>lB6oR@N>W*z< zzi8VF(J1}n zvUsaaLY5)*LV!>FBj`wad;j4p@4zahA&IYuCl0Ir*69U2LWic#uHn`{f@$F8{c!R`%{LXrU0thkgc+kR?jIUHl!F$P^2$qWDMlF=}P# zC%}tPFK8CCkH*;V;nM#4aap88tqe4e**DWn2f0Br)g(o<33Ka=Up+-6Jr_t)F-G zn_KvkFy4O3CFsZpl^5v!UJv#8fI0tzS6qZ%bbdaoL95YR=kb{E+ z`U%cH=^8{CxO+%Q!kq-$GYsH0V;|!gTrW$t=oM6dil-(^7z^L%|GEOg08)wYXO)*)%;qL`@8E>~-Rj%&)6^#;z%a8q49iI+ zn31fnl7+iPIm3Ig|=BO4gkU59JM?$ihw;$v95Q}t8u>0ya zvQ>!tz`0ef4!jScB9pIo?Tc*vK8}41=24d6+xtYD|J~W>pRF1NjS{EmM(JChvJ8bg z1HBEi$XCD<(ejP2e~=gHTDdCviBV>;rcjqv(mBf2Zx3IUsa^eMmBc;R%b$JIDru1_ zPhY63Lu7><`j8OE_xGirE!MpBbCzDSm}j6$sZsjXL(;V&u4={C4_GE#B6<6h@1>fp zkn0q_H-~dF!RF^B$p15pW$P!I7pSEhdHWq-?BlqFdj|hW{k2F-w%#zyCGy7SPGQou zFV~!-hPe29q1G+XW0CUZnp)Y1JHYVm;$a@4pTL`%c@p%lgj>)DDAXm<0-i0jzZhl& zyZrf-OmwbSIGaD-7As&dU-=Y6gtxWqX5>lwUM+i7j?BSBG9bp2aCehL^igx-{ z`xhoT7`g zUOIfdy^mv*Im!;M#inU59h{?L?9omGy-PF%dfwe-oQ{744o$uM#hQD#As!w$ z;0FlmDb8WU(W{j5^%khtNwROMRIrUfgz@1{kk>3d$4HeD^}H--&vvUmmeH~tcdJl2@bCf!{I9tpkZ~^KRj&_2(YX_fd z5xm&+@(ptMd;57o`2)TjknN$K(a#cX^7n#EAKjc-n`}MjFyl1%cK!+b54#VpFKeW5 z??NXo{tmcDlCEtMK{u#$Bi=6b0)@LhdkQ^LEfP#qRZ2vg8^pEp`#9ll_&X0@d4!~z zU8q zdI6lok1(U1ph6EbI<<;o>_Mry4(P8RP%hQV!Q4P7WMa@ONH4y!-=r2=LwW3gQ_sOGQFrnSfp&oP9W>!Q&BpdGL0j^Nw+v zuMhPMe4hU-_J;+Y0dO~ow{naSY-1k)_rp1Sjsl7!g_?7eJzVBV^Y>+HVNbx}9BmmIPLEXI+z%HaPod*`QSCngjbMf zaEOQF3&X6RmtHtRl?e2f;EojKY?cbVphn3I!w$ZD?FqU~LX16h<{*xbb~??NebX%* z*e{49bqWc$3Ux#}!0}9@#3Ci#nJ;m@9qvV$|j z=Nlm&0Y2BhAm06{RE2&b(=f!Db)0DP6b)~eX$pS_`ar<7V~Y^{ApT_c6>7jWM6i1o5A_UuKf&*natUg|kp2Je z2Yq8{mU{oKa-~ZoxFfx>L_#{ofK$^bGur6_`Kz{VT%^kjN9)8tdH;3_gP#W|EFxXF zhM*P@_C&S3Ts2=0cW;n8`Cg8}F$VLbpWlPmMOup0!Jgm=ty>`2tyo>6F;CMjs{Iud z+g3>lHlV;k96#(yuqP;360I?gA>x5vH}O`e<%W2GzS=(K+84CbQ?vk|AD2N14w;^4 z`>ThPOKYUH@|?pX9KQZblo75Gu88-3!}1DBH6z+2U2~2y&XBF=??9;8ye-DV+6dq|0Mo|I{-Z3i8h5h z1-l^|1>GO0z9^Rnwkek&>ZnrMBm&0uN!T!Fg^F_&&3vjE>p0<7v8GKzsrvQY4iS-# z0^KR5IyuDAa}4O_RLd>jK&6>}c7{Qx5bMw&=h@S7R{Wj!=AUk96EJq<1^?K zi8qG0u6$o7;p_W(Dav`A)gtBD(;}@Gjut6y;d=R8Lx|%qQQ9Qj%x0JYeL=8ilyjbb ztesF-jY5<&XfV}FRVw;iTj{|(H6Z7>%I#$URspRTT z(Rc90TJ+L{1uMg!Ny$Eb zD-2qjqjsyK0Jb6r6v z2iCMS*EZK0o_{JGvt&&O>u*ro+y3B5bLPLG6TU$CL*$L@W6&J0_Er9mT;D)vIfMFY zpffu_Ck6|?M?Kk=IB0)R^|s-8&=?pGx0X+~_a# zE@8n94bW`>)<c zP$2U}>RIaS*P^7`zdAH+7VqbEL5Alq7}Pb@v}j(>m@y>>G@HV}P}35-IB6c+uSIcJ zweu%NEqf=l*>`;)XlD-SoY@%}S9Ja{iM`t8_Cmto!gI+F0;KOgcHEykS>_37^kaP> zXw8q=DNs1R6>hB#Tz}TMvt0G|#C%AMfYe$Z2aWoJSfDvaC76Z2n4tPVY7C-9-Uc3M_#bMRWwDeu-tWgollu51^5?Y0Ya zcgttqV^(6X7#I#X%t{k|eM_yk*x^9*(o1>|<$FrVu^+UaQ}`|D#GTm1>Nj0?&re(# zF7cwHVtt_7F0XAB9gpPZCWG#O30rm6*nMYdcg76f&u2_dn?8{#n4o!mRoE4sH6dHQ zo%iNXlzBpq{X51tm z3P<569EGEB6pq4CI0{GMC>({Oa1@ThQ8@S^0Lzs9eh>fv00;m800000000000Lq*I z0C=2?yklUcOS`T+;-sUFZQHhO+vwP~ZQHhOyJM$=PRHq3o#f1%x##}&UT3YD^Zc*p z8h730w`!msn`CN~V*RvA8sKe}m}bKGRiF!VtC!y@@eE#}>Jky)W1aX8#4$>?7UY#- z+9X}BmS(O|>KLt5-5{%<$1poj3jj>ASSP-MbP3zVUBe+<3Uvp1vyY*kRH`6eI7Y|X z4{G!g8?02KfSTe$+UjC;Of0Vrr0-1277-tLOb%hq@*fRPDnN0U@_+-~x7|sEhQ>E%&5rwJ| z?n@kjCc|9){56_U_EgJ09>p4nmrn6g$u)w1=v1pr8x z7siPvgy%n@fyhTf!x0V@@?0a}Kwd#|)u_MyJY?%IPy9SOI99nKZiyG3!2i)ty)eu8 z10NF5CeJmTtBt*fek|I7eVU;^AX+Ws75Md8Cm-;Fy~i>%PgSLBn9JJFIgw$Be7Q~Z z{;HE_A9aR$j+Sfe=5-Cg-|-8W;LWh{im6a2&}vd9T*f$UV+{AovdcFk*-SLeFbwt@ z;dKoq+J-$xJ-mhfNBS?!dn8y}lu|kB$HVWJ|{al^=JT3UMM(Hvo@Y@aS9DSEC z$ZL#)NT+7W6+FpCptod8izN2JCh-(=k@grn>IwRhQY``9oS^bVw}L zdZ1I>7nz&NN8173D75`jbGZ z@D$$LFWjb^M__i1xm>bUPOAIujlYF_w?-Nmcz{>2VUjAqcYrzE3H=898tC2MMWVws z8vS&Pg>?dJNxd>4aGNmM`4*-|N~7`)UM)kj);?Y{&(rH4ex9C76!{+Ia+X;WuSxMR zJzxI`DiFXX9{wua75l(6!a=5f~72?T}^evdLSj;%3_3(OPWA`G+N zL3Q)hsexZ1-D{Tc3^~R%N-yI!%7}G~cX)^Ipdj5zbyZ2x&To^|3hok$jlw+gcG<>b z{(5_SK@hB8rmNC;2j(3}HUqi)TfchQ5qgLZ%fj2cO912d877ABXQ-ghs6YDz3yk!N zp&zYdeO=Mdw2KEg%Jn=$baOQe0|P}`Lp_X&q#C;15x+>|npZI>lP0SR`x{uM_k2{LLp@qg^w}X5LgR;O~0}V;OG|<{B$ifdU>B00KA!iM0WPU~isb4G0DJU~VJbZ{v;7`UU<~ zucOTK#b$>Hwh52mKE577-|~b8>qRdy*T__J>Sf=6E5t>H5uZtxv%Z~!pCacPa4#_R zy2b*%?c&u*{>_JYoMjC3xk8v^vdawexP+ChY?7X*HOzsz%`}m1m|%T?dV=^Exy9S; z;_Tv7Dwn7-hW}hUH`1XHOZ zgge4x!_*4RT&+wi{d9$v7AftVQiEKpPQgHTrJ4oY0ofHi={oPQXdBV?bd&opfAjhJ zb4*aLE)jmC`v;OQcCl-f5bRzd}uOpq}-!6a3WA zKs$ziHi;GMt5U^X33p+gt5Mv>?G#HlNBS*OTdmDL^arL;N`!Cb$H+@BKs)j zrLU(#)efmtBjw_NKrfe4#ow);Vnx3Y?<8B#Js9$}Uli;PbI(3fp@o0w&%+V6Y4X=w ziIyGGY;(Y4ucU3nEQ587Uzl0SfY=bbZ!ljw(Vk1Nzjvv*Nmi*^y)e|XXMjlK7;m(7 zvohv!kDzs6qb9;n$=)c>bu`=~#)W2?K8`UF*=n)+VP5$2YU#iE-|3#9&aglqczVAT z`g<&JNaedk%+t;=8fD||J%dL(?&3MbVEn390)O`Ndj}%iu2Gy~PBS-8dj+wNrC3S* z#xlt`Q>|2`EZ#Op?-1i0SuZzFJ4f#k!Zn;|ZJN<2^AijDu22W@qD69uTcDSBphL7- zs!aU^Rjz)K`ojUdA27E(gOiJswCB_+fDp#lq)oQiu6L8mfo2#@5Ha#Mw^EFzaZ^@e7;9j3YcLmM=MWHr&hF{yW1|>Hko?cIb5+syX;#$;R)fcMi$yd zp;4SQ-1!gOV&f%T-;i?zhv-96(lyD-2@2t9`c<0tEv6%ab=o2gn}jcW%Jo76W?7o~ zZBlh=jtSc75-sNAGmPzG9wE$A=ts9O(@fk$p26~UAFjpOqMiT&nxy#q!d)LBui*Lm*T`PLl&cDL z^7KVI@pk$9Ofok}aP|#y>Ar_}kgj9=8sOy~dW1C2s*@*OKS3R1C)}Q90s@4(rI|ZM zC}GD;>}0RVCgLcI7VZ6ghGT4bf0H}MD$5)D!;60P5WouVpK>*W|`eF8j# zD^wj~Fb@O05iaLxe_{M*-R>P=k{Rv_dy{QsnDYby`B<)2uI3&Z;_(O6Atu)V_NGfX zPyhZ4$wsmz%|g9gsYaf@um3XTB?87TqwF9r@irhpgtKBzfKP zQT74q1H4z5zq4qcZUy+Ga!DH>=lCH`ffnptvena9iKcj)8?alXX~uIX$4Ij@AV9OE zV%Y`UB~iCXq-~BB?4eu--{>zig=(%oqLo!jmZe=>008E)Ukdt~V%jxSszIbYJKF^<;|u`U>g`FgK_cqi($H2rEtp`ld09@ZE3IY1v($+eRRNI`q{@3?-7nruIK3O!m&XIB$k4t5dPa&TtS!qV~YoOka zP*8sv(My7*Q>&nN_GK+FYXf*X-A~M%1LL+~6CKZn#RS+WZD& z=jR=mWB3jv()j|GYjBR_6%^?060u6|>u->|Lh&E({|=@p&XGH4j9>hHoFlIw$7mX* z4^V05DHf~b6RaGg_OZ-UDHa|f+C@j`Ow;mp60LS|GL3knw7a~ zLM>Aaee&trR&l`3r0YO{LS5*4rzGYH%B3sFJNTd2u^xO~M|jC*U( zmMJK5%ca_RX7LZrc_4_X}jUO3X#nFyiB$3YH|5}3~UTBmCg}Vkt zx|*jQ;PMaX<&v*Gg3nSCZ?g}11^)N&6pI2Qk7$K*+u#Ke#FJ5mNJr|aSTCq&AaIG+ z8`w<(H($lt7bLOfKabnwO%l;&#sxBsb97De;V#F>?x7%n3)~6nI{h)4N)?S_>lEr$ z={BT8>8b?7WJ|V{5~C~R_vd58St@^D;g0{F{{)$Cvq^t|nW&d%8XWli4trIk01S2v z@vX4HFvrL$=?S_`f_QzAu2MDAa-OtC3w5JiW|G-F)5isCe}Yx9c8Mv>EyL6)9O+b` zn`5p-*EngAqd^7eCC&}@tW#XHc7n?}Qlo@w8T9GD=i9_%9=FP|Pff9kR+|^(8v8hD zl{%&L@jZe~Q124%ktCSA2fm=Nj4;o$4{xF0!kd()>E)~M;|TVykYgQWnO-AZAr11o zguH+aND$8q3#esLFU~S_h!*HxAYvbka3)&E+08N(>ihxyAN~Jp7NcA)Q?HZv3|=EU zMfq~?=ZAi@NZl>eD6>ethwJB;U~`IcfL$ja;!&VWx=y$a060f}w0;1<&o^H$*mDoJ zRO1A-S}D^+vjhS-(Po@mu@-GxWatcGAKyGxs&a#LAJgCWzh@U|^Yz@o=~mRr9uo_+ z2sO+zzkueLi#3;M1O)~9ULhpw5A)r^skGMfm#RvX8RVAgx2c$9rJE?1X%Ge$uGeD_W$MZQ$#TezH%}!?Q&cZ-;#`O%Uik&fg|8N|&c) zlBrjGgO0J^#YeTsF=UiSw>HA6SZ^2CC|RU!nZ`7Req)|`jLZFV_KV_O8Tpp(qrUJ{Maz=#ifn2*pt-dFGv4d!vk*INY9 zzNkB9$&$_f{*-%wFBkCOk8f|o!v0PmfLMc9knePdm;p7P&yalr z#@K-XwsF};3pC)*@wS`9D5pc*=4m6GePV}5f+O)Z&BEwM<*Mo5$hXRs!dz|R|7X5j zy=Q2-hHSm?5cvBeFzHsHONk-S`#F$&2g?GrFkHr#1&FvA?>EMK=*(ErTu z63YJOknQIMd31n_aapJ6;HOoQYO7p=e5YJaup4I6sMa89oYo}n6;!03uo& zypMC3Wk9_c;xoZNPWuXBo>D2o{k=)qEH6_P>lFKEaPR~x>)?0hXW;Loi3OZoe3!iG59qO>Zz1iD1J zc&?EE?m!X0Y@!p)rJH7%u#TtLTczFn+!8n^KyR~b2FQ`lU%>Wock#4~K>tWL{k7hI z@8|nB|2=|PCLbZsks4$np2pd>hzxU_BWV@{dl+Zr>W#C!f>+lQd2F4&mt&JRSv3 zz7>jLZjnxg+5PCPLY$po&kgJtJKS}qiBG^T-ZT^BUAL-Ip;#@^CdEObg>rVAS}%)imhfPb zG2AY|n`E;~?gD0!(ISU*U9_!D1nR*lxLx)UhNHJsI?p^P0Qt0EP%lNWt61~j_($lE zFqtN%DY1dq5IDQiZ5etdh165<7l}Sru>w6qto{+&nWlg3x$xGYZWOD~FOKjgm^TRU zH?CoP0}gPXAgYY_@%+3LOYDNO?H~Z_=xvf~)Kip=nsPM>#_}zgd#)iyIsaDw93zZ# zYg9Rgj)@*|=ZI)~uTNdVMwPc;=%)`*%e79?;w>rlQ*72EVT%uF- z>?7^tt}wu^-Q)C&C2FN=K>^YoDRz^DM%iuRN9eT*b@D&}gbS}Aj?sUkf9wHDHSm8( zv@*^ZXJPzuh{-lGPwNy3_QXDD6K9>UN`iVI+!pHQ9XLW4Z+iyk81)E2I%gY?ap>p! z1KJ@2k3ry2f@pKBn~3<3`Q z;OYPLrC*fr`#6_lV3tmTPpn-x=QHFH!8_OlSBYYgj#7nV((7ZOJNgmn{s0%r$}zHL zNtzw~T$J6{>q`{w!9DV13*5a~vM?`Kp9e_1y|1?&LXTg=omC69}sr2YsFnc|BXMytyi?cWRMkU zE7jgE$}^67z&z>~*&@Z=(JQE28|8HM#Ve3y<_7`F(FU<{sakE9q(n=Ak9~+>C;dXB zmU(=j(@*RvrgV!l6!kpKni^^4suhYVWrvu2y*~aTZME``Uit4KSJx^r!dakeoOJ^` z#XQV~yQf~JT|_^(NF8hM>yLPmX##is1koa?Rs1bA%b0Nn?U-swq!S1*&Z<}=*@Ck# zUstLD^uCX?O-Qo<02k?4rr$v!-MoRnh3l0-Jgt!Zx6$__Zs0O)eL`Yw{rpc8e{Pqd|?n|$Ldny1V*v&O)4|fL}f7>-N z(P)dbTwAiGBVNwQwQK)s6(<-#slvj~6t6FdO^HpAooi%}}@E!mPqreS`kc)F=dopkLZ zaHU$Bk?=r<#Q@6^U5_xz`41f6*D7_i-yl!aV>-D~tu3VLKir;iOHtf zdU(6}di8QU1UZH{`_oKK(!Bzo`Tr3i?mzHn7$cnrd5p3tRxT0v``E|6{toKo#NTY ze5T(iCMH0wa)bkQ^IOI!n_g+Magqrb6xTqM{uKWy_8cepBjsqUGw1j(46}k;FvG-R z!zhO>f^W%!gTsQo0`I^%Y7;`u+;L7Q=f`lAt22x+x7A9C)?{l3*e_tV@d-Ac`#-|* z1Ofbpx4S|y&NjrIWW_z?5`lj72J9ZXMwVoir+){1gg(Jax-QtWk5j24UpK>e2QAS$ z%kT&p;lkISU<2~1TA@{3q)oA6TZDST)v-*+JLTrz%gxn!NN@x3S^eLCS!A7Ieufln z8R5*-7aYOeA7#@iGR)h>PcrBc&$1w%eFg26PS*l`4fHP1snEpuovD&wo@+|6(aSp` z8SWBq%`n9|8tP$@p_giyAL>T>qlGWlbCfOi8~lBaF4m9F)R$^0bR|3Zd->Vp?QT#o zP7CzNH42YV56`mAFi`DBIkxeAJuOkuFQi?Q>OMxq-Q%3__qqX^VqlrgFnIxK5C%fY zli`}|lzW7WwP=)g^3%vNs7AZGL&05EPa)b78u+aKF@N17hPny$$ybBEGED2{v-e{j zX;&?i4G9nO){6-Y!@RU`3l8QPN7^4Dp`0g~+NXqiyZD@-RI67hy2OCJqHl98P18FD z9^u=^MVkeAjj7jUVB>fi+L7 zR{GdU2KZE{3igP0jB+%{(tUpclWANdLp?z{cZ~k}8~=x6^c{4B3*okC$448O5}aWy zRUHvA${pZ#2*lXbsr=_l<^LR;WXGgS#6g}blvFE1T`j_-yWeTaRuPX)il@k0sjAg`*t( zeP1Es^ss)^DO@6aRs-Jt^Yq_J;m%rQBpUS#j}g(1q?^QtDrI)@2zHuO@Ym@_;cqww z-l4+W4hUsRB5W`pguBh7n5Sns3bm3g5Kb)eO=3emNKfv7(~MsKK!X!)TSe;>BHrJD z)+tm<#@qhe>i;8p1l8&S{X(3PZ`VnCIZ-cOUJ4Dmr9AzfzCirdGc6N-Bi}*?c?Wvl zLJkX%{HT<3^T0m40X0iiuR=fN8&qty4yGQt#M>wTYk%?%v%f&2Q@Bcwx9b&zx7#jO zto84!|Br~ZW17x1>Eo}LgM36ic?F4fJVRcjwoVl4rd<9Q0jv{`(Dm|LBp)H!#>rRT zfZN2+ktAD~rlp(Y>Wj2rz<35lI_2txyILd>FZ}#|qdtOxKrwwsxUP}Q(4M1vdH>9R z`GyuXq;sKe(v@i2C@=P5_cJUS&uE8|3@9YTYHnG);dFJMc4{v>< z@s^I!_DMi*N^OyjOfxtu#fB}idniC)Kar0}(yh*rhS;>qRx$3N>1L!GKfwdEinfWH z)$nFfANxeyf)EcAoi1Sj;O8i>V9DR?!qJX6=4^wuaR@J!$^^S2y&XJ7yOZpp9+JPQ z)PVvCwzG{ScrcFK!C_s8xK>Lq;HQ35Z4mEJsE+VGg%0-Y>2=fSji?T}F$~`L5BS=3^HxKnkq>lUhKI$O`<9DUv937<^wW`oy znL3QaN#b?pZjN37zR^wGQxuNTY$K~AkB~~02Pm}T0H4qNpQXQohkEb~POu5~lx={& zvPt-I&pXg19PPM81oBhl&} zny;sqe~xqu!#dh2$u=oCpk0z-_6JP5rcM^^@H71!BT%n?K?$~F9D;q=2e?1MZ@IfL z9u9Cab+vQP5R8fp^vd4OI12#i28)m1S zhq#w)ryEfzyM_IU<{lg2as~65evhygHKW`GyjBJJ*<`(0_Gg${iD+lXkat)pfI$}F z`VkTS${h7?)Bsne#WPf(#}O8ib(OL@xheK*D3q5XZTuDGeBCner*W=zGL1Zn74D&S zG3Kd!J}bd`72Qa)}<~(aj^>jP*qQLAi!;PCt!zs8qg5013ihKS$yh{*1UtX`b>6^?)E( z-#5T3*fmVB-8vfewA8{lyFiPltB>~z7W)c+5BlN~dV&T18u^!E1K5*E?1V69f2GoA z`ZoySFVD$`7*<$rpl##r{P2Hnk|F#?J0Y59S$={dSU1m6Zukv-j#VL}mCif3PMK?c z_i~6qy@-35X{p;m!~j<2()OC9;au zndYYH;%zC;6bmYaIfm*bN!CV5ZE}v$w=nHueEk}w*KjDOhB;ErpXtZ@F~%NiUnjpt zc8O4_!ZJBW@9XawT&A95s9T_11pxH(EmA*&e|T(_#566`-5_flZh+(!}Oreuz@>?qU@ioE}2l;lZkVs>b_-FcCrI4RJLiMr(9S+DxxLre% z4d-xtqQk=E+v%rlgY~kkGdqRVOApZU432SX6snYnf7MF(yDgKaSx*XR6oG)j9x0Xd zaqo~WFm!UC;!m*@>h$s$X5S$=1u-w@DW@BM#`g*?SErt@S6QZub)a05YLM)zm656Q zjRbq@XTAQiLfRv_gEh_0Km7{S&+{9Gcnj`vmJ0sY9PJf?L9t=l6#F4jkoVWCThJiq z2&Y>03`=Ww(nFcLQX`yo`DW^+G1kxcVQz3Ql8q3zXIPOwx+O^aidCHw@IR#nLjCkp zhj~=0ad#ve>DOQ1`I>oql8nAyKtqc)-ht0Cz&=%|q&dLdJi>ZA@HM4b9Fp?3bV>Zg zBHYd}E!Lu1Vw@q_KtHPfwEg$;uakC)NHx2Mwn%>L>p}joPEajHI{W*2gnXyW26%VzP)>hg804mz@8U(c+`>$<@Xe=b9Ng1 zfm$WavS{l#?-=i~hDlDjBEngdYP3^^!5)S| zy3?oQPqL+3m~ATe+%g&93HAj3NxqY_!zv}-@)Q;7kYTAy{u0^Qw_cfevqqbG-87To zyL!$gdJi-0%rIY*ievB?8x&BOYrbL3w@RfZakHESDyn(vW$gm?o>JXal3miaPuqW; z;*8)n5yd3yP?_l^lw^x|d!4+mr(If+QIm9*j#Gqwc8734q-{W@9Na^(Iq-vQhhWPi zIKc+$rNG2Hm|;e$rCP3Qq)3-@B-C?|wQj+;RMv_6FXd_}79T6~&qx1fF!aAxyq5@x z)|5C=Ko93oqqv7R z)ilcU8hn7=s^A`ma>_2HL4j$+&;8-gGwKogC_nK5{hWB~4QPlX^bPc#d8TBKzbDtk zF5V3^>W>xLQXRjDa&^62)Po$u8a3b--L!nIN663k4700L{ZcHGm#8sz6*A6I4_}8_ z2sZuw;$4-q`KNq*oCBTxg-4=oZHf}j+oh5$r`eA&Dn(REmdI=~aDSC4FA+`h80QJK z4T|pK(|rGl66?VHLp+lH~Rd#@!||pk7J0@SVmr8u@Y$EA$)x zIP7JjO|{$~kU^1C4BSoIVC4q7W%{WU*K||+;40a82ltdi6oyIdD(Jf*I;1D}fP8}) zV$yZDFx)-Zn*blpl6pCt1fPJ#PK*;=;ICu~=>AJ7~C4yW%%4x5_$7*qm{TfcDG0+=lUq5e?xKM|4+bNqDC1CbT*0PN=mis^>5%+3M;gXbGL~~G^5NVJGuq+ zvy^HK@`!d$vF~1XNe-|q;`MWK4Yr9q;|SOCjhJS>o-9yMtrr>BDs*wG6MXFJD`aR%aLi%h=l%j+OplaOUv4_{F5D0R82VbKf33|X&?O2ZI+ zw(e*8E7ch`Q;fPeE{Kkivn;apie+gxU|+vQ!#-MupCOC&A7JPdlCBUO8K$LJiFS%M zaE}liTtXXW%rcG&C^bwm8W$>*V{K5+zXPQ^C+dW`xrWm$Fim%gAY78JYZZUq|H)Sx zWh7e;uoG+$FPx%MEC_b|{MzJ+m$lB>tt{kT=eIO7%u z^w;k623ER>V#O(nYN<$DsC$bjD7u}$SYw!Tn<&T7)icu=2om~J|9@gwrAl_1%R0M}=Hwh5}0ZEPs;OruFU!Y$lW zqdcj+UMc(Z3Q3gHE&LK=qwGtR1S?m6>r}?&HBv9X2RMqw4*oEQaF-4--Z|bbrDF>p{j@7EzFENC0T#*;!gZLtQ2#Gfk3fX;&-f2e0N4|pF-G3uCIP%3`{q!n;kqffE#+>H=a)P%n zU0$whnnAqrSq&^uC)lc$7wfyGkS#MbkMUq%=IH(TI?jTy5BU=54+;o$(X40@wT$@< zuTkk8aEuLqv`Fm}a1AZfRIlnCb_W&Y@e7r4T68$j^#Me);X6I-S({j%8Qzjp81<5Q zs?g{2-}@O3+eCzmV=~-1)II6kBpb^--Wtt!(jN}7JY6G#H5yha)snT6Wh%J_B-?<; zm;mNwuGaW(2cw-UT7}f}#R)XM*WI!DIaR;t7}$TkFe z!`vRDStkO$M>(;N&C|L>guAv#lCDF1S!9+kZW4Qgpq}lN=IJL`q*(e)fBHAIMv;~> zwFViFSmqJ^v49c}SVVWI;JNr1%-T+UivnG*2-W&K) zZeJ(AAd`yAuMoHHL8iH3?x?3DY&qI&>OSyW0 zFX)SPV!MP^dg?cU-g(-2THHN_+IU;?)l8Gm_kV5TC7QvWGL2*G=tmYQAg{juM%kQl!!_v~v4yYLG0vb_ zdx*?Ay@f5-mt+ua?-WkEyhv)4SughnHqMh^Av8S9IKwRVM6rzLcaD*hEx%>BM<~}q{;8KoIiy(0*EK8gu-nBGZ$mrAK6nG3V0{M~ z;rxm9nSR-Nj!~s*;V!A>`!ByRWEv4K26;p}Q!GB_kdJ%B)``KM?x7u`HHzbGVQx** zXvZEQc)N4-7{4T1Q!E-}-9v5TqaEezDpdRUksixbh6OZBXlE1(^-8h#c?QT2mT)N711*9>=e6?Z0ix|E!wZ=dn%`Cbpsiqv$F6nc` z0Y1hF^wV|feUun4;&FnVWJ~%v#EWXB23eea_$$ig&-h(JetskyU@tm_us0twfN2K8 zO`TECL?owFAw{yb0 z?NYP}=b8)EA>Bmz#hYwkS1QfXex@JexJL%$Z9qVys9sE|RiJB;3jA5R+Ai!0i*&~& z+Ry78$tX*_sar~@`xN0jqjTUsmQ+iz#wsxYU>Em;YMPg;_Zld|;}&|B=Idpei*P61 zv`1LG!~&U9)B$NFge--R}1#|aZqqsubBABCsxCa1ojH28FJ!Y9V@EIoF5q=^nHNc+O#j%gIO6U|0 z@?@A&Ev0_bF8WMA#ABU&k08NLn)wYZ*RWhY=$}Fz%)>vRc)N@*FplmJF;}+;bPGS@ z@8Ho-zrf43kFo@LBzWejw8+EWM%ZyrvW*|Y26_#ME>SbisO4T_{Q;S$z6VWo=;tU^ zUZ>P91Ohlk`32^fUw##7Vf_9Z4reReo@dc43;y0B%_s})K%je;8GmUT?=${6ifxi{ zxLmRf0tkWrpRChmNLJnv|kQnNS! zkYU!WFhRdU$2zx2T%f;519x@t#V3GgFu|r$#WC72$2GiJO0(qi9l!-brHW=ry4fBs z@)^XFcVL@1><#ptYy*E^sJmO(3dQ{wub^GLRq`EzGi2!|h^HFG4AZ~AE47IQ_-GX$ zU_U@9SHWEicZm)n|1?ZgFN<)us6G9Pe8Sfz-S8RRD3|Ey95cf986w!xAv_|OXr)d; zss#W{v_v`8B~P;`+8pFDM;Z{d!fYGu9L(1xIDLRsE%7b>?yJ%Z^U^KN)7>KOOgFW{JyZfF+<0K9?_f8W6ed$P?MXNoqp3W7X#NRM)`jSup` z-WcYpHkxJl+<$^?$(A6mFZZt?aM#sJMcQw`Ow)_hp2739j5Arrtr8v~w(-H9 z;jZqXzW(KEWveK;4V8 z{)`TNXPiI7Stlvb7wJH_n`S1`8sa}mU$4|AyoZ=#fqj`}G$L||=n#Gnu3cZHkg3JI z2y#cdY@G2?R;065rO23OL$ph&^bmcGs$4~*a)7Ig%^`tqk$7W`D#TVh|1`%1r6z@P6TM zR?9{@@buIvULYn|ex@IP7wtC~ILk<^Gs=FZl~$T$ja*&3490ny=_RaMZMu1{l&|+N zi)sz_Hs|CPVZJKeA}H`YxpnOStN)L6GWwCkDEGk4D+mbIPvPbX(Kw?QQ2nx6?I_b_ zD)5_T$`I>n$^g1F`#t5SIbFHje2 z)XmG*`zV{Q$1pd<#$y6GD?hk@gKzp6=5F)SXI0owR4bXLP|H-Ab$6ZiZM#te^6Yh?gCb z_YhVo1=<`Vlye(Y#)($Bun%ZIHS1XW%N64sRSFoE0{sHr%#;2ujdGT5afI2=yFqae z)+HF`{|3%5Geaxf<`Yc1O1`LGD%tcI-#L{*&)r_5By}CEHL630Cz?+`*&%T%4+ommTs;qzpgc=#dlh63Q{1_(`KdjQ2W=yh@^~u))0xY9Onbcd?$S&ciSEahz_?V{9 zF2EkVLSt-)xXp9rYdJc|R|fyrxT018cQ4)DB65TzG=#N7HA}J);NuYE6F{*-_q|oZ zJJ31u|Ihs2$1mB^Ed=%O13$~SOV}cXdU28Z94X2vPe01(02}_QUM|}x-AuV^iuvPq z5fI=6<)0UYNN3>BGmKirkdOYpP!Ah43YDWA?{K%^5CG{~vuNd7ivQ26%l{hY>59#2 zl~BJ;irW;}hC~{n-%^a|7L*Dm`B$hHNgyweNYYGLr+q`+og|00N%*>)W1{SDK}1{s zF6|VhRk}m!oFdtpV3uT+V}kVaI}7y;(#;WSwm$OyGNnT8r{_P}yxrf@V|{tM(yVo} zJR&-T3HB=WG&2r}gqkZ=SiU>O4$-6B?hp>}ok5Eae5YI{4fb6j1-t*dv}*Y>l~gm; z8uy?{e!8t$ltnt}VyxRXp?PM)H`cj(P~%VcKW<@J7U4eVyZi%=X<3F@%1rASW==6u z&ETh~XQhVEU?&)ZoU=?1&j7G3>JXO_UEQ2hq&yw>|MjBMF}g>HbU#(wC3;YzMbJF} z=)FhKB4w1LMiJ)LILjvCrNl z4RZ_roNTF=FWRw>!#j{`ut+_^$u;~>UcI~#&NtvNH@mn$pgbc;zl9o)@#3tCEVj^_ zq^}WVt3RXL#qmrcKHk90(_I7e^(`?bS#(Q^wPCN!@W?gf>L!}p;k>;e9y5<8X-SOv zySaxc)TKBKGK;qSQ@%t?v@gzHvU?p{t!bERA7_Y-X0B7rG8za-rQAJij^;Cdi1@;UPTE5OTdi$bvFfN+8q=>g{Y03UJp7w#RRSg&+VCuf`{W1e7hYxP!0KZBl zg*Lf1p57Zkxa$Md3I))6ibaSA@EhmI1>$G^CtHxOc8G3})GGYMO0t?@%{Cg~9pym0 zpkDO%Z5Ipl{)GYbzC*y*Z=3~xWtzb@4s#pjgne-Sf1K-4Ey7*n?um9l-%+lLccNb} z(90I?6RH;*q~;l$WPYY!u@37xSFfGVCEPCRJLe5tuw$i4K&W%**NaKkClD{6TcS8S zz+0U}7f+5QbAN(ktmW57*z*L7|70-E9_B^7K{=gfc8+D4=NLJGwMcdfxki(0U>zdd z_>51voNNdF{tK0NwnRH$?-JI}FUa}JT?hN1xO>DZ4csr8R0`uU4w^N^V#Lc@ zr7C5ymXH4y_$O=<+a>#if<0^0`&dg1)oadSkxwoWmRUN4J2<0kKI0o@4R8+$3EFa&n655cT!Hfki(1%zx-x_^UWO`8t~fyxkVbU{9s$Xh+aL z+(Xq$1-jv`yaPOggxgk0>Sd@W7{5O56f9Gs9lJ!F{$DR@-++AmLH}?K>(y4ME0o4t zdiu0$5^dsbLR{tQf2Mz)R;D?|#w_^~7vV0#s?0>SLbZ_bdydu?G5Axk%Q4C|VVoJs zu4q+`Db30-6aFy}z#t9$VUYVj8S3N?v8UMPY4Z(|ZGFQxaQ?iokKBQ1*OIM2Ktwuz zrvDK-BuKOc{7tec%z2zuvLV$5>E;c@#anP_7pqoNs2=E!{8ze#Z%_}*rQfe zwY0A<^}>HLfW16H@eajXwM)@%pzYUdY$9GkLxc5-v-GMKZ4!N^pK{^uD<}}rW~vSG zZiqYheXe$^%sa^YpD*`=TuP<+R$bCN=%USL>EawR)EZLE z6ZBC}n*Nd z*S=1^);;nLy-REl_Xn;=SOs6ace=G{_BKB5f@$h!_1`T#!EKd?c6^Dz-D8-qRna0q zJI^$6icoC+|FHL#QB_4-*f8DQ-QC^YAT3HsNE)Dow4%}=AzjiUDIqA`-QC^Y-QQiG z!*Snxuh(KR6X=m#Y3}Tv@zPptGAV-P|?; zb`BhP)qUlc}wfVVqecuV=N3FesYjAzo6?g1h7!-bcjRGs|=Jk*MSveB+08*dy%c zz}a;P$2Rz{cX1Bv4^0 ze%xyk*Ud9Yn4{7zHVt=*edp#79PBp8&DKw~aEP2?ae_R>m~7S0?EG(eRrm9G`|wWS z_r2dVN_?~{&^Arw9FVGydvbyb=?yUdQWLA5YOqmmES*Fmy9s2Up6r z31V*yv;6ygwh0I~niXFKrCKQ$Y3I56YUS4}xA5;^LV$;gdQtu$#O|wMyMRnxqDiu; zZ3Om_eb|%uhgsxf`=mP<*}C0Q`Rf1JckJ(#7iqis@(hL9nMOWJ`}f~fs7wdTzp}mC}zAp16*+q^9+fWGVk^BL*L5R ziFV6XHc9k}+6O6pvy9fy*7#1e{GYs*PF}DJ$`Qflqt76VlXBtf{fHOe)Ypk1J^v~> zaQ08r)yjN+q){C4LaVSv)ZH)9vX9%#ldJ!uU8utdYl0Qo^5;iTP?rd{kzen7_*%y= zQvBzA-+RW{ujpUEBJ=W5C|53(v%Mw_fq8)Xi&eX{ik zeD7hFUZ5n^hH&xG9Qw*OVwrdk%Or=V2luc=h-K)N!PvKuVH<9j&QD) z9qgrEa0P|FPd~ni`=58xEE=akyHjaDZ3GJ^()P}28|y#+-@gulcJW^9^E&(?rDSz`=sKx9^P&N`q54y(z(_DsQUEp z1NJV_p}cN;Fc*C)|#E z?)|Ep5Aozt!8R60e~wkY_Pv5q6~<+>>yNg$i(c=x(NGS4cQ35tPGNud3lzh2+xSn< zWQw~vI`|%y`=enXX}6Bjzz|lW)8{e0Y0xzH(I6i5HtsF?I-dvpveHkb}Dn z^3}{7Vne#YIF2&Y&i&oJf*nDP-V!z4oCZnRn&4Lrl0xl}Er1Pz9o!<#4ZRsrN;Q1v;r%|?=@6G^5Mzyf0O{N%>I|_} zP(Mqq3Le@xDbQV_HCwa#xAXrZ*53{ZHq!{8vqWQ|emVu#@#0N$_^`Kh^9&2Maw*1BjFWWh_-Urpt1zd-jC<(4T)(^5HNrWn zZH#;i{aB6x`Ru`+QBHs}B>XsQy@C;T(du~n=TSHd_R+@K4YJWTsF#*uqK$S5hPh9} zJ0$L4dl>@Xl&Q1yH;E7Od%L^4-TQ4^?F-KO+_BcDQpy4kKvK>FX34RsC z(MvJ*E~J}F{i{@qcBw(q^WYHKT8Ienm>>*KbL zhn)ZVb71X}El1k6is0GwvgHyfK%W%uY zbmRZ5CJ2UDpKz;MVVVWUM2g{qlqWGY3QA>=kgwsV*h8GC)(lf=r_NEt8YgLX@xSQ5 z`p_r9(ruE3y1hU+!*_G}G&$yFj48^6SVx8l&5+!WH1pr#Ygb*v7pwREqgykz|hX_>+bzG8O7YmE{}_=*+94}zQ{>^3(* z`;D-=1Rh`-d?8zggnx{xRBoJZoF4t$GVz1c{jYfspzq+W4>4k%Ni?dKT70rh^nPQM z5pV7N#@FNh+d65o<$9^4-#&dPDE8?_dG(xBE8hM*)nse2AK%rYA;$kO57I0eB-rN~ zWJ#8h$YqE)DEYH08C-kj7qDL7>XYB%~NEfK{1od+C za~bBPN~B9p!P{73118a(!j_>b)o;9iAJ;x4d|0qSh;oCoLo!Lc>f!a^3)~H)=U*Xr zjPxik-0`zjhcNU_2Mgw@XloC_-!NZ~$=6zL?(Uay7zf(93(O}--F%5pax~ri zN|b+hFN}i)$}|(3s0u~tI?W>Ipk*?)VMzFJS2(-8Jx^mbi@Nx6b}1IUJauy>80VPm-;13`sSmoA!RgFsW4te-->H!1ecceH$M8M6Ajt**u+Pkax%|o?@hr z4FWurP1Gr7o~CL3XLHmo*I@D${Zzgl*(R~?vCbdd8ihI97<>D~Y(tqBu3`HG107Nx zJA_Vh-dzaS|L$H?8%b8&t;r6<#5Btz!lQJUt3AIxr~l8vI#{k$rIBome8b;7#wO9` z`}Rcy;d+LFZqY7Uh1|n}ON?>KG3Hh&gcF_b+?~frjDsSL+J$0`zq=ROu30wHIpr?h zEasYi#{H6U@>^&~&p*r_`-p5Q&dMjSn{|%TIIB|eMZ}Zn&(_aE73#LpF0j>#V=ZEz z2Dx&!$2xv=+CVkP`L1{lzx^Bk0}6^@uM{eE^39Vl4;({kWS_=5hCts5be1c1{noBk ztqFCCHIuJ<{F!hsN1Jsh{h^Nw1bC1*jX|UYk&Fuasv#_O@YzTn@q0Y+1Sn zpXvMLT3(0raQ#rXh)#Xl$vr`x{)ljAoX+L9HT~k80X+FuVbMp+)_O4ZX%_i;OY zh<^URoc^FX<`Ej(uuCB6ie+Mk(G~m$C)AS@RQoXRH!Y&DH>)I>hCZ(eHl02&jaSK^ zq7ZC~v|b|o?#@x>wlQb8SjVze)AWzi3$=+B%n~4>pP;Fg4|3mLz4p4mDO2JZq8&C) zdmJm;5&kOEK<{g*0$=|z!UAolXfw~NxEPzn$0RcglSK&sI_B+y=~;1nv*enOy1o^$A4 z#SX4YQQ!-%!N`}tk1O3G>3r|wY!`w*YZRrMq+FnyWgmd_`!|TTNk=(P5iahs^b>7t z!wm9%h@K%MAijNf?>p96xirHt!DhMg8(-V#Ty3GwW+}%giK-d0LH7UtyQ<{KmyXc? zH@okjBU@Ll8XBruRIb|B!!i+geFB|7tw*4BGD`|{0e@>20!10{7k+nt%LI)5VAts9 zlnXn!x;ff~fle@x%5VK+NHoISa`!0zP^fDbHA|7Latdw|StB(|E>n@O=I^kHHc9zn z82g-QM4=jce~ekWrdqaK>GzpU?IJ}Qb|LJe*6{-zc@MS;2-noUL4FP^WcR<`-4<)# z!suq_Jvc$jd+=T5Nt|x(s}REVPZso(WDB_l?1RxZZ@pk{LmUv#Pmw1XbAQY0%GFqY zg1)m43vy}^5pV3|^L{5?2l@B+@LnO{>}Bc`toyxj3W|BoHo(^f1xvD4qPj$xU_rh_ zHH&c+XMG3vENY5jhL(Ea1ckeIlK%g8e*ccYEIhX2R)A#=#;C@)>|gKMBwc~I=4(@ zoRF?tC2vl#m@meGAIwGxum9^L|NwUT)%wqek>;1-5*!7?$`R6lE+X@d~+z%X-_ zWSUMt3)HiVcrn1qG)}SjAn%(xcOS@X%+g;aiFsxdCD_r$Zymou`1SrTe9@LD8^(#a zC$EATCw6eV`9xZU+bR@&USsWd@qbhA;zvDMCo)dQ+tw;nsI-nhLN8SXeN@Vn4=@Qg zBpRpai#34O>IPQ3pi`hk%_yT&;Db}C>brNxXowe&KDP-!iHm-29q$~}#joNxq|2JlWgGc;vC@aW1K)eA>4qwzCgT##@%5W zCthQi#M{O^U>zY}!rP{u!93vUm8$=RFICSufO){xFWy8u!_$j?1iHq#`^nVubuW=S zgeF+^bK&k}=^JJSxSku;T=pNLN6=zF+t^uxce(`yr0(LzM~=jcmhk*L>YzRj`a6p`RnsPaR-R zFp{n?j|p_LjB@vpFOe-XOmg?}cM-3lo}43HAd;*yOo}y=tb(^jpc8BV6b0dutDkm; ze2H!v*8-hL=d(1oFa}?8AJR`bgnqy0nmAq!rvzTIy&yVD*KuzjnH2o~IWW&rETEq*b@?*4msZfVs_>&9+ zoRtb`Cd^|OhzVArEtCtG2mM@v9Z@#jd{9s>f#EN&;NN&(APRIs-xX>ln{f_Q%k5*e z2|vgaZsQm%)Y>F?m^;pt_n<`W05ijAgca?WYW@^u8;@$<-!0yna0B$mW*q_FD9G98 zwY#5lP^RG*1I3D;=yKJTiQm*Q529?i`g3&0nM~3|TF;O>1^nF}=5`3W1d25?PE64& zmkqIN7vS!=`OnZUk^8wXP)0wu`&gi@S%h**u!*yK1;0dY6V)i8mpx4<*>LZBlQ_-n z2I1qBD)|Y<*rzs8`&elvp!2F`(J6{x2VZxYGUCOr-7nMdwa*s*qtA^J9=>?nur~{o ztRq705{(>#WXoU%d3q@p5ihRbQBT0$&N7O2%sfWC#@$Cf2mT-R99O?sGyBjDEN_oQ zqd+HDKgS@!rcgV77x@zV5Pz3o2g@i|KR8LG>VID1P27FNYa*?`R=-Fq-88`_PcPFr z=K$``DoN~9Uk|GJEqwbhiN;jZ8(260awXOgqVBe53GqeB9wL7ynQEH{O~>ts?ingMHubBg<&S3-ct>6~YbL8RE4%X`yzw>v}2L8T~B54(`4O zd5$5Vdv&`|xzadO?!zki;8!5;UAPVH81y%@jTCQUA94&aPQQb$l>w{w2px1n6K}GP zXPBH|BwkCfVjiPd9A$Cye--=_U$wMQ>uIdY4~=5R3BGQWQ_g{9GUT)HmyHrDq|0Qc zsbkD(Cb~I}A(9OzsNH#F|%0;ID+*TSTkm#hP{Uff_GMU#l?5yj-bD{wKa^>M2UIm~PGmqOZrh zclud4yOay8BlugQEvzGB%*$kZ*gU<|bD)wF=K%8<`I1O0?F`2t>IvC0`;cUVL?hia z@)@uL(2uC*1v_YF&yY!1kj~kL87A3=@wd49fDItg$kWT!PqNB7BGwGv0EtGXaq!pA z(~o=!?U;0he2I33Wc3Q3V$m_=8g7bymWIEJb>xQ%{giN9fa^Tf5jsFeJC3(rCjuP` zC>KaqbaQ5CS4l)$LLG+L;I2nliPzw-h}S^vnrXUL5y}PEfFyH=&>t#e%pSgT)NR6r zTBs)%i1)tFQBy27NNN`VeC>iOc&vSkPj}E|%BHEWf(^c87*Wlmo^hjB}81TYm`ZmD|mCFnb@exY{EgB#d$B%WU3Hm-h&M(`=& zHqjQac7@t;cTi66pf?E!Hx?*?#X~iZa7nQ!+(x`6+{WEUv531vGb`D^)sJ+32aUal zamd{#*um3_c)>Od?gZWi-X6jYmQmCbwqdS*m|JjS=ja}xd-&!(m}Cfl$=zq3R4c|E9L973uzRy56M@t51FKyq&>*n#;cV{GKalUtbn^tHfxY%m?T~+ z)(Ep_83lRhXvamG?tagsvG$8KOwz=gGK>Z}zTcCsqn`qKEAUtDe#IJP%GYortp;B@ z1lxq)zOPX9^{AH;ZAmq)R4~fu=Hu`BWZ@iCuH@$L>+v`RYaikAhsu+<3PtB2%!AL5 zkk6**?ZdM5>^`QMybNEU9Aj=1b`AnH@Vfcz!+?@*oXOzJJ{H=sQu#6&`q9_>oCBmQ z(sf+@6pNt#;VBBmVwLn??bYsw4y#ue*mKy1-@cD|hIR}T**v|J3mk*sM3-m;J2T~iK&NB_ z`w;XU@tRP(WP@bGKkYVfa)Xndr;UKIM+RROC>tc#h|`US*uUSS zp6lk@!au+SHgu(eR6Tze*>aFG-u5aSPj2K|&#M%<=eE+sxNV-m;Qn}1I zNVEm%e4GgiDoejccAW_3woLgPsh7vs19wNRnr_-Kvxm1#xj7+YRjwNB^aPu%BO{Cqmk2Po)N@SZ;0>pl#ojwd!rc*X;_nh} z12zJ%AHm%u8j07A(3i+zZgF-=S2zc_`fFsf^nG6YxpNMHtbv!|jS^m-jv{=Pe5Wa4Q&<4p5P7IUfN(Nsl6~MoGdBDyKcU_=e zBP-aUn-l!%`@Lf{Q0G>>sYNu%d5XSBldt<_ILJ-151U}@6ks1>9f7+(M}ogfGs)M9 zdxCi&UnO7l@A%hnPvV}&lB`;MTBHEDt^u$&vNgUQLC&#HRenH0eZQxhgS9_L{lTeN z1L3k&1izKipme5xJ@&er&9lxrO(}W4TrUVh%vya@}r;2 zHQ)qQsJ%iF{tADqOnHOQC2*9bRwmW-Nt|`Obln7_WP?!qB|?yMk~!kVlQ?kpunh~h zfqfaw6IVay0Npfy7uXH{^XdP*I0nJ4FV-yF20A_xY!YsO?jN)>MC%)bq$_O0+js|< z^iyKZ;!R@Bf*rU!)N{jZIJC-IN`)kI$p$DW?>G56;!W|^l?q?)!(9XQI@|Dzh;Qm3 z>u`oP)6h0DTQArqPgzf@-lPYSVO#6VP}6 z-1qJU_@%+hBanWi&MC0(hLK0;TlSS5K9 zH%s$0*4@uE71+~f$QOvxb)d)D3Tf`c9bD8C^Q1y8l+$nO309!~=^XVThDfXWH-j&r zCg$()?LM*%TYT!_1s)^ddqNzE*XF1lLdTg7Fn4iSM|5-Io`|%jJmws5_fsuhq+por z<1SOiJmBuz!F3G)9>p?QkTa;2XA`ASEK^H66aF&xDexoZ*3BP#4}UAs5(-K`3sjN;T?GDwA8GsbKJysO?4!@iWOvZ--%2(V zYYcLP*?&_%#291d>&`Spyb$R8VqlqwctNsil(CPcn?t!UMgJ-|-MCHowU2Q+6qHcA zTs7iFlue-)6cqhbA2+B_{v_^2!~kc2EA<@QwSLxr$LHx)EzQADiNBF*4eTll^ngd5mAkXf?& zw=-nM3AAI3L+Cre7Xc=ZW|n#E&+{+YK)Ql@LbQH{e1;4-L(Bug4z7OwF6uexJM2Bc zB=hvr%<^?pF3?Q_9+|rjSPbBkV$Gy0Ft=0mh!^0T0Tu__FyV&J>k-y6W$L+67K1Mc zmvGnZLVx=8;4W127l=X5)pGa0ezJIw$JPJFyO+m09(PBe(<*^;0Oqz-m373;U!b#E zj$pGv@@eca+bT&P_aMg+dYLltRBa=*3o?vOQI62xcykP{kk-m*754DfNvr%QQKMKC zYyQR6{Qh$D2P@b<><*f3*wbc9Z%w(M~|}XWA$;LA!8l@Hfsl$VRDK-%)UYL z9O(u&-B`2ei$SKLRl*m8Yq%_ZcfSrnylv>aW3)pIm|KQP(H8DL^dqM6Kkfa%hvV(R z+s57_Ub}(C+Xn1`a2xO|*oQa=K-Zre*b79edHN~zBVhm2&H%dt*cagJr<&*M<{S`i z6Kf_~M>^;311A{!Q0&uWvxpa>Ep^iG-g$Zrazxtx2|v(&PDV z2y2E>wH)EbERAN7&+GSZ&65r>%9PWMHwYavccLP;Pmj-$@hM9jAr*S)wEPK_n~vpqt89OqAj~PbkpkJ#+d-mgR_ft zPOqniZiM_m2FZBS5L{em6jOMvy|7zErP)jXJUqV+?JE⋘ z))C~`Iuvo(~5!AC2>Jw?-Si!_X3+$rR^bTi9W>$v(fSp9y0K|0#^C_x0ww3b8u6d^KiwSttN_=2 zEaP;;Oz68nmvW_KGp7%hiNkCmj<`ETnkkQcJ;LnGl1Esr<2eR>J(kD`Hiy~fsOPAC zJ-GUNc=L69JwhDGm%iV-gKiQ>IhCo^%RWKH-ZM_$!9_Yhz*PD1f5yuG^HQh;>}j)@ z!57n1;Wjt_I%%7zW3&t-*8ux4^Q0bL_92*Cz_7N6+I=Kj-om$y^mh|!wfJNmuT=g# z8spIE1L8#wZ@jfphCpYcC0L!PCj^_92;6;Ol?u20ld1pjZ-8V2+43k0>xe`n$|=@9 z+c4n!00+!DAlbk+412@d1ADVf27L#-e41HcA%JHp*}ypfECz;2a7KuAGpUm}eA=Navp{U~lX`jxoFY zeZ4Q*vX2FLfZLWS#uea}?#wwM=-mr`Ui?l`b`@M3d0__{v7SR_Gb<)&xwK8qOk5i7(LLB3s zK*B#mK0(Dee3)CRO1!p*J;scF1o$n2&1^mPq3`#CoWb8)_*Mx->rdjU1NH{QOHfZh?>FK#z}ASi0H5y9yZ^5XJV%B};Ng?3k}Zq03U-jJ z;_QN*UbqcwpSOo|0O|Y?gK+}>>Kut|nPyg`RjOXJ1?9Aln|22NieZwkn|Tc3lBbt$ z+TU#t8}tr8Mfqg0M*RM*a}XqKgv&MJR*?j&bmJEhe(u2Q%zap*wuAfjJ*Y&j{;h{s zx$GECtU1sn$=v%5i1r|#$yF~gys32N-q4^B6*X(mhLAb#NK#W^s*8E+lvvOo!OSYa^^A!CMyT6-6UVL3;cZE9^p3e zCbnVpBeG?&X0c|DLAYz`Iqp8%8Hz-{tnylvG|yzP&6o?g{*{aldH!OX6bVC|nF)66bXSS5h^l{K;;|8S0)ZP?3G ztt9;AIuXSp=r00&2V%o&CCp$9^km@c z=IQ;WE>-`2^Oy(P1^mE_FGf9iLj$I2sn0JabGDAOqZe(&vj>^<_OelE=-@uo?J09WL*4^Du63vlfeXcbZU zK{x$8`V^&1d5C?8{aMWKc;|n;xcc9{1FMi}e3mBe3E6U|z!3Y32-zB){A|5Imr8|r zYpHsm{c-a*%HZw6I0R2$t>gkR(zaSoH%BMGMD0Zc_1ycn6O6eJ2RWecygUP3K{SeT z0lYB<+K}*p{;5H758LjeRYHd#(mDE(Vdey*eORjLGFi+s`!MA)pVvkiVfI4pY{P(A zw~c%e5oL1+jdo1AutrQZuU4X10pbRW6m`<5CqM&(c1*Dds<-}(*h0eR?Lj^ReBU7k z!6tu~coXFU(mDB(K&NmU#v#`JB?8ty>j>L0$|+D2@b*y8UBgk&0Sl0RievBy{RS3T zfxyoI>aiKxTA9~Apznlsfp}B+OT)|qOi1|nTiJS{4o_p{t2PM7n1Q`y@ri7ibVaV( z!&j|@VsVK59H~O_26mk30x`)PMARf2AE&7NcpjZ#mGU^shOfJy3#ep<*stK*g&HI~ z1aWqe&j>aZDuI$^3m+0b&{Uxv8)k|%qnyS)@$w|tBw6j^XB&R)bBf~Wb%;Sd2c9PM zU8jIf{uF(PBkIZX=zN_w-ZipT2`!>6q8x)+`sv1>9|6m=SffxY%4Uu_M>oI~JOkaF zF=j~kRq`Ib4xy&0f*ohbZvOc?_*?K-Il5f^KsjOe5ybjUQ|GC4bDl?+DVrsKzZd+< zBuy`Sl*Qd|g|tvBOFzij;L9QfZ_ggKQ3g=^!CkYCAfL4h0UaOf2;}uIT?cG^$p(_u zRTBCs#)%nPf=$W=!0B8d0=|)bNTgM)nRbS58VU;VOSdq91qA8=iAMAz@Rv~g&($x~ zUZjb$i+aK`+AM~*jdl!HZ{7n)=%uQ?JcAqwRtT3Ur|d%@n&lV*)>Wx$fp)zV_Fk!K ziCU>D+;y=A;RfOb;l?Hb(fZ49pV!1|h!+H#`&g3AA>6fan^vJ(iB@5`(li~%Ab5{44hc85@ye8i+fq$!BZFUQ7R5Z<#v5W!HGp>qQEhS-|B$UjL#kG_ybFk9iF62e&X7 zhd@)nFiAZJm|?tapd+Q42mCNNSy)H7`UN^c#89}6uN!bh;A{eMAm9(DnE;y<@K8Cr zIl7b!zmzKf{Ss^bVz7&oYWl&6YCg$)n2oP{oQZ6ChIWzx^q?SJiGDuD+{5b{Fh~9Q zk)L}XH}u^#9N-r0!~EQJa~^%JmC4eFyLJpIQ%1PN+E00Gni^&ELq)ZeV~}YaZ`&jd z625s7@|jDZYe1R_;EfM3#hX063^QY%?P0GGTYO?4B3lNkRGTQPgfM%5x0q*o*;)E? z)cst*LQXRQ=ko?(%4636x#}S2MhV3Vs`+a;;7c}03b!?j*?okBFWFF{Hbp_arO z7l_nzh!-1#So^p;Xvb&Bf*n62N_^d-E&N?T^Tg9jyoP)Rv_#+U#aoLtzwv$&_asiO z1h86H@R0ClXqCz@5p;79FMx+XO^3fV#2)>8g3&0$&HqVUt4Ot+PW}$=CIP4vU8qH| z==~=5Ay@w{PK&6;r(-m$giJ%ggieCg)n91!f_9Ox7vT_M=?^lB1^gs)Ky z*cR;q){!p;t^st@t^q;LmWk7J%wspO^i#pFGK`#qW@!{FlFXfhf}FJqiPwM%2;ow` zs$B^2;uHmNXAkm-*ItHW?Z1eyjjWTtKj+=BSTp(&#UkJeh1yw1n8tyU4)w%2=xJ<|_zLM6 za+HmI7$p2%9La{a?}4H#{H1dc=rKUPM7RNaQ!8@=`|h1izEuLw?)Q7`LP+PE1fMK= zc>-Muv{^@<#2I|a)|;d5<(Xv2*Ezs+3530wWYEd~p|XcfwC)nf*WJahRS4K)NciC| zK@7D)(ltOoE6l!K2zWVP4EC{dbVD57{bHU?(PJJcmlbK6rp7#b8rv?UT~H_8A*fk2 zM?Fo)-B+dz)TCeUlP$XhK8c&6e;$o;nx(H;afU3>2%=BPW{~hOa{N2F+^YVP0^8W2LTo12))+|lL3!!#j5A&q( zmmtzfwhVKNaLG1Iw9Ytza>_K$(+k-H1lBx%7wX9+!af$=G+#IR5m;$#!&CIIH+0kR zS4ijBd#oeySLjC@gjevG2W-O#m#iaF^*|HAF?fjpGy`nIzz4pC$U5m@grV{wAy`~q6a;vBVOd_wu&HJGEUG>RVn}rwpgQwH`Nr>Gw$J? zWDsj!AzdQhB%q%PvmasyeQ9ZDn8!#~*@woMJ-tfQI0rI}DilXqY$L;8*2<)r(9S@@ z=NyQ%g}Jp4```p~n{G_9dWpa?`c1u30Yu$(b3oKzp;9*oc-uffZxi*}C(;%uBsK_z z+5=s1cEew;5#K>~2-e6Ba?DdXeUPf3V0@hN^}b1(Ol|P1By&jkpj)?bx@!RD0dEgb zKpms45yRfh(g5|7L}R%U&8&98Dv3@$=(9<>QY|N2GfQKVhP7X!*3UIVoAo%mWbT0XqYT0||5jT^aZ!?F{Y?);|3d;Raxxd3sM!lg!_EV;=B#S;uz>LO~s& z`+7ja=jlZ{KS5<04|L(~BU`qKS|#~nP$N6We1>ctFWN%3oM~wHv4@vq5bb!5x`!9x zQmsTc2jQ}de+!>x*3F+{k!1Cox^fxr4&3!6!ZBKn>^v23k3%TyNV6DMKm8PB{vk)V zK@$C_PI?O;@d8Agv;IEp+^sH+5a zw>`YM5AT1q`?yT@=riq1r$DpV+xN$4oC82HQK~9cukr))pjr+RKG`zDWtpK?Y2r*n`*quocE zS<;nKRlu4|(a%wH4gg)&E)L2m6qGm{|(Pn87E?Gvi^g#v=@Ik#iKR;Bh643!`DVZ>`0MmAC2Z-8E8 zf^m?ei=SZo*`bqUu_Vof0M1jJOIp}Yz>IKxCD|dGmnY1GLNm0 zUcukMk}U%U9}+&$RRZPcJQe$pa2x#;$QR)12dYu#F`)fDMIl`QF#(B2+8OjC-X4${ zBG~aWTMVd+Z(-Pn;I0`bz#HKjfPAKt59+YL@itARpAv7%(S?L>9|lx1ecV9V6=~bY zEzww_CR<|@<>8BVOte1A0yt&)Dz1Kj5pR8jZW}4kd4??BjDwz$8dKr4$qJ|2HA#@&!F!>1dwhT#C=6td3$hnF%Pi!HVE&aLHq|OOn>S{ zfr?nL17wDD@q>BjHh=IfxI$X5k94{$=lXPihj)6c3@K)iS!{n1Xi4QDsfHvDBb zU#Y4?Xr`fMV$3sN51{MOEJ`!k!{+MG*I6Rx>c4}oP)xKe(zJ;>MX^lGd+;ha%pTZ| zixg-!Xfkkvs1t! z^m%l#M%uUy{zOZKN|2$lO426$!71gj`Zq}UA&xt^k3PfPg8l*^j|8wdts`>1G-f8Zy%g|J-GWGeO@C5D?&dDFi|U{$7m1o z9;b{kgIyKa29WRp^TXA@jW^1&h3^vhFjqI{7|qKQXt)nB$(J7H+I?i4hb3XSo<=ySo;!VZDK^P|Pp_j9|gs+>EX0k{D zvc(KD$(Kf0Ek0=%EKvG-%+UI|=j%`|)JZE=q?&#)08u!bs7`??`erePNf1{@xI{jC z5s_i!5Gqyw?j6Xm1CczWbIbz}t@)|xhRpv;)f24)`;TfK?HK60fz5=s4K)1%oy=o& z)2Jsry&%3P&`G*NJ97gIDyIL`|BJK&W0WtoIX^`Q7ooB=IXah9Aal02N{sA0cs_K9HT6k2zAnlmKLA%vW40~ z1fOVq51VuaFhrmS7$kh@I>6$A*e}rYk*>hrAY4+<;cYWa0$o3dvx8az0-e}0%nk#y~Xc`E3;T^z!V5!NPg{;tOPr^9TsG%TaRuUrFM0`0@rh^6ZurzBX}MvAr&ZphX&Na|&O zvKVKAy@9*VFbZ-Ge~EfB#{9|RPuk<3*SmK%QJ`J{+pu9K;P!R$ffclcAK=P1e1s12 zd*!QENeZ<6-Aq$URl!LC?A6$(VCUfKH~0eTa=Qk+30nrwa%ezQ%h75Lf?mp~25bXu(9{Q;rT()7bqY1YmUR)vo4cISUiKmxwf^~#? zj;EJ(1Ss`Em3Yz>rE;JoF49ChhP?lMvH&@Epa!)1w^k9_nOPd$9Os~9vqZ~!sTx^@ z%De|4N5jv3AIm(6eW+EWmq)dfcIKz9%F_$zp(_S}SveK1ZEqqLVM&mS%!+_|Z89wxd-CTi$y}&i zt1$d!n0>0LUUq}zCBijarvTOb9QBhp%7t`e)l%WMQxvVjAZO$=nc8+CkShe982Bvo zoo>z{Mz&su;P-piaLrPP{)C{=YR44z&=hjFWe^F2J(QxYyyk_3Lg1P zpp#+|F#OkWT>T)f0qlICcJU^l_Wt#G5FO<20;)lV$z`%Dc<`qByq>0W_e(Z=5dr!4 z?_p0cE|CwjnWj$BOVvM(1-0kzegCFzl#yXXv<}p~YsB}zB3y0|S|)-BSDFd1eKHNf zXZyH$dq5l{)pQppTMy&VIv!+~Un1;btNg$?#5ml?x`Bm+Pdfvm=sNiugnQV1+^{#H z4hCODTh@q=&>JLKM=U;tI8rRGkUoh+ym0f6vS|`GOGZ7hiF%j|K5O@}MbzI-rq&^} zRpdp)IFnd&sp=Ix6jY9`b$qBpreTy#vlt|N_94+0o2U&!u;NHp0RR6gc$LJ>zf@JE z)iH!=yiFLqn_x8@ViamcKX(lAbC0t5sVne#Jw^ZMbEctrQh_$fs%k0BE$ayI%g>Nu zZckA_^^X4~0wCA{d`h%qjzQ8D5HS>Op`GFFp_v6S1dtC7dvgmzKLw)7fcN{U{`fWj zKp_a?e=MUkvj~@W(9S{UNR$gGrv=&#k}|dILr-HNp=0e!HnfU(_`+Z1K5Q17rNKCq zukv$0M?yK>AiPBQdLOW^j1yGzbkn>&nTEYQLhXCl@>LCzKR=ClA>Oo&=kuC;iGIpH zOtwb3OuT7?6?X@)3XBs&>}AT3@bR`S6Swf+zW-!#jOOn5$-+D-!^k8p_G$P_qIHlr z39?KQtU$e*K$jKLDtSNmCvmGJzuxPw_rDl;d4d`M@7~c*Ste4=e{jmz;TRm`Q2%z0 zq?-eof4ukIIQ<4zu*1Vwuww`J{#Rd*By;TorE(B!oTCQb(I$ao2#CrZqXoL$`wsl> z4#85@pP!C?-XR$NGUYMVe9W^%ORRm=6QOqDHi|`{1OcA;|FZuBj}JskK_(zqzi5kO z18)!Dd^iUPHt(Q8eD4|#M1+8K2_ikf^8a;T@U{T{7xzo76V(xw4!KIr2Xjk+9wRh&xQ1`&fNF?xj&!l zdcR+{PNeJ01GP%cGA|Ae@H@sHdu$&+&yZ;<)~Q#p?{&QbsKtx5@11UzS^sb6Xi)3; z1ti$9Po!ByJD<8wyAIULn!Wo}n|$ zyhD+$pSLF3u2EX0v`c7}eAwX>v-zt}kZM(%q+{$D=lXwhj^WTswWD0Y-cc_8{(b@8 z!OSy>wnv_pYk)U5$B2j^S096QjI~Mf_czYAOEAtB>P@pS%ZPCTT|SZ^(C->avy8%n zi=s<(h_^xh)_El1;tjFR?|lv1#IKtP$Qot!3f;ozhhRR3!pk)xh_X#ewSs-{HXwif zLCMWHN4tc^QLk{1@C<{G2mIXJBeP6Eg8+pfJb$ZHbBrw0GR>e2{E=6yM7;u>kl-S` za1)0Hl~9vxy@E{=D5fx2a@E-_I-2Y8>Ox%b{E&SO41O zaQA%u9Utfyc!w_BG|B-l&>AKCglXo5n+o-4+}k}>sx!yc}C>H4=#uvYFYHOR{|P^%Q{6zGq14fLg2ZIUIgKbCI@@)_g2e+sB11N`rIfo2jx zq+Urk2le{1!{Fe0yXWvT@bjow0JY%qwfm>2SHAy0I05tupl^2QIoBw7cDP4??y>C? z*C=#q$khiQ&m5z055v4dJt#W2d|{bZsaC9`S%whoTcZT32&j%3<^}o(_~Gj>Kc0UG z)hd`BDAlT0@DB{}j&Q?#sz}En?#02kdv0DJS07F^#~%UFfOYEhJ^T1_6@Y?Gv0Xq2O$Kg9dv{@e9F!)$~b z)-AP43|6@Yg9X|H?B&4${x|*)wn=af!gH@tPDHFy;Zd;WbB)4O2i$-#*^_8zoSS4r z64od;eOsUY{G3Cr5;S1Ifp~nZM9V5gsx`#RE}>ilhqg{8SKltdJD7dKGxX(wV~=5X zdF*kK4i=MP#xmV1rBV$$!BEc&HwXEcXP~>UTi7PqB?@l29~nBtb&7;~!FjtryPILY ze2sGqy2HS5Ay*&B3;}*T!{DieJ>1(p6cnReN1mR!Tdoo8ZJP+LfX`c{S|i*nQyJ!U zitG|#$Nsaf*C}R2LD);G{6s8z~4ILrfBHF^cEk>u)Qu&$BYKYretWdiDf zS|uRP#5!Uz2qKU_{QXy{80O;~%+vb>!O@XsVU@x$?iKR$@2XQ2?hgE)lMi6sP^ed` zRjvUw2atBium8~D?-u~aDD?{Ta!`2Qp=p*$wnaLcWzhTp^$&P4a*fn0a*ZP0tWzB0 z!29|+G|ME~saKGMfBy9dGtS1N?ww|zV3-%_W|{uFnOyys2U?}PLMqhV!>d)gMH=Mw z3f}H{yT?2od;z+Jk*;-$IJ8;D0Ka_0Fi(+=d-ynqQ_RQh|JBtJ5e0gOp640#2&bF- z27cM1QmtFaG^F>(b{jc~3=oU>g z1N`#!f#h-Tbc6h<`v_u>@XtA9o5DPfJwEXeh0ihpKQ`@ByF{-LP-E7;vi~c9JF)jo zl#5Z0O%m-A^UMf$wsEp`oP$B$o4w}g*~Ukn5|H`&-oX}Wd)~%6(l691sZ{^_Pp#6= zIr;=~Xy{b1OjEBw=U=l-saC90z2a}wpIRko+$t5{;53UsKWJ;^8#u<11nBp2jKeG$ z`f4!U5$lB0;RHMI-+q6qz!`#JKF}B3D}DiZltG?*xJvcQ13!o>e~K6!?@o4gu@IFCg3<)_OQ&R;z6K<`M-8@c_S5_rDX+zDJk`^$OMM(<32XFeiGq zn|~m}jcpRH7Ww}=oX50f#(L)h*PWyc8YZv?7Q7tzO+b_tB*(Z2rtrUl~Ar7 zerA&87vL1bHENX-?Hua)@I`vkp0$}~~VSQf9e%H!y?_F_fx4>t^wVzY!i~eJ0#erSf^IG?Gy8iLOq=K zK_#^LE9ik?cldiAaF1z}mudP0JwF6K%vi1yo31%e$A6)L$fT}HOdv^bn=09a-HH7YpUhB+vMlpu-gKj&y%Ci z56v-xa!$1h$e(MJX%_zePBAAQ=IgtM=NewUvgOOsC(x@>sRlp#uX(Ot672%|Cdc?Z zL!Y2RJ#_znoYVgtJ4@lzGsC>)%eGIPWAJu|$-#~fu-^p7_X53W7m@%opsk;`e358J z5Yaf&a|P{UU^sz`;p!EI`gHRTJ8G1_pVR&vHOlt!onj_g4e~w0pf=+jLJ(n=15^~f zg3_IBlDE&H@b7npc_`N1ydcpY=xdq@{jlFNfe)ZwAsFf2CeQzhID8skZlxP7&-SD%C7gKkP8dIsT|$0BA%6B&obxKRd<5 zIu__nu}ZXm+mvF3B>4NEx=*fttYd^*i}Z_w$<~}>xrR-$aSnL~>E`Sc26?PgUpI4( z-MHu%;1;1-R;S1@{%$w>M7zY5t96Q``kFk$9OIzg0VS7ID}o42mA`rZImft1K;sKK zI)!@8G7MI(5g1Y;-2@~Ct6C-3$Tf<_;n018-6E200{wK0Qmv%#E8d}1D#5-vM)rw5 z!LOS=!pb#%kZS)F*DmjUbLZ?h#~P(w0tLmc_tPw$Vp%574>ifsFW4p~TMPF9lej`1 zl+?pK*Dnq7!S0&0uWE=_vhC;-#<^~hL(e_JfIY!JL9RZmSYJ1rWXUzkH5%n`k4&?G zld@U`W=xi;#oE!%#@SDf3iYD!pSA%DQa}IfoeMWf>$)DC9OSc2Ja?OO4A`al`Yh9= zR?1(0f2!4Qn@&Cm^0{=qRjNgrYqVH9*cJ>=0q??a&?R!n$|7xA=?+<-k^@?I`qZ}L> zRs$e50lTMIn`Rl5$KXv$vOy4cmZn;=O@cZIk0O-|rnKM>dv=(6q*Ltf8Ov0cDDuC* zO;V-Wz0=eyFAko)(SWJplPa1Nw>&0xkcPPL$1C?xp}&JMXY0>F9A8h&M|)UiF|`e7Vprf zZ2^7E|zPAcMEA<^Y)K$9k+cF?-1``m{ikz9kdIB$wacSim#zaP zsB|ZEugKMYdEmp2TtnZ$et|_g_y+aM1Cg%c9gK68YGxT&Osb_$(d&KY=_yv3rs5s> z`nrWzuIdyy#K|_1%9UtqnrV@C@rFiugFFFQq3-Wb{`?0N?yFatWk7pSuaIa9SA3Z! z*RWipLfs~5h_^?WZBnEgkMat^U|Xa+#lU@=ZCtKFDp$5~w(-8#RI8G0VII5R0Re>c zbNX|@%+fd;I)}#D?{@EhCD9I(_!(xqgcv6rx?6;T;^B!oMuvI0#!9siFUwTlK#Mfc zrjp7f(Jt8r)7nKk6kfRoSb%?b{XvB_%fvnb6mXg5&0jHCpzK!PdzVX_ecRkSlC@y{>H=KkzLJ)jc~ zrzgXV#;-!W|=zb8;507N4+c-leOj_&_Hs}=`a*=U1;cmvWHx+fI$|5mrKbmK# zqYSD)cj*g6AHkT8l)~8^HsU%pM!810NTi!cB%g>QHCe zC8vlM720V-^RwcM`q(0;Kowjm55Lo6u%ise*ol?vEHVLq)EkXL)GOsOg_dW?Ors|l z#7pZ$P&~jOZrpV{FR{i2e$mEZK!|ndU%5wmI^M4B3F~GY-GH9|3_pl4Pwj5{dF+oV zX@J~O-a{+454U>L>*gB7wdR_zj7K;bW}sax(nUMnK~^g1<;OZWBg8pmny6G8Wi(6D z%);Dx^;T+Z5XUst)`)w?I$oGRLEpg>x=%9&0jKKt=Jhhn)hGq2!)E1ug50A0s!%(| zx{EbSccsVOB-teo;Nm$Q|8AsCaZrlO}j;E<}oaTzp&zy&Cc*U?&piQ+wGBN8fANXWDRC^ zPcfTeRjBC^xle1A9AEqp-u~d){>^P2fc7{C@WGuz(=2&}jVxvZBS}@OXJWE|lvW7UtdNdo`<)&09iNHI{pv5#N8155`_i!8%br%(g-5?$(~ zT5+WC6(Zo5Sx#&}`e~p*xXu^(nj`$JGW!_dEQO>H3;ssBdW3a~7UCt}V44;R0OzJX`|Mg3lk9QEN+tY#x@GpMM>y0Qk7oT=##szZlWt*lsr(!QxA+?U0@G~V zb3hpP6=bvp5bRvaHkx2PJm(pfZxCzm(@O{i+c^z6t zqks)%H$v_M`xaS8EThs)xa8B9>-1d(ZRP3|T3}Qi`b+!(iKlsiF#>MZ5Yz!0NCkM; zBx&3raJVrbM?W3MI6YLq?39$#!QWh9WZa)&G>TtA&rS**pPz+i(cAX}}}f&f9U&oR~%`x@y8dyamb zjhA{@s!Y8UGKwhqV#hx~62xy-XYiN6TbR$6{)bDiL`}Y`bzGf$o%18<#&InpT!j+) zMYNMokO{ z$L_VJ{z?7^LddUI?M7JnCV%4bFwbyTuMn{g;3wwwHFn4FRG%LVNW^Go(Ga7pJBik5 z0iLb{kSk=yWWWaJaed?eIMynMWi~yBpkR?=nx56k_fJMhsaCL~*6$hqQeL>rD?|j4 z#W=$M=J?o|&!$<7i|yTRJ(7t;Q>>Eb4|lCnDbg?d4YWOseDw#fPe%|jv0A1H^<2n4 z%ew9RD^Opg6>-$%_A8A}-+;bGTT<@_%9o^gz117nIPl>0KEMfX^40*j{Y9>;+nX~! zU!%l22|*y(z1+A;1lLCexMob;=HLJH`Sg$Y0ck7A?126C>lY;8`9Dn)@Zynm)ei&& z=no*QZSJy$18i3RbIZe1`=6Wd&#x&$kbwUf1N*VMT3+<(*9e?|uW-x}F}j6wZ3 zjY0gkj3EIG{nr-Ae~kUt<_!M7IWolmrm_G0jQ{rn`Nj7Cdys53RXy#L7Dso4Ye18a z&jUiH)o_3#?I!|-tm)r^0(8~{3OWQ`=zC{5if5l+SMckq`M*s0<8>l*?_^IQ7IMk1OxwfU&?-HJV93`M7{|;H~v{Bjj;*{$2i@;B-rZ^{@8zT$WSdq zJ>l+};4F=?Or4^C+RuO-RJlBGH8{Bz8Am){ur@CK{KS%FBvxUOGrq(le)-@U^9dhb zP+%5i#xwxff_@ifrAk&NB~`{F^7~Qm5E5dW66Ak(v)qHO(M|Hpx9*-~e*HD$nm$Ix z+MB1N9XCu`AoICNm(7-Ey5u{dJOlp`%$F~;Nv$)v=v~=iALi~+i!`cMH%Ood5C#qq z+V5wQb4C32x37QJ0}{|L8*!@_+@Vh9dRKAzQ^pRJ)9+s^Frk|B&4IR0M<6it4*ccH z+^Bl5wwc=`bCIMTZpCIE?g}loUbBac*95~SOp=9ci);LYzmwaxM{keJE~Qp!w_APS z_#(GZeQ;xtS?mf!xy=gA%*sC943%vC>QAJF*-u}Y>GFz3{roEGXjhJDAKDt5r zuM>DnW=V_mz-EWk$M>l=c83t-X$4y>)uKJj7<4XfawW#;YXDVSUoPD|Weo1Y(rjXB zg>wH=A>P*bYjbf!v!ntw-wwTOuSUD5H9W&Kn&n5$fA1Qohbl!(D{&G-Od@S-z+yz> zgof5k3i`>HHn4|zO0$HZDG+6o)n$AU6?qcmcSN*DlVaTBcsoDmp*v2KfNh89>?Q6_nr{ zW4B6IUdeR@O>4qgtPy2!li?uD36K#1LmA&$KAXm!~>K3;QfIC1s$en{K>@!OfS9X)f>K z55Emm=@+M&I>e-o>F2$IhPDX^a*2JSJR|O3m7ZSbH^eMXNWM5IM7fAoitC4#jxEF2 zt&F)oM9+`;vr4l{PqQd68WLO~_4O@EORSn|c8F_BSf11=5bNFSE7BG9R;gT~Y8HQ* z46=ZiJd16_Bgr$@ple5xJWg@+Iw8{%<0i;7w(pJ z4L6SwZeQOy0S$Iz8UmCcs5Yu20vlzXdaf~*)b0>H=l-A%ts~nKUB89RJX4xC(w3v= zPFHa-B=-ymB%|=JwOpIUfc>-A22 z#E>p}3pnJ?v5ptg6bv_5AeG6d8ayQ;8uVJ-kk@=Tgu8btS79ydCB3G=*sC!}MIW1y z|LF!G4I2r7ZnVg-%qMaHg>Q;T*Ba!_l0(|57FT;S%=m^0wyZLPn=_2fQ5<8@jTqK2 zPngGo0KusfOm>;f67@2FH}nfa{TuY>2eB`q656q+>Ebi%E|8RvxCx&_nmeb=+mon6674z16lc(|9#v?bK(5&AL#{mCOK_c}vsqDCb^~)kd;%-Xf$+=L7vh`Z zWDZR>W*ZP+W$%`*kE_x$=JQQ22RX|I4eXzxTZ#x!v1pOLJXEM4 z+SxA-aB_xLsrU1XbYdUISNYwj+uZe6X3EvGjeYX;1Ji8{2t1c+9%79%Mz~xe-#xI6 zUn8v(YZj)Ne%{e8O>+AY0OSKhD>S`g_6PrXy>W#B>)yFNs^sGn_!mt`H*EqtW|`DK>5(qZ+#*S> zYLssIxQFoy9btL>rPB3|yiHOfE6_hr|JV5+<-&866W1I54d|tDNvu|a^cMRw>P6Wq zl~ec+dH-OxO{W_0VWHF5pFH?AaIVNRxq+8!`MKD7D>VAt?`?O3?4(-rv;|c` zznb}M(tWuwP7ktbwfqu}FLbQy#5A+b(X~kgN$aHi62{jAs5wTiQBL6n*$0?*Nd9hr zU%irltis zyzwzO!kFuXzj$;ljow2U>Y?J_-d!DL?lICjMdsyXAKUJ+kNaoyDl|&HzkC*Fc!#i# zPvrFeq!|h~qTbSvFs?ozog+aXbzQc5@EqU4E?{A=ukqI?x#hj2wlcXnv{wHO;R)^< zL(eP{)SF=A6>^J&cGoBN_3=kgDL+Ok$Zd_A;Nk3Frsp3(+joS3arce|2*_7(O?~DX z&r(+YKEsQ?gSl~vEEfSjUN1v@o@BJn+(oC}!oRTyD;M9Ju#WBoAXFO=)noZ%czX>J z;3s8T5&x_*hZ_D)o#n%R14rmJsI5|`2dWCbpv4cwkc@Zm)KZzmxD^Q3@X|QZ*~ccs zHwbSljX_p6yRxp9YblN{hyU_`j}!^tf*Prt;@)5kOydep6ES1=ADUs?UMZtYv3 z8&FB0TBcfI9DKyEKgnxFQi)cR{-ZIzQ?UI#a!0cadneiC3En8{>#1F>Q$V&}uBKek zF488MX={=;xbq`t8YxyF*RE9*WhB>#dO^9pzGDB^HQ6a4#W~5OQtJ(Oi0AgA5+&O6 z9ojXe-0+(3lSZ^6S)qo>ZDP>|<(vQUflYd5B8%7zE0LB@_!M23_xl+q-o_K+3~i8~ zFlU3jM1!zz_Y!8s)0-kw!mCS;dbu_F9?}XRFB;J}yy1=WMWk9X#irWaB>k0%J-}cu z(2pN{zZB^X$)hLW=ZBlrlx}8uYv)K(O-rZ;x2D$}-1wj`$}Lo|2=dPQ zT8p$aYo+{V^5=P;ZX;Z9>3#>3tz2a1`vM(y&;Bb-SI^!yA?Fo!sOEIuPN<)F$Q#T7 zmEoGnX*3vxT3x`~eJx~#=FjsjITGML;M=_q#ctHh`xU&uSM$PntrSF84^Qn$wG8eW zWcy8^1scngjN=ph^l;aTLT7OE+rj}r+j%8mAD?WYQQS2i(ZoM6>BZG|bK@H#(Os_O z5?!{sM2d6>=BQ4WV=C8LCkg3J#uMN&!aGkX)&1Fe&>Jk(5^tGd#{Vz2(Gg~ld!9P5 zeTDiA4fd`r&>rIktw<}-3$UUuCs_yiWa~?GdH*HWx(A?K7pSlfE0xYt?4qewatC?{Lp;3Sw2~T4@*h__NHs2`mU?_~5`^@McyhMyGhG77R0YLGO^w0k}C-7iotlgmQ8YoClg%_yPu(Z!%N=7F+5#ig3pE&na?t`o}59 zGP-kym1Q{4k$I#}iu>OJm9&8U-#xrCwRsZ2JeIcza*R{WFHs<#ex1|AgOFp%ux^O{ z+YxAwbjvV#goeMRo0V$L%MuYL%w3@d)zcEFdo23WA;Tq05R7C3RO}t4Oa%Cz)?J|V7D<)gw@{Cz z+jO9cO%?$(oA}xU>gJ&TlYL@@%MHfX;MsvCMohD3kaFb`C5|zzZ_VmG_1sRa5Y|_a z#R&!VzDSzuXeT;XN`zo4R)!^g^SJt&Y-8$edF_*P*ec%u23Akvav8HcG2arUhMz7u z)pBPbjAM?GelgVJv@){-BDS0tim`oqlh6luaY}0wF--Brg-|#ps(t&j0Cy-wt(R708CGHlvc)4iB)IqmUkK85l0{k~$lj*+x zh(ewsB}B`qHd#V0p0X5?h(d0T7h9~?+k0BiFG8`)&PZi z^Ee^HqJ9Vui!2uT`j87uj~|&Y7M(wuJI{a zlIy7>>;nns;U%@wA0 zcbVQ2Ntrt3>Yc8|ymrJoUR5nP5mA0ktHYHv`q*VKM%f#;D1_S`KG4(ONxs1#y7_M6 z;4T}QO45OtOO^yT=BbaF0-c%oCFud(n1%+qQ4VK)UIt*VrQQguQr&BSCi41Mqg{@9 ze4Kma8bTE{*ARWIroO-tbyhHmhiJIzJ5fJKk}GlfH4;({&=l@ARHWtiohdG5I2nAj zZ}7MX?n#`h6JiKTQEL}0f5$P#NN)<@ z7G@NG@`Kb^{^MDBshd4RN2g-4FZ(_BtXC|+5ABYVjBM{2*7H@QOS)l{*dzdBZ}iNoodw{XrDsA#5(<166DG{ z6y#X&`wY29CQr*12E%-i@daguPql+<@oPyv5w>xWJJei&dWkn!$=_Gy3_0E8=^>^$ zrqxexnCt!ffI)RDNR=g{xGGgcVrw8((%d3d60BoK)dc5{ht2?+wXL!L3&C!1@cX+} zVw+;Ac7U5>ia$3y)Wp>Ic{g42W+33lI>2 z$<)#yZ;eWk9?#&m(9&e%)IH>BF8oXMZ}dATf0=sIKLyeiiT*j}Ip>gPP%YZB4e!6? zno-_8q852?klKYh)OHUfUPh^g9XPgJ&T5iUu|sd&Z(Doc1`Rg1(Jtbg9OOg2sE;wu zJi#l~=@4@erx-K*#oB+D-+MAFtWxIMKRTdYoxjxQ>N+UDXR7$*=UX-j{&77gqQ+*` zKS5h$_05Lu=c8TZxYIm`zY~E?$v;^NdZ0ydJPvCIDVQ>PonWlv9I-WO8%eZTcvN9! zyYJ1F$R%7Qzbuq$!O!aqZH)lnHrK^DrCM4f`GntISExHeg@iZze0>mng4}2M*Lh7d zxOR2dFJ`7OMzad(l!@?fId&qxe6dZ}M&O*dhWUAF6~Vd&xiEKWeCkD6CSzVu4*qd( z^RELWS*03Xk`@SGfZhioHdY5PXjFSm`#2}CzZ!MtQBs5k&`PTDx)kjTiZ#8OGKJ`) zWJ}(JY7i&T*{0s%_rxvBy`mm94yeD-6J}~$tuB%XHm{XzhxV1`GOX0eAuDHldgC1J$xp$6dQ%?nXX}@MwsVf~Ncd1(?Dg@xNX9zs zpTf8t;{A%7uPyKucEX^fCgKt1O%ZX@r- z$%KH&Zv5k7Pxg5($3&=X;~UTkc9w1V_Vl{vE zDwM+=Z`Xw#e}h(wKwprpe@5HKvq{TzbBq9pG$YG3fDO1V%Pc&uSYnK(NDZeu!BL(V z(=(TMH1`n;jRu3Y^qe3sq+frnAR%8-$%Nn7i*D?160wv1pNY*sn-T`jSX`6 zhhAuw}?2T&~Uq&lXph0l5~|>!b%|0c zSYT-z1@*J{I{siE^YU&P%GYU$)lE*%;u&{K6=a76ZVlxUMYwDbA7#k(BdGD$&vLNPSmdkmYL^NGaXf_5HbwQaoIg?cy3 zEKbNa@_^YJ{vOM4F`i72ms00GI^;e%O_5}e(0mscTf&~Rll{9UUSJy*N@&mq{=nAJ zj%S=UERxO0z-#0atXHft#1y;LuV#UT?!zY3p<1O!;U3N-npw17{AM-1#WJ@01AqJS z#w^n)BE|;`Mz;6^3i9-rngIp!jJj7Ns!$=GPrp1!>6l(MO1cQMm*ilc7~oO;%(b7a zRAQxcD)H^L?fFI?EW3}AQ?r64j>S*Zi^-Tommq>d?kS-B#yryoMb?Saj zY~T~c)?@NWh9lf~hj@WWa1Cx=7K&_bi41MTurxrQ z#=1LZ3L}A~RMoFFKzL8yJVATcHZdy)igmJmBvG}-n@4ciCOSteC!e2+p12|o)N5+Y z#idnQcq|ZD6`h_Ne>_JIZ$+|&VTF8AWZ>}=>MGS6Xa1DRQ>~dzvN%C&7Cc3dH-B}x zNqeP+@xAf%O$Q!3&jf{pe8}RE@-1K+KmAam&v+|4@%_}tou&8BhjyD)NI&suhJMC0 zMrcI0MsSDpDV-Z&rr&ClhH<7`+K+#1Xwq5{`11YQ;%~rDHFx zdBffFe&rB`6^m3$sV`;fnd$U<`qj(kVSQbq-%zewC9X2u-lATL+zwL5){c;)+dqhS zjE?Xvx)Y#ecYnb)h-Ab4)jUyH%`kpcz&ImHihZpT3EK{`e=YR~?#{;Zq zh-{r}_}e>_dv3u49H5IvU8Xs@G1tH$2Gldg;SBZb#~sxk;{x#-oS1%-Zn>Y0cz%eZ zkB4%dYJF^nVVP)qdS_+_0RZzt8IAIHH=|q(?OddEjFxH<-{_V92t5aE#~Dxe;QYhW z{O{mBk|$z@(OcYal%*o52USjNA8m>=z21)n*&sf}8HHJTLgH&s_TeozhKz9vb1@Af zyrkL()!Icywu8F(`C;vR!CyYbS|Oc3-QVL&L+ff4XC?G|hITuuuuiU#yumOoAl)d{ zyY@a`|F~fq?(1BrdUW< zCw69dMtQ<}N0^8BqWz@XNM=Vk`nbk-5KJI%1%ABH!(BAVfD6A~w~3@n%XCCqcQL51 z3Y6j2hErSZ3?~+?k`rQ$@SNZ#76tCsNvCH~t+zzBL?|>NUg_fpbq_B9si{!z2h_x9 zlPGMmdiY)O!WRNIncyz;Q=5Ix;R;o{zYBT_bwjIr*8(4g8TerEkz69% z#FxjIJ$z{50=BuKE2 zwiRT+Ft|wuU>&<5-1#*PbU-@|bVFDt4G`LucZ$7-`;~q>V;X2<96o}DeO~JXS0C%E zvn(}`%^uOTq8={H_wJck?|#YL@f6W|=nG z8qx#9_yigMbc*q1W?HD~3jdq)1B`huRxZoTGEA!0p!*Y#c4-`qcyIcFxgC5Un>brf zC=qrrOM)`JWX1Asc{=x?T4jn|N{mNo8s~6zL~cP>;LBMl-jaDtBVVg9AfQauJKZ%_ zxrk&P>#$h$f!r`F`_;S7yzGOt(oQH|Jx#kf!^k#ql5K$ch_f@!Ke<9gHIRNfP@~W3 zu4jgGl5duGnq6RTu3@Zoh$*ytt_99Ph)bd=^k~4(S}Y-;URkr~q01)i1O9jQJ=8rs z`nPzEVQPR?sJUeKKJXiWXZMZ*|AEzC;Ow~bS68kh`@&>q5v@vBaG(D95rRWx^OaE# z%Egg2#>p9vSeLxW7uo!iz+G#c+xH}&Z09JyU!YE*XdO(|Esn{*9f;S+=0RO(eNItR zoN8rYj+b9ASmP@sdNEE$`0g+goKMig0uC`gZaJktB?GLDfAlNfE=Smc?D~I9J{w}V z#RMnuNP5fvt*KU+VuNs)F-?ZH-@y~>V;-WPwS|`dCes>PSFS-n8)Y-WPPOm^BhxBZ z7vv|?^n!?W66cy^9%mb6`?pr+1LM3v$svPw@%oVP!)G+PP5p~=J7#v<3Ci?CODm-Gk%16 zOw*BW-@my&u}HOT_ut>7TAm#vdJ*o@inj;U$~*q74`CkmOcrQMHWX>^;>6oF#r24C z_s82!ducvz&a4ow(8&taDo@c>DX}Z~XJtFGPhJ6KI6s2>W%&}gXJ@(IW2)4xP=3t3 zM!BvIEmG4kbO%Iy{R$Ua75o_Hk}YRfcot4DAf`Ru`b5m z0&Wj$I3d-3_w;^Ew%QQAIHWx31U)V7>#hvr;tE4VM3OJaHnf9ty3QBUquxoX{CJCD zQJIuueh1Yk;gksG+p~ZDcyT1jQl9GR`D^Kw{$y^%usFCg!#c<$UN^z=k7ty1a0lS( zSc6|s%5D&AUTz)XLEl%&0nfzSj_cO|5?OJ^yuQ z0Cy-h+4<4$F%_3D-e?p9f=k2+wo-J)Fkzh_AIkY|X6x~TRm^lp)(3#~CRP5}YG zs7+30a{9gAepdBs3=@`FGukW60D1I1y=HutA%~T zDdwch%(K4m#T%M+21!6~N>xA)Rm#nB`}nVE3wz`A_}|`P7XV&Kea5dXRG0ANf=m4P zY=)_e@^j>Seu^thLc^gox-qc|NxrtH=RL!6liVS4m6=UPf39D469iPK`6lm5=ayLRluMX6aTq`=FdJ5EtlX>90?AMzReHaz{9k z>~qcBpdj3=`}Hz8E6}P)+QC2h(!4*r)yBEPOwVcl8C{tRe19jFrZQ~mmZRJ5kb?LZ zDndMY#1?2oxs>OQu$Z8@NA^gKGqwu31=HM@H9>vsoy1KYTJLpFuU1Wdr z^nL6=AL6YdEg?WH%pQJ;o?lRwkr2-T9_o3%R{zHsviA!v)TdizZ*4XUAP$HxPy;U}u5R zkEdjZ7x#VNO;4|dM>*x_M3$yh&F48)8WbDRji7F;WXoDz0jZ{;RZa3Q_3y~$aCKu` zZZS4#o{)hpR+)nA9=~$4IK^-N+Maa@Z89T*NVg6@>6Xz2h-Js%O+P=#aM(l|(X(SE z`E>GuZ0aTSa^Fow_vUe?*Z_An>8$~Ci$Z`zHl6ZmDf$=$CwRLxYPfo?&IH@QW|Gx+ zW3QFkA56v`ynzso9zSQ;uHd$h5FTZ^%L7%K-w}F3cgyzH8?t()MRWDa!{ZijyR#|Yss(j?a{+a^*c(=FRR&gvW<)2YxA;p7J) zQ#Zi_S#>A6kyR+n$12k&9pL=SpJY|0Q?fb8FVc6E%_-0a0^kq1$9SihhFL(pCE5o0 zV7(#ygB{?i;D4Bahto&W!qsCFh;_3Inj`nuRRior^=iC~G zXb(t|Y%j^?(Z^6or-d3HX$!5E{3m^jGqA{O2?cfx?aI+#GaXXp<{0JZu_ zR#s?i;|UDIoU8!mdrWgE_vi+-O5pB7+z!#m=D@CA;jB{gOvG~`9-KX`V%&YA%`w&% zX%_@AJA-7K?9xA-M|dGV_jfaFj0#dMZJ{LJ*Y9UyMDOKZLp$#V!WS`pxzJh0m4BGiUV4Q6PgFs+mGHSf}CbE@0L}s_(vkgNu)_$^IQjL2_LQ=~j)=`4$}6LXB)A5u6n3aa)v0;- zdcs;F{Ads)U8Gm13fCG&4SBP`G&E0d9f>V?!D1HmOhs&t2Faua9*@eB;;N_{+2kn3E`~WJJ-+wJT zgrl3$F8a7Tf{S%|2cYj1%P!DpXTj{!0ke@pzG0E9TGcJ=0@W+(6q#mfgF&%ziURq3 zi465fzGahS8xP`kL!UtNPsJsn#_Wv2KDqMcwl%^k$pJph!^k!eUMmxHEllf(U}T0( znW6T6iunw7iv1a=BUfP2H~C(-kH{@cE5h;tBd{AHH6@4U^{|&DtT`zU(WW3z?f4|wQ#nrQKTt>diOpw(<0x%7;mx6znxO8 zH{Cwg2ZEWSkG7@pmiol19n~xWV>~$)3GN1Yr)aV+tUc=GSf{d71r9nNLp*(k8!R6X z`wY8eOk0BE7BS(*f4o;WASS^6KbR1Ug-&cw_Z(noQ1n*JA9J2nKr? zm%&Xhu!vrqA6ZS!Y);%+f9KdwNQw*%Gcc>gz;(Ajirfsz|n{CexBk>-f7ck3FIQf7b%YE_{UA9Dp7m zYS;f}5CG6yaE{!e%(1g?7OT%v8U1yQD$?|dCYdH5ID=0ysunL-LO-R> zDtv@ollXB3SM5U*apY_XQH{4YX=Sm@lY%bI=CmKPyGMb+b@LM>W1RbIjzFyIW*wS2gD2QoBa|{0O zk~8~WNsc%NUne=X%HPAh_(rcSd+_-TnX44Qs9_ ze17%##U@bitdh$zA7a0Q*2N-M@7fXN&dW)0TpT?-efkD)AQorT!txzp9(;sbu z^y=l}T#O1o09ddO_AZULd@JI9psP!aK@RaOhCSZ-cb83|JOcse5QMjU9i56Z!iaXG zd`;rV2khM;cD!v-MzXbH)f4paI=BDwOlKg$QI(>7qGDy1nO_Jrpf)LA5C70KyDOM& zY?V;tYl!g#*)J6G337A2TZD2QYwr;G+uI)b3~*zB4}Q7_WG?oo(hx(3Twr@`_{le| zwCf4Zea9=(YYM*e3(+yJh6GSg8EgdS{)0iiNp}yXct@iDD;Jy}O!b!yiVg|o2`5BV zVpEiR9jvp4gk&n?i(*`yqPay(f9+Q+M2#~a6wE^u_BrCA5q zDMZY@ZGo>2fq≤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

8p_hAq^pmi_*$M&^;8Zt@TRJF}PPSs}&& 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∋dl;t#fAzWFqpVJ0eLRXN4TJyYWooGguP3+uALp~^6Dh>NFUd04oET!cB5Eem}vX(mm>-g4+I;p z*v1gexFm- zuuncVc?GK0%GWpqJBQyrd-@1BjZ!Tz4hnS$qVGXnC0gGjdiycynQzLnxgF--OUeo2{ayndLqz~W{_;!BD{mMkBPforg(u6 z?xa|jY>IK{5%3xZ{RHi_V%ZGM9n^1Rrm;RQrZLcGrm+(=%XsvoFlT}dg>tAngo{`k zqP0`h2MB|-B{Kd$xc_;NEM9@XE8GjStX=s6SYX~FERch_u9dY9Pt&2Ec|F51!YtJ? zj(!IHAjK+6?;1H@Ua9B`dYkz9wwo){Ji**D9_#24(jzok3v<8p6YhaXtxhWN@uxcI z{*b71NWk9)08kE&-_gw)q%e)T1U&)lLs9Xn?%7NTRABg z=_V#AeppzCnI;H#JR!BSe`qmH9%5x2>E;KyrTl~bk9mP)Nvz&8m|)W?-rcuD?5oo~ zEX5qs5nn6x!@uT+p#5%A$Wx9kJ&0jwse7@QlwhQI$WyM#aAi!#ZSB;+U^;2mf9#)E5|tu`1pCJBdq1i zgFc7Z%C&rTQOy+@TE!G-QOou84fy=8GZf1FJ*1nQBWZ`wujZ)lkVZ)&E!>iRzsFwj z^Ll*wjTd9_{E}kJ+ACSl+WV=*G$+Kl_z&*?Xw{+|SVq&X-GXl7DitT&Lf)E22({Wp z$yWWxtdQ1^d8XS$wxN72+hmB>NGHM0mdV*V6!RzVBApTqT))8GB-`w~v;0A{DAZz{ zDAJLu;qV9hFBvCAeg-@XcPmzMb$j@jW)!O6ZLeX$T)gr|^t^IfJl#9~!&5~R~!=1<%A@9c-LtO?qUUvaYHeDt5_We{+q>`_WwFmwP z{`l9(v+4-l*ZUU=@cxhS4p2co(a!dm?Q=$#b(w~?SfV8Qn^T1r-(4e33~Ci0JnPCQn?6g z<-9+c|9AQ^(cw&CbIM<%(^{^E36Fa9`+`Av)$!o*tT|Nvc8x z;N$NUv`Ogw_yi_gZIu-0yn%ZGpJej7r}2MEu5yn!#q=3~yTRYQM#enU&$+;<9{clo2$o9^{6K! zj7(Fei9ZbTH2&vz@8s{|=jvmaSR^G~@%K;__z?k6AXm}^Liv1;M}JO_WHS}xL&ao8?)A4?;5g;Xa~ zCkJy6@@|u0|2^yQIAf$;u1=vU&%$E8`|L7n6qkr^|{?R}BNB`&_{iA>M zkN(j=`bYoh&oq4mbHhB!GQv2HvjhIPjf=ZYKgl@GF+jKu_QX02c@KZdIL4oGs7~%*F`zcG)6P?x(ht{;yonJ4%pKe6YMp_1JxYG0$uJ;S!%ke*M0d5)QDF_o37xt@M3M$^It#`%@xXB zLmVTvac`kpg@EVV#F{1}o|`A4ouK^E&4hS}x8&(L#Hg0Jgr}Q&U6=X#mfd922MC-U ze^34N*O~ffNXWlIpTGE}>pO>myd;}8i>MUkXo0+(BW7!->xVh>ce(`w&u1Ux7~t+D zU8b5NTOwJRqdG&v-enr2pL~EIU!v+g z*+D%8eMUTI9>v?Dn}WK7y(V0L2F2S#J>~2Np5MoHgnkdnG`5GeLUMuz@epm-%PrKZ zP(H%K)3ZWSrU-N6?-}Cyy7DO5G*cJ#bc$|_=@0{VyH!Z2RjoiHFUtNG$`)Rc${o~e z?M*f{PKmWyApxGx-zihAR)DufJ=-C$K!Lfhk;m7yLQ?l@9Kc@(06cXW<;ATt*8e@VEGy$gH& z?wDu|@f_~z9+GN~c$K%CtB+-bWQAdZY3vLM#;%)tj|0^WPrdWGKYk{8!I1}6OWgj$1^ZLrwSFWIyV~{pWjeew_{|F8|pKv|M zU9<`MHbd_*9(Yf6WvsY z!0Y^byJ+?N3VDtJsao9aPX1HW1PityqtssRQ`9*s!u8j83Wz8mD5!vff&vl*QGy~#a?UyDoT13EzB}4(yPf;)x$i!B zyW02u*v1c}c4^;LYppp)=)F(!6~!vqI^I6zilgK2;OCqLWr=0tqsP$>cJDu2z3^3} z{oXT*W!kwk6SI^w6Os0CSLKS}ySA~BP6ya2W-a2b;U`Yu?~JiJMwO{XIo^3b&cZ%o z9WUPU^nSU@&(oDkzP?AtKmRS++$61A0B65ZYL1qDB+f>=V2e<=qfGVMyHwK)U$YFj z2gF*#+=w?8sT8VB(zFXEm~-_)-IXgEq+@NZ5^(oG1KBO`_Ii`#9PK6%0&VxcP4wva z_nr-K&(p})n52odZV^%}pZ>W_fka*TXprR*QmJ(DOOgest*sI~LIS*B-#qudLpa=( za7(mJx?zYD&RiPcHpr?}l5C=0xbRgk7rse`Y1Oi$;|q0i49nLjR!KLgmZ_I0SE!eW zwaVA9jB^k4@lG>{xA6619pdf@b;{LJEaUDGZ8A^5y&>ARMoO`)P_0nS)2~>iQ4IHu zLN()*R3m>6I71vAzf*{7&?3nuPP>45p+!8)fT#bx-4LgI%?|#1JIkpjYmjRY>u?_j zZx^(F?49*H1iV863q(Lu$I6banwMf{CqBb{`-!Vts7zI8ca7v zqF}9cibSIFb#A}-d})B&GEuecy&dJ!yK5E7yLi(KYNf1WhMCviVI5i~9%Aj_dxX%> ze7yiW7Ve%w*3t2M_#ZvaIs5nDP^>~Du70@q#Wj43P&Y5p^4xd3_uzU4PgbYU{ipYz zvWy>KGfqu2JbAE1h;>N0^y7?3`zYJD^V#~3AK~uZ4ZiZxDq$Dz==jYN(hav>p84_D zZ=!9ud!H|7Jzb#4+BX);Vdc>w2Zk*zXL5o~J|Uw_Lm{r39lpHCjh)taR^M+|bE z&9RTc+x>l#dO@RjnS!@3-FS``Z};fmb0{uZZx!RbeJvbcLs9td;~ zbL8v%JZ+LjH~Y#(s*!kur~lf!X@)3AwbER@6DN+2|Lwd^{(pV#!dKlq+gRMaK(7LA zx!O)4x3Ep34_B2dlFb9WV{NGyQcVxAJ%dQs&V5IsoFYG5-6r^PhJEDeeX>;)GFNYk zv0LEi`2T&t9iUhR>$`l7Og+^iFp(Lj;Lq|k63y~8;w_?Wl1;)L{5^8D8pU$8vUTJu zOO%yLoI}DLN|pZ(meOwDnX-IrhW%M!kKf3bnTzwM?1ioMh00dy7TIpxP-12mv-x=a;6P2$a-e8zcG3({S-*Jp0*uMN}n4?i@nxR8j zt1w^ZpI-sU1^9Yp>N$sa`-D4q`_@QB+M!mYo#Py08OPsYp5W_UA@Ad*SXQi3D}_v) zeS~{JyoF|-x9>Rh|NkyJglXqsbwr>Cxh9wcy~lz)zIl>m1W62(3u-cqa~(L6_sM3Jpt`aI48 z`I1;G-Ruf^uHLPeNK}+#FP~!7*9+JO23gV#>BckkOO%-S{L~AZM3GLR?lbhUwp)as zE^iaCj)5|-RZO<-5bN@%@8=4%)k`RsK3)lRr=KxS@8cb1+r^uwL8AUS`d^`3A>FWp zkGDIxx8D+k6avjLyo)E;CDw|w4>h7# zE5|UwHgp0gm-u_cTLioCc6s|4ryxJT1iIaO|A(=*30660>t&FrWbKb z#;JZDsJj}ZPn@7!(kzm%v3q~zV=o`<8!v9>>kw~X0^cJ9GGpn6;Jd42xO;+KMVj6L zQ;cn*W+{5P308T!q3)ARsit(ZAFoI?emhUPW|&zgd*h9D{P%O8E@J}UJo(JP`*Z_eUA13dx9BqZ`Crf zR!pq^e}%6voH@Qsk!bn)=DTaYzN%$3^A<@rU#FR96%KI6+DbM>I7>Htx!A++6^OUn zCD<+S`X;Q9*aw)wA7!(9pKk0LF4fp7_WNXEs$tKeI?R&O*6_8GM;~venC`yT+P+$I(XnFO+Fb8JvRm*t$`gnKoptB>@c!&imp*~)sO`QE@ z3YKvMdWe&+munD>m}C;{66%CG0r?8eylfq2&^3zlbcH&(2S(VHD;_=e46;mgh*qv( zn0AOppbNB>DjTKj-ft3l1r}*?4#C+2JpJq=F0bs~zj8TF{q;Y^DBA*clO)~jB-53T z305|7Rf@H8@9j*|p5D(e(kg^qA;=SV&m_$@R-t-=me3HNh-jlWeY0>=4~8@cGiMmkrXibG&_3 zP+U=zZLr`F+#$HTJHfSamktDXcL^SXySoKg+Gu1d~lDAiu%{ga^md26OsHN`EhWCaT-F3G1=(|zfvwMxRhs` zty5u3vNw;thfUentSD@LePHwK(};X%S%-GxZgHGAiP$V0Ojz7&gZ-8#uUa)vaWWYV z$Y%;>7!uipy1Y7)Udh=A?pzl6%=v8L{}VnV7yXE4;w2{w*=sP#1 zij3$3eOhGAh-@jkp2(H=CRNtOYSGXeaW|^W zzng9$qEQmSG@qY-Aw4qn5#Na{a!m-Lzmp8CqxFjX8xU1!Q4DO@qWDbQ{rfd{CZ3t+R9S`rOs&c4iia@rD3oExBe)+A@U9pkmj{TI2Zm z-95?i*(?dQiTUIVi%3^;4=EP=CPX+g>i6h>A}0EAo=VS<^yW#K#U6@oR5OMXWa!!u zF!^g1;rK=z3@kCq*J}^-gEf~dt)15j~236bG1V5(PvaOB@=1108c8?@P@18MAuFuSb#7hWf zei?R>ybEo7i6!)+8l$pHkn8yLw*AE>2y!7Ls^1`6dp59ubbxqh5{=B=X-jkX)py!~a#u{$4PH4KVK>GFlz#2$BT_=lPjF@dFgHNNm6a&okX z^G6T&M-Lz<;`OcO+1)?oQWRHPhO7tS$n>tGkNt7mr#d%U?C$C7jPN@`qxUFM+lJ4w zUo*m$aK}4+{|fmkIidQqGU@h}Bg))_1aqt0;8LXI2C98Zt-LG`ts$qfQ2_+e^6mrg zB*((6Z_g^VA7Vh0p4T{-Adv}l>4b;tG`bYn83fm2eX*UJKz7aL>*JVWQ);5y_^K~c zhoYV1f?$yE`C5ki;?4f_espSvFD1Bt*4Z+?P@z(yBQhw@S*Fo`dt(bIOp;14rr9_r z*XlxfldW2BxtqbOmvu%)cIo)QRew$uS^7IS^{r;7YvTfstVWU3zz4pY&mh>ro=s6u zdZjDiwwDXS7g;q<4=M$JLAD?>=P3;^K?0wJ>hbSJYp8Qk{EPUm-x+Gl-LKn4HBZ9O z&HYb6cWs${QE>p_2-V~g>V@zvt@PIZ5H*WUcFUP zv?bPATgnpFe&*XJ6mKg_DAvbQ*K!M)$Zv0**=y-Zv=cSnG#3S zFD(1ww3lZmbbM1M6kq^y^~+~nr399mTJ%T99wWAiLF{hv2Xfq5^EM=;6&it2E*X8w zX|}4=Gu+3Wa(^BTGx_8xj6J3(^*yG3k_07bf=G>2(Yn}>_8&;VF3AD{i`>#&d#zT8 z3A8(i!2A2z^u&_l^n0&>DFN8IPVwRBgnpPRlHm1|!%K$4QBN-8{O%RG;T|DmLEj0= z;d-^(6ou;DEH>8}1@@CXvKQIZz6N6HRV)`z3%oSA-f=~#H@d{A?lY!D#1+54NgjcD zdIKRhgA;amv6gp7C+_iVEhSuWLev*tg?SuzI|) zR%-c><;(^zUI5!pondvfETc0*mGR_AJ}%gcdyISe<(Ot&JTFuby8^Zyy|xV=p&7B6 zK6Ox^tp!@BV?_9i!v=HjQiaCJ-VwfLB~(MIq0n!$GtZP8^9VVb1Eg@vJJY*;hodf- zM&xI2n9k{d0S!=%>N)WaM!lqN!N-2zS!S=p-bJBak&#Y;5ZErQPBhxqJw_0d42ZVfs*!?FUjopm)+FRh4A6JBzYMAYq_=9FLMF<0M;s?29w|fMr&( zZjd$m$~u^Q%`*P5%R={aM9Ml0qSnn~T7S5p7zD!B>V&f(TL*>+AT~camf}b7SRC(& zsF!1(tI?;{1nMS>bI%n?HfZeKJd1)|*1h>B*(TTrUoKbaGR;*ZpF?XRQuIRO5_PGM zEs))eUYYb$&3XlR#y+2Yx(hL%EgTsj&Xi2+4|xBh7Gc8Q&;NW`qkhXxeX99;0;{=> zc{d)gcq5D5*X*a*2y;SsNorb(GqwtsDQQ}<2AekCL-raVh;BPV>i?t?ethI{Y+lpl zf}Cl}puIBC6oYcax%y&AzjU;L|9PdAxv**X`eJn(TP6 zweH8~&B|J(}Swp)c>yJLW>2$qsRg@(!$d`b6ZikSpz!()Z%f z1Mmtl_-K^no@DF2z@gjtjtE|dp{t}k?KX%ykC?`~ji;!Oa zruW6ZwZASLkxjDra-B$>*>AWaedC@=Cmb9kq&ZHJHKJ>BUP|Df^WiSC*sM@%G(6() zGt&!N{SN&*yc~}cT70Df7bApbP#<%1|8!FyjpUkGslWpT&h-y#QSJ=&HH&nNi?nu1 z{AHEkf`IiN+aun2Fm*=`xP#dn%K?-53>_n3~W)Z?|{FwrqBi)otuOjoUJQ!p!#a=y%fe4c(~aBE;oLbM?k z#!KV@`WoV2Xm$qMz9PM2kN;z10Oxd2!Bj((^yd)XhFA%Q zIPV$vt4s`nKkM2XbKYAQ=b_5hmZw75Q<+~wWdE|_>AH)W7$Gbq4Q$_UB~4~j<2il-rp)0 z*pWg_2}T4I8lS0RPfY_~EOLk~uzZ)u+f|V`pBWA+e{kLLz2zZ%D={waqYpv1u~3w$?8NGU}&xPh^q*tWp8 z!ev*!zR#pB&G@`^KxjZquiEo8LAQ4Ty4xxuVn`0UYX0^1EPRiCn^Y6wEacSBG$ibb z=kW7w%0)4+B2|`KjRmR@kL!~{64%`=w-5;7o`rNG#Qo-rWxV_LdwB|?8#FlB=8FTK z1sV3&G_Q{#eE`V&R;p{hJps4G^yIdWpIHT>~z;vcuH51h!o zXl8@dF$RS?FmHqU`3A}SQZx-@Mxe-%{W42umSmhzqQO6*TApI=e6=z?M@nuvc!Aeq zbZW6SNb-GcW^Ce@d9zX0VKXi02Y`5ec_K&9i4x3`@%ls?}0_nUq!KV!&{!!@Y zFUNpJ4d#IjESn7)oxGfU_|HM|Z4!+(&nTc5hXtgxUU=$HLmV1+YSD^`VAWMDHb9@z z^cuX&wy?pUFmiNtR#iqg97G`N8U9nRK!gsX`QjGBks5d1q8|StVm=_{X1l`?`k;84 z$EnaZNkKj8dL05E>?sD{&%Isdue_F(jAIWFt4GC>9-X2(nLvY2!(Fz3>pXG|va4T* zH`WGF-Aavqxqk{fSwMfv74eFzp?SAk&SnuUb7ze2G{8ZH&t6dWcupwd}fIWNf5=?Bc|&fo?qeoTBHA>ZT9iXpt}+# zYr5u`UXPAXsUd*wUEgc4cmYNpQnGD9rWCo;6J07@%8Spw&Cjz6t#Y+$BZ?KtW+b;B zTasCtrLQy`VvFp@)(qOV7+Ul+y1t?#9Np3aeU*tl;vcsuDi(?RP>-2JEkhmD3WVOD77A%BbiC|tJ}{i zt#ZRp#1oE7M%`bPA)b3x2Et{-&dKia9!qTO;5zy1J1EeZ$kaoNY?4v6%-*B-F zNR24Qsi{M@#u^C7!X>-fh2{|B6kXYVpxxOS^U zixZuZeH-j@v(sb-<1u6*B9(W@r8#S_9;^Pyl0s{f^l!0&Ed0RX!FQRq0=Wb`jc)TK zC05>5@==P_ojsfxq^_1oXWKZm`_(=fO6e7&w!!6w=-1cPL24bSJKq$RQRqPb>yT1# z?r!cInz~2W2_uJ0dM`Y@-v+Lt#>JNIe!JGudt3{*C>4z+BtqwY&3*EOU zy8bpzYmQj^x;UO(6F7z(nq`_$VJy^H0v@GnYx5v|mk8TI(p924-45Wz5?VBHve7qs?Q>&y(gvkRIs z3$8q>)>|<-MA0w!L{R5KqQ~F z2ukqE7G-bTU%cTu@`h>G#S0*7pNMfoj8|~7mz!<@;p`K17a+**>#|$c5gDI9*sDjS z^4~Oz_Q?*A@&TG0T2%oilfG{Br65e>*M)8i2{Qg_|bDzm~tmEF7bD>zJGpbkjv03v$Ksm!neuC z&2mOYdFGkr%M@O>`W&;P#!V)An=G_J=!LD;Riu7A86B(57Zw`>tTc{?CCmueKnJqI zdQHtz%xq0J{p#t!Jr0#*Rv9o2H}#82@!6h4-4sc28m4c+PHYsM)*Q>ELToWVj{l?E z?wwAHp2Qd;NL=_&F(yX28Ob-h=kn77<^o5ubEtKjUWQk<(G6~;#PMrH)8*dzE~3Y$ zxlAie2fVb8D0SC{dbe`3U1s8e5PgmZraea~}H?qpf#;KvSh2)T`ha&f)0E@H!0pql0}?MG=t?oH=1eksOaI%gZx6zzvC8 z&i)G!R4Z*Ar&*%M$UDS0=I;7V6-neExvD$-jr#xt)Awm27U=-jDdomD8`mixa1us0 zV)0ahuQ1;SOgAQMp9(UJQAG#kZh9cU`Nwz`>Tkcb;lFYJ6Pymn-6y4+r_f!R6r2Ki z{Pa73z*|`b=eRr*vn(8aw#jk!D70l!^#^B?{0UW<4)f#7gLN@}ZL)$MA4F$5e*^=R z6R9SBlPDkivX64UAvD%pLA#|uU1T}6y9T=lDt3)m6z(}-LV4iTdmbQ-(&YH(_%Gi% zJ<2VG2rS9{)v819B?vJmtrz`mwu9Ek^4yGHGOA6LabT@E7Ap8NphXJdsLv7I5%qU7 zqB{vKSf=3G1FfzE-*}30;rXsnO0Dg;5^;cXYMutA<@ux2zO|}s+Dk;s;3^?R;~~Z6 z_(Oe?Vz&89ENq3N_R%l6QwpV+9hPcm?fJZgr zkfl$rjW5#{r1HeRXwbDcA8 z@+ylA-lAB?pz_$k#*yTZ| zmK|Ndfbc4bMs&eL`p4$eezC3$+M`Qyye$9jACx%DQ~>NmyF#EuQ_v%FiCiB`$CEkz z9oIU{=wYJ^+H96YpwUscgmj3cu=n|1sh$??+6d9qXV$x@9d4jLIxFO zw$@+z)N2oMp)AS_s>#IoKPpe&1Sg-b6Zr=9s4L=At+R?Fn?fJ>dOOq+T;sgk28bE= zwMA>ADpEVUNKd$?Ft@98CA*;&&uu}4d$}Jg%-e(?=SEdoVi5cGC}GTEJxJm6N=tZi za!bryYl~mffReLmK^AWfdsrqb`1q~kmtCb~gWgG1>OAs4)P2T1Cb(4~i?kq>&dno% zxf&~RDYzpR1_dp~cqhh>xL}fAx_&`d;2fq->i{Xj9NRf5+DX0SD=w9(gq&FK&2c+0j}to;aa@6S>K*)L94x@D`u zv>w48H#wVEdk;6khL5v*6iUPNj`X7oiIyL}5ylx_;uVfDJevagJ!1NQuns{JSgs9= zH!-S63$pWsCr;$Fov(@)C-!{6H`#Y}6Paq+`PP1~9Ir(HO8u4tR zL4~ATRy&NK%RGItcBlZ0;AJYM+VK%|z&AlqqWQ;NF^ycrA%^=!P~l!_21JoKAlaX0 zhH(la=Iz{6V-O@Xs)hH5Oen&2j60h1KM_15`g|#bid1IMC)~?nRB4<+ z_yfI~_l%0~t=;R6Yin9cFsgRT)5X=dx{t&+(7saQUy~+Bf0bK;CdU}HXZcPKqB}ca z=N#q=*myCBNG0D2bMI$c*iSM@M0KVgl7~cL2m}1e71V+r{ly9%3_l}7N)nJQ*&y3m zs17jisCson*^)N%55Elqy_i7dC{jOOIlVb zYz^g?N-00cs!ASM;r%OL|2;zp4a~a!uqybM$LFOI)AwC%V&+%NQYpc+kIA`1=Lzl~ zjekt12b>Ch0-Z#@NBj=C8k8SX*n4N0T8P90ZuJJiVd;BJ-Q8y8qEo(YvURrUmSlyx zMFvj9AHsdj{_ejRDXNN)XyRd6R9&DaY zNjl!CDTzd$?nunu$EW0G|7O>L17-F{`Q(&{Rk)mQmLax=oexhgWYx~-KWP)pC|aQd zDbYXB&R+tf%k+{d2r-VS)nnZdT`$5tk7?x+#x`1Y}-vq?$LneHVAsImurFTZl1MkUAhdA z56I7IK%QUPN~r2?gHlI04c)uX)flV7{OWUt*?B`V`;W~fn`(5|-Z8q<>XcmTSGdiy zz$iB5o<^v1y0z#uO}rnP%H6B@vT$9}R$-_b_(l-YLY4#@R95lc1?B4Cnjz%@ae-cvb&~xTEA46( zdUz$a*%HTaOQQWT%*iNq+rp8Kk7zZcK&Z_hl{(>hEX2FS`w11yn&S%%vKjeDC!!!u z{amYmg5N`ZqaKoxPgbFuzAwdc5)X9w^1TfZ|JD=&F&v=&t8vJAO|H3nEphV=bZ;9& z5Zs%ez4>vDUN?1^RB?Qm{VG+JvPx!nzEkul|li_#(UJq5~0EkCMp&QzQHMK&A2FZPL24-pDEArbX2kmmF z5Wmcyj%P2~KGV0ZtN{f^d;qx5$~`7H`<|{1&>IO#y^h~=ej1=#d*7sRtEs#rd3<`4 zX+|@su{?~Y`z!KYM6wmm5Guy_on)9k!L3~C66!B)Y$3Rdi1=Wc+@LDXygss2$L*C? zIUt8+LbFdF-oqg?Pt%qR{sUweM4?0_UrZbUU1Il31|1ws+vu_ZZ5Xt8bD19xVR-B@ zIX7KUyzx1v%+B5*H@V*Ohxt6ibfMHcKHj)1{o6F^c|^O%3DpbHPY?T+vpxKHcOT1X zMFYQlRlRdXl}Tj2+U4OT)d~l|r#jpIcYm9r{S`B`!{hd;!RMNplmr6l<2t3kl3CEC zk-Y+ao-S9*fGe+387itoW?yH92!-D%F1GuYsPRwj(?;1Rgul+N(=AYljA{LWt3=6c zRZeA2;ED_p@Ol*t{YrF!nPe#<0D*7r`9cKX+Tq$Gc=}eNZIj&;TZ1jJUZLY|607=M z$wH}s7!Ks?1$u*Pp@^)mNPOYF;AnHwOX6brbnhG7K>IAezUsn4n1NJ3sxhaO7-R3? zXWJNyI3s)XfP^7@n}!g(N~hNs2P+zM5SeHYT5Ya!v=9igKagIUJQ9>Df1FY)CUV~E ze$Ey*wx>R=`~iqBDchPp*_RP)4I?87NI>KYaj-wO0DhQ0<bwfsS z5ik2I$f|v#no#fS6+>3H*FF9<0m#AO>0$4}$n&+NWF`xLE0PncRarJXUBG4F0e#k3 zb+8Zo{5YLveeAnHsGnG8zE+0S@s}!%mtFTNV#N)yImXptF1c>;rswB))iBoq{Ido0 zZ#m?o#`fDtJA1r+z7G%!yqP?pP<-4B9N5u+OC%YYlua=6iIXtPUOi{rlSC^3OfJUmXHb-C`!%|7d@M{(ay zV7XrztNFY7wq_(LRG88NWO@HC%}jslh%_U1Zu`a(c0%GC@7|;~%k!s3YBhpKYIR3M zg&xlep7yU{r=d{VBsiH2QYL;Gi1{R3P`IZ}?~c$B3Sl?C7?S|2`?n+nW!g-W>J;|2)-AH&>eGn-%4UA!xPg*9YbB?leI%&5- zdy8y8j%-ot!{@{o*u}M!B`I+4UWnJ|{ZX$w<$D1}b;aiTDK?3Bx&^w2I+yHRC7RPi zZHA?@KhB~xxaOU;g6El}Dj$~Uv)^O2TjAvwAaqRUI@Qx*qC_rO?+DEIoMQ{(f~(J^ z>GNY&IQ^24svHGu&h!k+wv;Hc5%>Yyz?b6mT}UDn%0TeU6CA#6b$pA| zjXtAoadx#!VCvT`S!YniHd!0)bJrvzn~%#U?cat#+(!5!5BVc9X`gPS1>$RTsF+nZ zeL=S=;}y!OwCO)pHyAzx=6Qi&A!gv*2=dh2RdpcNS7p&fa@US;aH-}dL}w(97lxG= zT){4q?Kfwc-Q9RSzJdX+zSk(2HgII2ZkTB|NFFm&vy(x;C0h4t_|X)@#Na=1Qe5Zl zotY89Z-u*I_OV?1h>`1#Br%ws$u8*(YmQ@A^h!Xe%=#fp2}XhN%V@JO>zDb(*23?2 zJ)R*{I>l)?ma(-1rnpm*aCrM3ON2!bBBY`IprKJ$i%XOqr4si80>OT{28E$Zj93AF z34gfcs`lR|-@%C&T!%T)jCEc4e{l&RrCqTU;@8WD^}(qrL8%xr z(M6t4lk}L76PSMV^~(_osO<`S9LUNgKRZD=qf9Ex6NtX#bgF!WknH@OVAKERIbPBw z(X=p05+d2E=ohqre+K=q@jZH1vz}&Dt%>B_pH%0C39FRA@iCDpgf86CLo)+hMW1A(zqQFx8c zG_t^M8)BX#(>^Q`B&o`(!Wvbp&V2i5OcEr+*ZK*9JiNo9_VDoB}YqWMuDZD z+w=zG>8kogHsMYS_iEx&%T6sAwVY7Zm;oGJ-E#FJ{b&{hjlU!=QLjATWoZLq7I{)^ z9J8pWh6TE1?^XqYTPTG_B6s_4n2#8IPu_9J7NUcD4@xtp(tKp$0s6(QkrrfF4%yaY zBLCWJUWnXYX>;ZRtwd87VZt99-Ru;Y2D(y zlLXqo5Ejc1)93hqkRB5RBiCwBUSyeKVY+3VfuAw>QhZyH)WvGVW}Cx5;zVCw4Bl^- zN|)%uylU;3W)DBtiFvd;#g%^7PToc9w#}A7aNSY82!|e%~)qym%J# z-QLmsJDcnwCrhIX=Y6MNqGFHosRfzE#|BM?$s)5O$Sz8Fv)Wp>VKB6&@<+Q@cem#6 z0Bu!i0+yOzJOR1qxO|xdTvj>n=bLR;c>z-#Dt}mJa`Ht%cl}FjEdnc&3WZVPRb&<# z<1qtZZALidX=!>0czObwgngOLH|pn>?d}(#S)kJo?~tiQwFnd|4KD@O+9aHO(y!F4 z#%=t>hKPBtR*7jP8Ur0?=9>Z4{;~3ks1;;*N(}+xM}7wP_&;u4wZ0H~#Ck!$Ryj9a zRfj@mc2JxR-<@{{lVgJn-}rPt3%|dvz^!_Abay8y%%XMrdF0?(laPqcMAm3mFOn1D zH-m(nn}`OTn;h(0LqRrSy#j~C-vm8w6n=WN{TAbW2J29_hK($X-shSIVJRC7z_$iQ zb4|`rpv{e${qEVwip8YcZ@H^?qdH^U&yx5+zY-Sg1#mMjwthSUNfTHdiireeRG3`Q zygs8k$@8{`4RjKBN~_4Wu#M0?&A4G!O4NwOe#!CgczR?i?q7#6^@s=QQ}ZIP@z6gp{46XKl#Xb| zaJawO^a&H|2;-Fxtk?mM0o(4qGIr)`#8@3Ye!HicG{!;!h02>}cl0ohx08mwv?zM!!oc81ZQmRMUH0my*G@X5EFA;K9PWRI$N+EvNCRQm7m z6owu55Wa5V-oU-njG{jO2{9EtAl z`i^*LAIPuw+bn-dvmVu?QX;c8AYl4H*}|pwN3hEudG?|6{v}84yM2y@2LAN0A{*ta zmR}x73*-A)8$*oq0^o~>$#2yG9@yZma1)#ZwXk?e&Q|)KR>*`zz)}aiJ4V*)*UkR5 zBa-WPK-er(wq>ThQOF$~ktarJ+QT)vqr}toqQajaB!w|CH7b)L&ft@iT(#&-N$S%c zfZ@me)fNApM3L|!uIC@oshKG+xX0^o&$wzt_YGfEAp)v$u}s^Cv60N0aK1A$QlYZM z2LyhBZck)7&)zc<&g!a>Xm^YY=xe1^+xBi-R384%|zV}2z+0P_=^dJ{T?M;q@2XmjX0(O<(BSdd# zKmN-LAK*Oz&%2-VKYW>y|C3en|EMoB1|$&5|5h-}{}RmV^M9B?U(5vv&3SzqaUy9G z?};NTHOR(R`|Fx-$8)>aCsjO}pjFw;LJl4EL zBA*50_aOa&*2a%mpZlu~iH(;tkhjR=vIqFQ>*6gvi&z|iJmkxN&)4frtG|$RSc}UJ z(F^&*^`EO)Ih>$f3&p(;>Ke3QO55!2U|QC>Ip47hlm1T56p^%U5R&y_40I}gK$5*I zU((J+>b@GAPrm%#)FKx1z9L__PF%xA5>Cm^_jF+R!M(`0@(S=$ZDLUw_3w1Tw zXskNniBmntQiU;>g$fxtd#Ujpz}TdWP+32FMXa`T!kL0%iE2p=%W?{06^V~KpZ22! zDlxcu)>84sXfV@yOinTm>{%a2&~QE&FXY=~u4?mOEyw>DtDtIR#FTjBxET3yx59*_ zN>$o>aQis;Gj^@#QXb<=hP}W95$N76yLfnx95ujRtl*T5(ody9!Qn)rp3Ubi=gthf zqu!$2A}u4hwCAI9r0kD}6IHlg-}bEYg@UL(u=J^_lXj~(j>L(H;_FEVSvvizhaH^P zr9dpKM)&v4EJZcb@} zRTz4x?<_6me>? zv_6J+UGblbwt%k{n{Fex{RCUS0%exTk{?4|n!B1l33nTu_*8v|LZv1Lc%p5}W}#QirsdZYkD}c6npk+?Z%*V{Bh_8APknYcbPUfP?yT>O- zYU6e>KGcx$#U8UiAAgMjpyN9D!|s7rG=Q1|H3F0>2L<<^w*LR~qez?*jxL=~WeqiQ z1b0AB#*|;hD;%Y64)(XlW_#gM6R6_#n5j}Nz*e`MO~Tei(^P2k{GAU^lHsb;c*2My zJ!EqzE$Jyy@UMcHZNe5r{IU<|--Ihq!MV&U8`Q{KKr9>6X|0E_i^Ith3J~DVypShS zT0C(j`=M#k?P?lU*V1de{G*2-i^$;`-%kKtG**Ndn=FpbDElP&WI?jlG79m>HAM`r zfJ0~BgYw3j^{wJUGX)h-Xc-R^tpx+7irN!llN2%PZ;#d&r?>ern9^ZQZ`ZP944JzP zBL;dvbH??_^ig8y??ex6e1-ZJCyKKw0Ld@JhU!eg#TvW$l6MNGVP3DTw$|<1w1HW` z5Lt_Ir4!TanF#4>Rm%xsHY?TK%N~QDfIKUD4wu!%;@kd3lm|+V_962)*<-Fy>y32D z(weeb8Vg+Y(m>%V>XE2L2_K&Sv0rLkwLVb6k^?8cJc4_WFj4EmKT^8Fd%*&$K}l+m zP(A*2<~%~GOWH0Yn5L>e-0Lo3%gqNxfD4`*eyK68+^(F-L6>U`FgOng_M?vkS*JKS z*Chru0tJQ2jSWMqc8k8rP|<$9DOQuM)Yys9t;1@%JzqMUG)g~}aO#^#x{6JV!}mR^c@Tbn$PjZVsQmi{(c0E zNZ6GVE4cdLims+t^Lh2jl*hHC_cbu0D>{yY4;7aakC+m}^7Bz*eE6BCs zC6E9R$y3qh%%j-+HV>&Okw2b$7?l+G8|BhkD9E^Mq1Nh2{U4uBxT>rTepWjTRU>^bfLMyQ>~ z5!gj26|u9I2dtW@8nB{Z-{>Kc*w^>osuFpcrv5VZE#hSJ4ulw$`L4!7vhz=djsuIZ z3!~1MUA(^E(fOzLD%9f3o`n3JP|m&q8#4xpy}C%=YN7EIF5S6Bm(j3kHs4adx>ecM zYQ@KvOl%@&ryLa)ORx)@!@_ckG{(QSypA;rN-0@ZYEa^+_yqu0J;YS=LpHrNriTu6 zXYK#|9^u<86XO#f?8d)D#pOTem+G5YUnEB8;6NXXi{Upkd9qqGue4T%Gw39^EIrwE zO6~qy1f54LaX*(Y*P|HzL2GC^8MmZ?qc?3txKbFt4lWp?X&@2f=!FBL7b ztavQ6YH2qODFac<&&%ST-3*$+;{@y@{YAZxlV0I0WI35+gk)K4e=uYB>w8HaIll8(&1UUz5Xdu*0o7VVE#S>)4(v*KiZdNrA0gSTRf@K*7n5dBPLv%1WMaT|9qC$H$5 zpSF@?fBLo`ujS;T<{A91g!F#WFpUFFO>j5hJ0=U-H*f}9*PCLNy{fqhJ4K} zuH=WDe8zRzt5-vwjmlmhgZ6Wt!%8#;gt23#yq0bR>y(#Jgt41q?=|nfg|~*c7xGb= zr%En{J_`ds09h5>PfDl&*#}hqi=2jHr|zT7I+(;ToU`Vb@y_@D?ldNpNN#JEjWYw4 z{k(U&%ObCfcVM6}PR54sX^}>Yxr#~n)WN_w5bMbQT--6p<`O)~TgAIW$US|TY(!KC z9Gt?~0-DGmYKYtrLVgKv^wU)#qPHD3l6G*8cb4>e8{cP@%N-OP6 z_-jtt`-+d*<&+AccQeh9vhT34%!_J7wna)ny+XHkiBh_%OZXH>DU4a2kr?@9-Xjt= z$rin>bm-AahUmDX;_%SHDk-4fm0;a+rA3yCKpM>?>ee&H+KYF`IXo7|K0q@(^V19@VMW)mOSyx#?26g zFF@$xk9muO_4+8bXf)}A5hqVD7HQ%R^UH6hbtj8GnEIJ^Uw1f~v##Z^aMG2~n2UD! zyT^^~+3EmwE8RK^*NZ23SnLXYiymf2_i4n)3vI)9Engargn?({4zq)GU#x1cDv#l1 z1}JJS5sKB*#ibV3&x#7qMWRMW+2na#GpPE|iJQ!~aZrt5jXEwn6sQ!H$ked;K} zMWL)|SYyBZmvrzy+GU~tZw5pAFTuuH|8Js$xOZr7tPP`6Z){|TUtX%oV-!iAd?^y7 zO0t(c!7L_9y1cvuoY;TaJeqg{F5i7L*4Tv2a!&Z_oNZQIy5+8XL7-E~6AOffL&E-V zeE0~EYDW#kK5h+NV*KoLf<03mb=?bkI>9fMuq_rCmI|_qqU`HKMH-Q;;2JulkoXA< zhb8`g&Qu7ipMFSi%x|9hN37@6ArLB;m7rv<68z;pz?^87)dx<;a3IgSP z&Du+$4+1rfiQT}%K8Ljrx*_q&!6PJip3OM3^`b+Za zQRTUL%MQX5Q<+t_S-@kNp4SRmCe=P;d6VtH7OS;}S!P`fRKLW0`B+oFixK%;<%aLy zr{=BSM#A7dLhivW)@y~UNV0)bj1SVO$S^_44e^y``Vuj+<9i0F683+>D!vGVl!|-k zV|Jy#q;@k4)-1Sej+Q;&gw-6;U)vDfM-T0HW?r-is@Xw`7ruv~W;DrqQ#X_oPCR+X zMQerYqMPX@9n$+}hi7_4UoM=YqpyWJ_DJm#DOP=M;9nk*?1Bc^ETYcL+MF-KuiS6Q zb6Q8nn#6{B)Pj%INYC~rK{MJ{0{Y)^0JwD&D5g%irhbtTN@rAZa@ zLu10w`y(eMA&j}uJ5akFVF9wt^D)<*g3Ik(W?dvy-ZXf=hJSW@k!@9FA(0wPAbpA%SwO<1N~^-9hQ z<-BzLT~ezZgJMlvJl&cxuFBPJf&8Ok{uh(eUzR#sbW&fuQ?G|UcPtz1J?2l=7vXgW z=6}?qa#WT6DG=s~u&@*XU%>uU?aY?OdFq_c^*%XFO>OlL)CmuuH~sx$j%nLknnfwm z73-8`vSgWt=kC($mTz9n+F2iE%I1WSPO*$UeM^UEChI?X2IMCa^8jS-0Y z)7vv)&(6!wPyI?sD;^ea$5PJOt6$-}5#O+jKrp@w4BOIqO5*j!MmfHPk}{dtH`T^5 z-$mbwY+b@bOh9k8lmCF9=WLTt;RNKguKYXc_X+Y1RV#s}dCRcBAtLT2Iun}X!ImjK7Ez&U~T}B|6rJ* z3owg5X?3Y~upBG)Ao>P7n*$VUq1z3%?>3Gx1{940|HoXi0>o}gSMc%93x|B{+1)C*kR~{IM~8f#=p~6TnSM=g1j}ka zhuLUoW-R{l-mjfj{I^Lh*HZZHeWUgB&r>j5$vnDM^L$0oc=M?4Vv)WMUQB#~W@iI8 zVagT&Q73F!TjVA74)#?ZGRRB6@JGu(ijm{}s^t-qtiC#i?{ojIx=mkn*Rfw$Ly2@8YW;F-k#1OmXANHtnvMBal``r&-i(;N zOI>3~Q87>aV?Tq~q%a!|K}dXsHlUkiZ#T`;(E0bp7ll?}`3p#*%OqT~P)OxQxrs{H zE_wHgZrEZiwf{l*Z?Jcng)ZdpBWc>4Lup&-7gdxu3a;EQZtImQ=TeVDh!7V+1po}8 z#ANHy#hg9^7wy>hfvIm|L*QwbshbW9TzWYzqNHEwvw*~NdR%&37-(o1o~=Cfiv(-U zg>uo&CONa7o^R>K4^QZi6q_3q@b*tuWDXkNljGi1d0W0+Lnq%-4L@O$58=ApMWtEi zx{23Z?_9Q+_m)oE3-qA<-2|Bu-J-AN<6N#t!83e_!wgG3{Vg|h7OrE6 zkJ$Q{;`IC+UsaRR)i=c@*8YcQ`xvFg9X!TQW*;Egzwv)qJFB3$+NethcL);P0>Rzg zHArxG2=4Cg5Zs;M?!hHU;}YE6-L>iN;hVXcn#-xbPj&UV>Z(4c`n>Pnd#&}v`ogcg z9uvV5ToUrPNo>s!*lbeEIUih;k?y?vr%uuDx(AfVG^grs3cHsDWE-?sn}q=|fQ}kX zDo>Qeq5v}JT~fNa_%_%00RcIVVk3S)L}1Hnt76%mz!KCcX*$71iB+26Z=oTYEuldQ z-hWf&1}1q>%wVX3RNXm|16$xL!2w~ZQITK~zn>x}Ax`dRaP7%wMU*~tj zCTHlksaPABKpmc*zqISQroO2H=R#Ng6tz<9Zp7^`66E^Db(j%+G`#kzBke?~qiuP6 zeHzI%5#E^KFDH{6U*AzY)#__BdL^&1LPI}a@eTXI**!xAuK=pK-`P7MmSpvFqAhI+ zc=lvR;FnJc`oFuxC)?|8kGBWe3{$a>#=f1Sss4gca~;O0WJ_`!ktzrFd*)>HeX)hG zbIQZLw#f5__b}O|73u32m2c>Wy!jYWf*ZsIs+AeNs-M=sHj1Bg`%YE$Vw@~#=AfI0s)e(eL`VBGYJT(Mp7 z7oY2EM88P+3)rST$2!mbM?u$rNJuxpHEO_va@Z(Q7W=IDkE7^YU+IR~yhXkI$&#`4J`&cxo93hZ_DSZok zmW08+-M#xMH_lnv>r(?73J(98R7rNqB-=Ey5ey(w6#lhh+3AO2MrQdNoM`z1!+EL# zdvZI3z^(|s1F6oaWb+}~~7 z-$8kIenKv#E%F9cU$2~$G{y~F_DD+Buhq^EDg3;K1FaYq_j0}Y-onD)7U@5w1yXE< zN9JN`|12Tc9?UvYxY;rA^-r%~nsAEU{yW9BNnNRtYw3{6HWt&!K2taQ4d^Q=C*Y4V zg1Ul;bCO}FRfqPdTwkNUP4$G>BW{+5d6r|6W;-`EvmEDSpPXajZ!jR7WyU*blQ+tV z0im5!t47_x-oYzo= z{WC`)J}Hvue2xt5;u0`=Fb|fPRuQ683QFS@g||XY=4KMk2MEuXR)`nbZ$4 z00FiH7L^n`!j?-4@YmQj3L{%Q;XOo8I;~s^=tVHZLKJO@p!yqc)CY|&&q%aDIf;AL zu&U#)Xj!Ae1gXjsP}92e&JD2KTu3ahxp)LmKji%`QbG79(@xUZG`aohWDJeIUwHiFEXX_ zCC^yNR)Lu!M{*^Zr2u7~sqxn0^y*j62~?NyMmJeT|Nh=YJMh=ahYp#SPmbk@zT(LQ zgMwFC1p-dD%VWzGD}`a9?UB<>e}4cA{Fzia>6PoRlRmb2oV?WE_%{Yo1K@lKEC+-Z z>H5WTDYdL8)q-vMX7Jj0v+8aVbdK=wRTVvFUVIW75tU|;z5z*-Q0IS{HVK#Lkq?w- z8+~Q`M^uUwpIz!kpE~i6Uj^tm_^5bp1;sw@%7#UAwIQ! z_bG_>2WPxg3%pyWXs114X6xGj<_1J7ZcK#+BxQ(*zChf9jD80PLZHuOrvcpVrrzFnVHo0dMbXcUU+xIx_vfpH%^Opzk3yF(lHkte*tu0_xe|rdd{(SvFJ7iKi6ODG~ed;Fp<^Y$G9zjKL~hW zUO6NEcqunyOk9_W-*yp7{$6M^-c^e1P8toert- z>ljq7lx{52ig$snW;h^qNYC4eX(7V-h?rigO)=BeDRBd(TLuL%8*(uU&ZL{{5o|Dz zv!Z+^#oEQ)^+z}+RC@}sH>%TUiK~|=@0NcsuQSNi8OGQ873wHiULrXN-=WoQZ4)-} z)uEkozQF}yj!XGcsfE9v;2;p_8jg|i}>JeqP>m)T_;ay}P&i4WYaMO=$m zqaT2sW46`}^r>FDb`)_@wPW~^V_ms$ZJTDU`0w_VfKTXrzf|Ydi+i{xkA#zQUxSfs zccim)>Fn9@N5=52l36do)t1kzJ^TW8=`ha+SX%U!ik}AVZtEfT&6}mEz)X(IHqGTn znT|W+kWNx=NsnuM)Z@*o9g$^Tl#3@6%e)zpM0ZlD`;X(#NH_(aqwF2u9YT{`KK2RL zhUKCnZ7KmdHDY4TZrO@u0OtIUP|!6#xk`uBu7gJ=_N`eyYC9_YLwI^{c;~&HH-D*P zUU9iKHZjfWP*=vvqZ-nW*N8IhwIOcnx1nmo)G9A2nRRQhrd_S(@Vk6-r(&x#^v9h! z|Hd)I$6$2yl2#0X_fH<<9;5oULODG4qSYW%@<*veiFhpDDMx&eSgEDQgKgWXXO7Ef z7DeapG@0H3Y&pJXFD8rpQv*HMT#Zo3^em2#wI%g$9@$2+4!jLe;eE?QEyWl56Rq^q zeuq?qt`mGq5>?U5K(2AAE+U+_Fw)(e16rQev2XlyiWrDlW=ZjUOa$KiRQr#RF5 zFE)p1zP4IAg-BLgg-HjO7;H^h#v1I)fg5Jv-5Yd5B{;FFflBm1$;b~SeI?$ z{(6N4;@HA>#HLcfP%>W4=7Q+$Lnz%+ZlClxBSacoS8(5Z8tSSvQZC203k_PEM)>EM zK7~cXdK(%?VUQ*hg5HYdcIJBGc|w< zDDRs2YN`ECxNxset~5ofPS46o{3nQO*c_#K5AAGm-LH*&c1d&_vtJ35GUS0WGE80p z(dik#QPb+#4c;T7?-596j<9iavsy2$nqL)+6;!E_To0uVp%nT|?D}}GNPu&W$E;l1 z>kfMQx9F;KX>u~sRjs8tphqs)`mKVI!p9Q^{CcO3I@P%&FVQnyVP^kbKI)EXf6U93jQ|! ziAkx+EmoM{zbIHH-qWM;iO4LQ;JN$N4Gi`l=iH`EaF1{e@x*cT47W)BtuxL?x@Vo^ z6kS(AqW+YfP>Zoqv&1wML_sezQvBeRY{mSENmKlm2@d+&%H7T#-Zx4Pb!X zJ2xf3I@T{%za5XZ*N^g=bw+kKhhPZ>wWACjY2pAo_peg^*K_rvO-pTF8UpHFhi#D| zek=9Na?=8vFY>LHg!?2PV*)^iL)wY4exVN4+J5F=KCwQWGwiEFLhQ4T;~M8I#RmIq zpX`7*@`rPLtj9fitUJ;(JM+!2C{JjBQE}OZRq8c%jN5F*N=cys--u+dM!la7cw&d; z6nNoXrhAB)-(@Mbb(w6Y&sm){9EI^LJ68*fAbN`l)~KSrocNp=Kze_bxosme+4 zC%j0jC%Syt1)e9P$=xp)*SpQLdS<1|c=ZPy(^j@-9G<0p&EL19N>@%B+yJ4g@SrBe*!A(OGW4%pr+uXc$$|7yE`P5w!>IxQsEo)Eag6yr|)5yR<~u<$L?*DsuU zRe1Co9|ouIV}3k?97mc&?l|$Y%6;rf^YnSO5naX$Dxl--L7s;9yCyE(ULFGMac1|R zjMq{$UxbBqEUGR*^j6A8+k$F+wakPv$Mu~U`w;$FyCT6X#N-w+!6(ic>N(RQR z-XXqlKb4+EX6{Z&j-j!3NjIHef&VWCR;OoF+JKNtm_5F-DV`?#xxVk3rP;5YYf?$f z+Lpx|X=lEY5Ap@j2(Mp1_jH?Wd|AWTu3T!IzH_JH1$TdnVPO?*qTE2?m|&dm{`=_z zn2}|QeJyJoQD=5p^qQJhg#hYqKw(kmWle?K+vfjE}dM*FM5o9e2k=JCxqNhN%XIPLQ`mxM8^L3x_APy=(UU0t%3oms@x3~1%q$x@3SmKqC_#y)v^9_c#w8DIGUT!h`YxDMg zZZ}ZO>E^!Hu35$^9aGtFEloM$qo@%Kk3dFS$+0Khjca;Aa7BfDZJ1u6uFzC+LVRYQ z>H{|Z)vhteBYPS9>X9(Y>zYbL8<6-ch<)W;5^MI$oP9?2$#?C`*&h2O7F;ecap+7@gxj>@bvWS@VlF*eU!k$#@7 z)3!)*TrC3#bjUPLXC8CYeuoHmh1NzCZN7&N^!%-bD7wHRBr%)Uua!i3Vv

%5(%0 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

JPa+o4;y1;494sS8HXQO2Q~VVr0b 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

aL94}%;mj|lnC&q&3pv8g!KXs~t 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

y* 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

3auTu&QapR|R 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 ^!2zB!Ewf_qJQ!4liV7Ksf z8)f_wAz5vdJixk!@8iCMC0P|}yFw8E33u~Lr0c^xRk1qj$Thrd?LKxd57BzFm}DdE zj9$(+@5nC>;b^M`X(_i5` zhVA0gPbFAR(+Rc@a=d{KvFqgkd7NOcmI*Yo0q%aD&0+!_F!z8)C((M>2fL^!JAmg4 zV0rZM5o@lKiT&*9C;k(#$p8)?ibc#r#)ZLNEfZb zO%geJxVv^y1zIL4cd!eT0P7u4_jHWj!+VISlb2=S6q;d_WcCEfI#MlPFFi$1H~ruE zo_<5@GIbS7fW38vFhy?{^#V?|e1azO>tp&QBH>1zj9yNYgk4mf4C*QM9P?PRsZ;~a z>=gppvQ~jo#Sz8}xJuax8ueVEChJJ#7mTArOpT&sQ?-&98=*FT589bU3P3YSJ0Eu! zsL1+ne6nRP-!R8D;#aUA7Hh;x74uYODkx{I!ur{}xY_#85Into+yz=cEEXxG>)itJ zcHpnG44xq*8^xM|`0nO=>3Sdrhj_X9o@Er~o@ySb-FbJ5zfC(sw2p8E_yN>&NEc+w zNEd(D$$vEh=%!!5uMj8~sONt3SbtmZd3&HAVDC5v0UMfgfWH�MLhncqZ6lA7Y$9 zJE59?17(~5b{dXBhDof0Yj}pq4gtyqyqzrqUoX%%-ku%2dzb-Ei03AWOhc}IgDi&0 zXj{FU|3v2L9ptc%V;ioK;}{Hc40AM2JHQHY@&2Y*iFI&*^?vh*MXBl@jzQKU1@r^K z)(9)?9f0#OeS#6-w&U+yCxX4(#@EX^L*eT8@xeMMQ?dAAl!3kfesh9xik^547&#|s z#%U4uzeGI!{(JvtobdHRJ#CU`7W49@n{JRoJ0aXyCbN$yRxi|~n^rIG=Bt%`fMy>8 ze*vm$b#r@pxcegPKXh>n;_miyA)m+C5Nu%`EKtJS-@a>-;OqAAZ;;B>)z27>2v+5;Dn85YsunsVe=%%3_ z$(Dhb0n!EgkU$4_A5d4oIzqAv_!Y?Kv@>`+G_yz-fOP>_pV<5O+ejB)zG=o8MnJw9 z^7$KRhrkbu3C5tW>cx>?u=k-KqHWQS{~g;l+A*wB5r|Wvo|-4Z-ON)tgx|o8vMiCi z2LQjtTLJI!1Ub$`yrx)5vDhwHFMSQq)jvnATG}Mx9sv5*EY>IqR6Wbplq-Y1*2+FZ zXcqc;BA-7&lB@zXOj!oaV%PA{4^ehg^z&4Au>ZO560gDCq<;F8Y9Dcqyo<}*BiXn{ z`~)fTE6NUMkGCgJ2mA%|5bh?;80D-*^c4*5W{f%139w|`0|eU*GrtD?5}Be0ydULq zlN9G}*Kibb3~z$&d$u#4jA|IGxW15jLp>!n#oBpd%7-z3F2%_?3eZ<4_^_y8+k z+dd-6jCN*_gKiq;9`eaHTA?bzl6*;^L#D1#@RJQ&bD1Rs5(~q#q)?UNI+_Q}K zao@mg5!}P%>avWIEprYqjWbT*?J!OtT~IFY^pY>l(ySA~-B2uY4zP^=?kE0n3$_C> z0?q;CbBv=GaF$Wza}W@QNs?8{1=Lg45sF3pZPpQvLFzfKe)b{mKEQ(n_7Cnps7J(0 z))De0(iPqwAX)�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