From 86a611574b54dd6d53d937a3306fb2dcce6af134 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Mon, 16 Mar 2020 19:02:45 +0100 Subject: [PATCH 01/22] Update README.md --- README.md | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index e254b0ad87..8110887cbd 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,11 @@ Pype ==== -The base studio _config_ for [Avalon](https://getavalon.github.io/) +Welcome to PYPE _config_ for [Avalon](https://getavalon.github.io/) -Currently this config is dependent on our customised avalon instalation so it won't work with vanilla avalon core. We're working on open sourcing all of the necessary code though. You can still get inspiration or take our individual validators and scripts which should work just fine in other pipelines. +To get all the key information about the project, go to [PYPE.club](http://pype.club) + + +Currently this config is dependent on our customised avalon instalation so it won't work with vanilla avalon core. To install it you'll need to download [pype-setup](github.com/pypeclub/pype-setup), which is able to deploy everything for you if you follow the documentation. _This configuration acts as a starting point for all pype club clients wth avalon deployment._ - -Code convention ---------------- - -Below are some of the standard practices applied to this repositories. - -- **Etiquette: PEP8** - - All code is written in PEP8. It is recommended you use a linter as you work, flake8 and pylinter are both good options. -- **Etiquette: Napoleon docstrings** - - Any docstrings are made in Google Napoleon format. See [Napoleon](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) for details. - -- **Etiquette: Semantic Versioning** - - This project follows [semantic versioning](http://semver.org). -- **Etiquette: Underscore means private** - - Anything prefixed with an underscore means that it is internal to wherever it is used. For example, a variable name is only ever used in the parent function or class. A module is not for use by the end-user. In contrast, anything without an underscore is public, but not necessarily part of the API. Members of the API resides in `api.py`. - -- **API: Idempotence** - - A public function must be able to be called twice and produce the exact same result. This means no changing of state without restoring previous state when finishing. For example, if a function requires changing the current selection in Autodesk Maya, it must restore the previous selection prior to completing. From 12557526c32e9d38d77d8ba73d3ff8a45975890b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 19:47:29 +0100 Subject: [PATCH 02/22] integrate ftrack note use label from ftrack's custom attribute configuration --- .../ftrack/publish/integrate_ftrack_note.py | 71 +++++++++++++++++-- 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_note.py b/pype/plugins/ftrack/publish/integrate_ftrack_note.py index 2621ca96ab..9d040585d5 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_note.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_note.py @@ -1,4 +1,5 @@ import sys +import json import pyblish.api import six @@ -18,6 +19,47 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): # - note label must exist in Ftrack note_labels = [] + def get_intent_label(self, session, intent_value): + if not intent_value: + return + + intent_configurations = session.query( + "CustomAttributeConfiguration where key is intent" + ).all() + if not intent_configurations: + return + + intent_configuration = intent_configurations[0] + if len(intent_configuration) > 1: + self.log.warning(( + "Found more than one `intent` custom attribute." + " Using first found." + )) + + config = intent_configuration.get("config") + if not config: + return + + items = config.get("data") + if not items: + return + + if sys.version_info[0] < 3: + string_type = basestring + else: + string_type = str + + if isinstance(items, string_type): + items = json.loads(items) + + intent_label = None + for item in items: + if item["value"] == intent_value: + intent_label = item["menu"] + break + + return intent_label + def process(self, instance): comment = (instance.context.data.get("comment") or "").strip() if not comment: @@ -26,17 +68,33 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): self.log.debug("Comment is set to `{}`".format(comment)) - intent = instance.context.data.get("intent") - if intent: - msg = "Intent is set to `{}` and was added to comment.".format( - intent - ) + session = instance.context.data["ftrackSession"] + + intent_val = instance.context.data.get("intent", {}).get("value") + intent_label = None + if intent_val: + intent_label = self.get_intent_label(session, intent_val) + if intent_label is None: + intent_label = intent_val + + # if intent label is set then format comment + # - it is possible that intent_label is equal to "" (empty string) + if intent_label: + msg = "Intent label is to `{}`.".format(intent_label) comment = self.note_with_intent_template.format(**{ - "intent": intent, + "intent": intent_val, "comment": comment }) + + elif intent_val: + msg = ( + "Intent is set to `{}` and was not added" + " to comment because label is set to `{}`." + ).format(intent_val, intent_label) + else: msg = "Intent is not set." + self.log.debug(msg) asset_versions_key = "ftrackIntegratedAssetVersions" @@ -45,7 +103,6 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): self.log.info("There are any integrated AssetVersions") return - session = instance.context.data["ftrackSession"] user = session.query( "User where username is \"{}\"".format(session.api_user) ).first() From d2f9336b4541ce1ace974b6e162da525b2dad8c3 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 19:51:20 +0100 Subject: [PATCH 03/22] updated intent getting --- pype/plugins/ftrack/publish/integrate_ftrack_instances.py | 2 +- pype/plugins/global/publish/extract_burnin.py | 2 +- pype/plugins/nuke/publish/extract_slate_frame.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index ec57f46d61..591dcf0dc2 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -127,7 +127,7 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): # Add custom attributes for AssetVersion assetversion_cust_attrs = {} - intent_val = instance.context.data.get("intent") + intent_val = instance.context.data.get("intent", {}).get("value") if intent_val: assetversion_cust_attrs["intent"] = intent_val diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 1251e5c02f..be287fbb14 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -52,7 +52,7 @@ class ExtractBurnin(pype.api.Extractor): "duration": duration, "version": int(version), "comment": instance.context.data.get("comment", ""), - "intent": instance.context.data.get("intent", "") + "intent": instance.context.data.get("intent", {}).get("label", "") }) # get anatomy project diff --git a/pype/plugins/nuke/publish/extract_slate_frame.py b/pype/plugins/nuke/publish/extract_slate_frame.py index 0d8bfe9dc5..eff51d95d4 100644 --- a/pype/plugins/nuke/publish/extract_slate_frame.py +++ b/pype/plugins/nuke/publish/extract_slate_frame.py @@ -157,7 +157,7 @@ class ExtractSlateFrame(pype.api.Extractor): return comment = instance.context.data.get("comment") - intent = instance.context.data.get("intent") + intent = instance.context.data.get("intent", {}).get("value") try: node["f_submission_note"].setValue(comment) From 354c8d7a50092e7f998552abc5c6433e2e2b54ff Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 19:51:52 +0100 Subject: [PATCH 04/22] set intent only if set in extract burnin --- pype/plugins/global/publish/extract_burnin.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index be287fbb14..086a1fdfb2 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -51,10 +51,13 @@ class ExtractBurnin(pype.api.Extractor): "frame_end": frame_end_handle, "duration": duration, "version": int(version), - "comment": instance.context.data.get("comment", ""), - "intent": instance.context.data.get("intent", {}).get("label", "") + "comment": instance.context.data.get("comment", "") }) + intent = instance.context.data.get("intent", {}).get("label") + if intent: + prep_data["intent"] = intent + # get anatomy project anatomy = instance.context.data['anatomy'] From 349beaccfc5ca213771325c84e4ef8dec4ecdc0b Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 19:52:04 +0100 Subject: [PATCH 05/22] collect anatomy docs cleanup --- pype/plugins/global/publish/collect_anatomy.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pype/plugins/global/publish/collect_anatomy.py b/pype/plugins/global/publish/collect_anatomy.py index ae83e39513..73ae3bb024 100644 --- a/pype/plugins/global/publish/collect_anatomy.py +++ b/pype/plugins/global/publish/collect_anatomy.py @@ -6,10 +6,6 @@ Requires: username -> collect_pype_user *(pyblish.api.CollectorOrder + 0.001) datetimeData -> collect_datetime_data *(pyblish.api.CollectorOrder) -Optional: - comment -> collect_comment *(pyblish.api.CollectorOrder) - intent -> collected in pyblish-lite - Provides: context -> anatomy (pypeapp.Anatomy) context -> anatomyData From 8072f1dcc9736eeacd3387fb8ddc276725c39d7a Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 19:52:59 +0100 Subject: [PATCH 06/22] removed intent from required keys in collect rendered files --- pype/plugins/global/publish/collect_rendered_files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/global/publish/collect_rendered_files.py b/pype/plugins/global/publish/collect_rendered_files.py index 010cf44c15..552fd49f6d 100644 --- a/pype/plugins/global/publish/collect_rendered_files.py +++ b/pype/plugins/global/publish/collect_rendered_files.py @@ -35,7 +35,7 @@ class CollectRenderedFiles(pyblish.api.ContextPlugin): def _process_path(self, data): # validate basic necessary data data_err = "invalid json file - missing data" - required = ["asset", "user", "intent", "comment", + required = ["asset", "user", "comment", "job", "instances", "session", "version"] assert all(elem in data.keys() for elem in required), data_err From f37ea5d82ae82b9c8c04ba06d86f982a120035ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 20:09:14 +0100 Subject: [PATCH 07/22] intent is not required in extract slate frame --- pype/plugins/nuke/publish/extract_slate_frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/nuke/publish/extract_slate_frame.py b/pype/plugins/nuke/publish/extract_slate_frame.py index eff51d95d4..369cbe0496 100644 --- a/pype/plugins/nuke/publish/extract_slate_frame.py +++ b/pype/plugins/nuke/publish/extract_slate_frame.py @@ -157,7 +157,7 @@ class ExtractSlateFrame(pype.api.Extractor): return comment = instance.context.data.get("comment") - intent = instance.context.data.get("intent", {}).get("value") + intent = instance.context.data.get("intent", {}).get("value", "") try: node["f_submission_note"].setValue(comment) From 0d20e27cb3d7912fc5f7a7716473c55df495c24c Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 20:13:51 +0100 Subject: [PATCH 08/22] it is used default intent label in ftrack if ftrack's not found --- .../ftrack/publish/integrate_ftrack_note.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_note.py b/pype/plugins/ftrack/publish/integrate_ftrack_note.py index 9d040585d5..a0e7719779 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_note.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_note.py @@ -71,18 +71,19 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): session = instance.context.data["ftrackSession"] intent_val = instance.context.data.get("intent", {}).get("value") - intent_label = None + intent_label = instance.context.data.get("intent", {}).get("label") + final_label = None if intent_val: - intent_label = self.get_intent_label(session, intent_val) - if intent_label is None: - intent_label = intent_val + final_label = self.get_intent_label(session, intent_val) + if final_label is None: + final_label = intent_label # if intent label is set then format comment # - it is possible that intent_label is equal to "" (empty string) - if intent_label: - msg = "Intent label is to `{}`.".format(intent_label) + if final_label: + msg = "Intent label is set to `{}`.".format(final_label) comment = self.note_with_intent_template.format(**{ - "intent": intent_val, + "intent": final_label, "comment": comment }) @@ -90,7 +91,7 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): msg = ( "Intent is set to `{}` and was not added" " to comment because label is set to `{}`." - ).format(intent_val, intent_label) + ).format(intent_val, final_label) else: msg = "Intent is not set." From c91b49510045afc5903db2eff5813bc8a09bab39 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 16 Mar 2020 20:22:02 +0100 Subject: [PATCH 09/22] fix ftrack json parse --- pype/plugins/ftrack/publish/integrate_ftrack_note.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_note.py b/pype/plugins/ftrack/publish/integrate_ftrack_note.py index a0e7719779..679010ca58 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_note.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_note.py @@ -40,7 +40,8 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): if not config: return - items = config.get("data") + configuration = json.loads(config) + items = configuration.get("data") if not items: return From 59f97ef904057093d5b74082aadf7e35501740f3 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Tue, 17 Mar 2020 15:56:46 +0100 Subject: [PATCH 10/22] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index dfcd71eb3f..63249bb52b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018 orbi tools s.r.o +Copyright (c) 2020 Orbi Tools s.r.o. Permission is hereby granted, free of charge, to any person obtaining a copy From a549634c0ad925a038574bc01610f8abf93089a5 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Tue, 17 Mar 2020 16:12:29 +0100 Subject: [PATCH 11/22] added options to maya reference loader --- pype/maya/plugin.py | 71 ++++++++++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/pype/maya/plugin.py b/pype/maya/plugin.py index 327cf47cbd..85de5adec5 100644 --- a/pype/maya/plugin.py +++ b/pype/maya/plugin.py @@ -1,4 +1,5 @@ from avalon import api +from avalon.vendor import qargparse def get_reference_node_parents(ref): @@ -33,11 +34,25 @@ class ReferenceLoader(api.Loader): `update` logic. """ - def load(self, - context, - name=None, - namespace=None, - data=None): + + options = [ + qargparse.Integer( + "count", + label="Count", + default=1, + min=1, + help="How many times to load?" + ) + ] + + def load( + self, + context, + name=None, + namespace=None, + options=None, + data=None + ): import os from avalon.maya import lib @@ -46,29 +61,37 @@ class ReferenceLoader(api.Loader): assert os.path.exists(self.fname), "%s does not exist." % self.fname asset = context['asset'] + loaded_containers = [] - namespace = namespace or lib.unique_namespace( - asset["name"] + "_", - prefix="_" if asset["name"][0].isdigit() else "", - suffix="_", - ) + count = options.get("count") or 1 + while count > 0: + count -= 1 + namespace = namespace or lib.unique_namespace( + asset["name"] + "_", + prefix="_" if asset["name"][0].isdigit() else "", + suffix="_", + ) - self.process_reference(context=context, - name=name, - namespace=namespace, - data=data) + self.process_reference( + context=context, + name=name, + namespace=namespace, + data=data + ) - # Only containerize if any nodes were loaded by the Loader - nodes = self[:] - if not nodes: - return + # Only containerize if any nodes were loaded by the Loader + nodes = self[:] + if not nodes: + return - return containerise( - name=name, - namespace=namespace, - nodes=nodes, - context=context, - loader=self.__class__.__name__) + loaded_containers.append(containerise( + name=name, + namespace=namespace, + nodes=nodes, + context=context, + loader=self.__class__.__name__ + )) + return loaded_containers def process_reference(self, context, name, namespace, data): """To be implemented by subclass""" From e10343de2be9a795a42b98bee2d5bd8c55343a44 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 18 Mar 2020 10:24:25 +0100 Subject: [PATCH 12/22] add offset when loading multiple subsets --- pype/maya/plugin.py | 23 ++++++++++++++++++----- pype/plugins/maya/load/load_reference.py | 12 ++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/pype/maya/plugin.py b/pype/maya/plugin.py index 85de5adec5..ed244d56df 100644 --- a/pype/maya/plugin.py +++ b/pype/maya/plugin.py @@ -42,6 +42,11 @@ class ReferenceLoader(api.Loader): default=1, min=1, help="How many times to load?" + ), + qargparse.Double3( + "offset", + label="Position Offset", + help="Offset loaded models for easier selection." ) ] @@ -50,8 +55,7 @@ class ReferenceLoader(api.Loader): context, name=None, namespace=None, - options=None, - data=None + options=None ): import os @@ -64,19 +68,25 @@ class ReferenceLoader(api.Loader): loaded_containers = [] count = options.get("count") or 1 - while count > 0: - count -= 1 + for c in range(0, count): namespace = namespace or lib.unique_namespace( asset["name"] + "_", prefix="_" if asset["name"][0].isdigit() else "", suffix="_", ) + # Offset loaded subset + if "offset" in options: + offset = [i * c for i in options["offset"]] + options["translate"] = offset + + self.log.info(options) + self.process_reference( context=context, name=name, namespace=namespace, - data=data + options=options ) # Only containerize if any nodes were loaded by the Loader @@ -91,6 +101,9 @@ class ReferenceLoader(api.Loader): context=context, loader=self.__class__.__name__ )) + + c += 1 + namespace = None return loaded_containers def process_reference(self, context, name, namespace, data): diff --git a/pype/plugins/maya/load/load_reference.py b/pype/plugins/maya/load/load_reference.py index cbd1da7cbd..b1192d9c9e 100644 --- a/pype/plugins/maya/load/load_reference.py +++ b/pype/plugins/maya/load/load_reference.py @@ -1,4 +1,5 @@ import pype.maya.plugin +reload(pype.maya.plugin) from avalon import api, maya from maya import cmds import os @@ -24,7 +25,7 @@ class ReferenceLoader(pype.maya.plugin.ReferenceLoader): icon = "code-fork" color = "orange" - def process_reference(self, context, name, namespace, data): + def process_reference(self, context, name, namespace, options): import maya.cmds as cmds from avalon import maya import pymel.core as pm @@ -101,16 +102,19 @@ class ReferenceLoader(pype.maya.plugin.ReferenceLoader): cmds.setAttr(groupName + ".selectHandleY", cy) cmds.setAttr(groupName + ".selectHandleZ", cz) - if data.get("post_process", True): + if "translate" in options: + cmds.setAttr(groupName + ".t", *options["translate"]) + + if options.get("post_process", True): if family == "rig": - self._post_process_rig(name, namespace, context, data) + self._post_process_rig(name, namespace, context, options) return newNodes def switch(self, container, representation): self.update(container, representation) - def _post_process_rig(self, name, namespace, context, data): + def _post_process_rig(self, name, namespace, context, options): output = next((node for node in self if node.endswith("out_SET")), None) From 6c2b056dd479be7232e95ee7ac6adc7d09eeba24 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 18 Mar 2020 10:51:31 +0100 Subject: [PATCH 13/22] make sure not to offset rigs --- pype/plugins/maya/load/load_reference.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/pype/plugins/maya/load/load_reference.py b/pype/plugins/maya/load/load_reference.py index b1192d9c9e..797933300c 100644 --- a/pype/plugins/maya/load/load_reference.py +++ b/pype/plugins/maya/load/load_reference.py @@ -1,5 +1,4 @@ import pype.maya.plugin -reload(pype.maya.plugin) from avalon import api, maya from maya import cmds import os @@ -102,12 +101,11 @@ class ReferenceLoader(pype.maya.plugin.ReferenceLoader): cmds.setAttr(groupName + ".selectHandleY", cy) cmds.setAttr(groupName + ".selectHandleZ", cz) - if "translate" in options: - cmds.setAttr(groupName + ".t", *options["translate"]) - - if options.get("post_process", True): - if family == "rig": - self._post_process_rig(name, namespace, context, options) + if family == "rig": + self._post_process_rig(name, namespace, context, options) + else: + if "translate" in options: + cmds.setAttr(groupName + ".t", *options["translate"]) return newNodes From 47468403515e33d8b845042a474caad12ac81864 Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 18 Mar 2020 12:13:48 +0100 Subject: [PATCH 14/22] add houndci configuration and change flake8 config --- .flake8 | 2 ++ .hound.yml | 0 2 files changed, 2 insertions(+) create mode 100644 .hound.yml diff --git a/.flake8 b/.flake8 index 9de8d23bb2..67ed2d77a3 100644 --- a/.flake8 +++ b/.flake8 @@ -1,5 +1,7 @@ [flake8] # ignore = D203 +ignore = BLK100 +max-line-length = 79 exclude = .git, __pycache__, diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 0000000000..e69de29bb2 From 321c27234a23c169f2ae5cea94a3223f6b7b82fc Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 18 Mar 2020 12:22:38 +0100 Subject: [PATCH 15/22] wrong attribute used for pixelAspec --- pype/plugins/maya/publish/collect_render.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pype/plugins/maya/publish/collect_render.py b/pype/plugins/maya/publish/collect_render.py index f3ea1ccee5..be3878e6bd 100644 --- a/pype/plugins/maya/publish/collect_render.py +++ b/pype/plugins/maya/publish/collect_render.py @@ -238,7 +238,7 @@ class CollectMayaRender(pyblish.api.ContextPlugin): "expectedFiles": full_exp_files, "resolutionWidth": cmds.getAttr("defaultResolution.width"), "resolutionHeight": cmds.getAttr("defaultResolution.height"), - "pixelAspect": cmds.getAttr("defaultResolution.height") + "pixelAspect": cmds.getAttr("defaultResolution.pixelAspect") } # Apply each user defined attribute as data From 1f0383268722a5b85b40b740404c1c221b60dbe8 Mon Sep 17 00:00:00 2001 From: Milan Kolar Date: Wed, 18 Mar 2020 12:50:03 +0100 Subject: [PATCH 16/22] pool was being overwritten in submit publish job --- pype/plugins/global/publish/submit_publish_job.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pype/plugins/global/publish/submit_publish_job.py b/pype/plugins/global/publish/submit_publish_job.py index 47c0272254..dcf19ae32c 100644 --- a/pype/plugins/global/publish/submit_publish_job.py +++ b/pype/plugins/global/publish/submit_publish_job.py @@ -238,8 +238,7 @@ class ProcessSubmittedJobOnFarm(pyblish.api.InstancePlugin): ) i += 1 - # Avoid copied pools and remove secondary pool - payload["JobInfo"]["Pool"] = "none" + # remove secondary pool payload["JobInfo"].pop("SecondaryPool", None) self.log.info("Submitting Deadline job ...") From fb9cd34cb5b5e153906728a2b89fd48a1863e10f Mon Sep 17 00:00:00 2001 From: Ondrej Samohel Date: Wed, 18 Mar 2020 18:16:44 +0100 Subject: [PATCH 17/22] allow exports of non-baked cameras --- .../maya/publish/extract_camera_mayaAscii.py | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/pype/plugins/maya/publish/extract_camera_mayaAscii.py b/pype/plugins/maya/publish/extract_camera_mayaAscii.py index 30f686f6f5..ef80ed4ad4 100644 --- a/pype/plugins/maya/publish/extract_camera_mayaAscii.py +++ b/pype/plugins/maya/publish/extract_camera_mayaAscii.py @@ -94,11 +94,6 @@ class ExtractCameraMayaAscii(pype.api.Extractor): step = instance.data.get("step", 1.0) bake_to_worldspace = instance.data("bakeToWorldSpace", True) - # TODO: Implement a bake to non-world space - # Currently it will always bake the resulting camera to world-space - # and it does not allow to include the parent hierarchy, even though - # with `bakeToWorldSpace` set to False it should include its - # hierarchy to be correct with the family implementation. if not bake_to_worldspace: self.log.warning("Camera (Maya Ascii) export only supports world" "space baked camera extractions. The disabled " @@ -113,7 +108,7 @@ class ExtractCameraMayaAscii(pype.api.Extractor): framerange[1] + handles] # validate required settings - assert len(cameras) == 1, "Not a single camera found in extraction" + assert len(cameras) == 1, "Single camera must be found in extraction" assert isinstance(step, float), "Step must be a float value" camera = cameras[0] transform = cmds.listRelatives(camera, parent=True, fullPath=True) @@ -124,21 +119,24 @@ class ExtractCameraMayaAscii(pype.api.Extractor): path = os.path.join(dir_path, filename) # Perform extraction - self.log.info("Performing camera bakes for: {0}".format(transform)) with avalon.maya.maintained_selection(): with lib.evaluation("off"): with avalon.maya.suspended_refresh(): - baked = lib.bake_to_world_space( - transform, - frame_range=range_with_handles, - step=step - ) - baked_shapes = cmds.ls(baked, - type="camera", - dag=True, - shapes=True, - long=True) - + if bake_to_worldspace: + self.log.info( + "Performing camera bakes: {}".format(transform)) + baked = lib.bake_to_world_space( + transform, + frame_range=range_with_handles, + step=step + ) + baked_shapes = cmds.ls(baked, + type="camera", + dag=True, + shapes=True, + long=True) + else: + baked_shapes = cameras # Fix PLN-178: Don't allow background color to be non-black for cam in baked_shapes: attrs = {"backgroundColorR": 0.0, @@ -164,7 +162,8 @@ class ExtractCameraMayaAscii(pype.api.Extractor): expressions=False) # Delete the baked hierarchy - cmds.delete(baked) + if bake_to_worldspace: + cmds.delete(baked) massage_ma_file(path) From 3c4e427b135bde7f2d8203462e74c287bedd7664 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 18 Mar 2020 20:28:43 +0100 Subject: [PATCH 18/22] store popen to variable --- pype/ftrack/lib/ftrack_app_handler.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pype/ftrack/lib/ftrack_app_handler.py b/pype/ftrack/lib/ftrack_app_handler.py index 2b46dd43d8..eebffda280 100644 --- a/pype/ftrack/lib/ftrack_app_handler.py +++ b/pype/ftrack/lib/ftrack_app_handler.py @@ -286,7 +286,9 @@ class AppAction(BaseHandler): # Run SW if was found executable if execfile is not None: - avalonlib.launch(executable=execfile, args=[], environment=env) + popen = avalonlib.launch( + executable=execfile, args=[], environment=env + ) else: return { 'success': False, From 7f035d146f580b7591238d7d5491f09692eb61a1 Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Wed, 18 Mar 2020 20:28:57 +0100 Subject: [PATCH 19/22] blender init cleanup --- pype/blender/__init__.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pype/blender/__init__.py b/pype/blender/__init__.py index 8a29917e40..4b6074a820 100644 --- a/pype/blender/__init__.py +++ b/pype/blender/__init__.py @@ -1,16 +1,8 @@ -import logging -from pathlib import Path import os -import bpy - from avalon import api as avalon from pyblish import api as pyblish -from .plugin import AssetLoader - -logger = logging.getLogger("pype.blender") - PARENT_DIR = os.path.dirname(__file__) PACKAGE_DIR = os.path.dirname(PARENT_DIR) PLUGINS_DIR = os.path.join(PACKAGE_DIR, "plugins") From c06d4f6ecda1cc2fae0355765f13b98170debeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= <33513211+antirotor@users.noreply.github.com> Date: Thu, 19 Mar 2020 10:46:52 +0100 Subject: [PATCH 20/22] hound config should point to flake8 config --- .hound.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.hound.yml b/.hound.yml index e69de29bb2..409cc4416a 100644 --- a/.hound.yml +++ b/.hound.yml @@ -0,0 +1,4 @@ +flake8: + enabled: true + config_file: .flake8 + From 61df87ff4bb3e9cd53391a1be2524f3bf372a0ad Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 19 Mar 2020 12:51:58 +0100 Subject: [PATCH 21/22] hopefully intent is backwards compatible --- .../publish/integrate_ftrack_instances.py | 5 ++++- .../ftrack/publish/integrate_ftrack_note.py | 9 +++++++-- pype/plugins/global/publish/extract_burnin.py | 9 ++++++--- pype/plugins/global/publish/integrate_new.py | 18 ++++++++++++------ .../nuke/publish/extract_slate_frame.py | 6 ++++-- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py index 591dcf0dc2..db257e901a 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_instances.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_instances.py @@ -127,7 +127,10 @@ class IntegrateFtrackInstance(pyblish.api.InstancePlugin): # Add custom attributes for AssetVersion assetversion_cust_attrs = {} - intent_val = instance.context.data.get("intent", {}).get("value") + intent_val = instance.context.data.get("intent") + if intent_val and isinstance(intent_val, dict): + intent_val = intent_val.get("value") + if intent_val: assetversion_cust_attrs["intent"] = intent_val diff --git a/pype/plugins/ftrack/publish/integrate_ftrack_note.py b/pype/plugins/ftrack/publish/integrate_ftrack_note.py index 679010ca58..9566207145 100644 --- a/pype/plugins/ftrack/publish/integrate_ftrack_note.py +++ b/pype/plugins/ftrack/publish/integrate_ftrack_note.py @@ -71,8 +71,13 @@ class IntegrateFtrackNote(pyblish.api.InstancePlugin): session = instance.context.data["ftrackSession"] - intent_val = instance.context.data.get("intent", {}).get("value") - intent_label = instance.context.data.get("intent", {}).get("label") + intent = instance.context.data.get("intent") + if intent and isinstance(intent, dict): + intent_val = intent.get("value") + intent_label = intent.get("label") + else: + intent_val = intent_label = intent + final_label = None if intent_val: final_label = self.get_intent_label(session, intent_val) diff --git a/pype/plugins/global/publish/extract_burnin.py b/pype/plugins/global/publish/extract_burnin.py index 086a1fdfb2..71463e296e 100644 --- a/pype/plugins/global/publish/extract_burnin.py +++ b/pype/plugins/global/publish/extract_burnin.py @@ -54,9 +54,12 @@ class ExtractBurnin(pype.api.Extractor): "comment": instance.context.data.get("comment", "") }) - intent = instance.context.data.get("intent", {}).get("label") - if intent: - prep_data["intent"] = intent + intent_label = instance.context.data.get("intent") + if intent_label and isinstance(intent_label, dict): + intent_label = intent_label.get("label") + + if intent_label: + prep_data["intent"] = intent_label # get anatomy project anatomy = instance.context.data['anatomy'] diff --git a/pype/plugins/global/publish/integrate_new.py b/pype/plugins/global/publish/integrate_new.py index aa214f36cb..ccfb3689e2 100644 --- a/pype/plugins/global/publish/integrate_new.py +++ b/pype/plugins/global/publish/integrate_new.py @@ -243,9 +243,12 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): instance.data['version'] = version['name'] - intent = context.data.get("intent") - if intent is not None: - anatomy_data["intent"] = intent + intent_value = instance.context.data.get("intent") + if intent_value and isinstance(intent_value, dict): + intent_value = intent_value.get("value") + + if intent_value: + anatomy_data["intent"] = intent_value anatomy = instance.context.data['anatomy'] @@ -653,9 +656,12 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): "fps": context.data.get( "fps", instance.data.get("fps"))} - intent = context.data.get("intent") - if intent is not None: - version_data["intent"] = intent + intent_value = instance.context.data.get("intent") + if intent_value and isinstance(intent_value, dict): + intent_value = intent_value.get("value") + + if intent_value: + version_data["intent"] = intent_value # Include optional data if present in optionals = [ diff --git a/pype/plugins/nuke/publish/extract_slate_frame.py b/pype/plugins/nuke/publish/extract_slate_frame.py index 369cbe0496..e1c05c3d1a 100644 --- a/pype/plugins/nuke/publish/extract_slate_frame.py +++ b/pype/plugins/nuke/publish/extract_slate_frame.py @@ -157,11 +157,13 @@ class ExtractSlateFrame(pype.api.Extractor): return comment = instance.context.data.get("comment") - intent = instance.context.data.get("intent", {}).get("value", "") + intent_value = instance.context.data.get("intent") + if intent_value and isinstance(intent_value, dict): + intent_value = intent_value.get("value") try: node["f_submission_note"].setValue(comment) - node["f_submitting_for"].setValue(intent) + node["f_submitting_for"].setValue(intent_value or "") except NameError: return instance.data.pop("slateNode") From f5426c78a61697e2381fb3c0c6438cefa69f75cf Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Thu, 19 Mar 2020 17:56:54 +0100 Subject: [PATCH 22/22] install custom excepthook to not crash blender --- pype/blender/__init__.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pype/blender/__init__.py b/pype/blender/__init__.py index 4b6074a820..4f52b4168a 100644 --- a/pype/blender/__init__.py +++ b/pype/blender/__init__.py @@ -1,4 +1,6 @@ import os +import sys +import traceback from avalon import api as avalon from pyblish import api as pyblish @@ -11,9 +13,16 @@ PUBLISH_PATH = os.path.join(PLUGINS_DIR, "blender", "publish") LOAD_PATH = os.path.join(PLUGINS_DIR, "blender", "load") CREATE_PATH = os.path.join(PLUGINS_DIR, "blender", "create") +ORIGINAL_EXCEPTHOOK = sys.excepthook + + +def pype_excepthook_handler(*args): + traceback.print_exception(*args) + def install(): """Install Blender configuration for Avalon.""" + sys.excepthook = pype_excepthook_handler pyblish.register_plugin_path(str(PUBLISH_PATH)) avalon.register_plugin_path(avalon.Loader, str(LOAD_PATH)) avalon.register_plugin_path(avalon.Creator, str(CREATE_PATH)) @@ -21,6 +30,7 @@ def install(): def uninstall(): """Uninstall Blender configuration for Avalon.""" + sys.excepthook = ORIGINAL_EXCEPTHOOK pyblish.deregister_plugin_path(str(PUBLISH_PATH)) avalon.deregister_plugin_path(avalon.Loader, str(LOAD_PATH)) avalon.deregister_plugin_path(avalon.Creator, str(CREATE_PATH))