From 9be28b8051124fd8d699b665299c6eeb98cbc63b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:00:16 +0200 Subject: [PATCH 01/31] Fix `publish_attributes` access --- .../plugins/publish/validate_alembic_options_defaults.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 5197100406..a9de510e67 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -29,13 +29,7 @@ class ValidateAlembicDefaultsPointcache( @classmethod def _get_publish_attributes(cls, instance): - attributes = instance.data["publish_attributes"][ - cls.plugin_name( - instance.data["publish_attributes"] - ) - ] - - return attributes + return instance.data["publish_attributes"][cls.plugin_name] def process(self, instance): if not self.is_active(instance.data): From b05cac07b8b9cb596aa090c77b0425a216cadd65 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:01:52 +0200 Subject: [PATCH 02/31] Fix repair logic --- .../maya/plugins/publish/validate_alembic_options_defaults.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index a9de510e67..940e4f3869 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -69,13 +69,11 @@ class ValidateAlembicDefaultsPointcache( ) # Set the settings values on the create context then save to workfile. - publish_attributes = instance.data["publish_attributes"] - plugin_name = cls.plugin_name(publish_attributes) attributes = cls._get_publish_attributes(instance) settings = cls._get_settings(instance.context) create_publish_attributes = create_instance.data["publish_attributes"] for key in attributes: - create_publish_attributes[plugin_name][key] = settings[key] + create_publish_attributes[cls.plugin_name][key] = settings[key] create_context.save_changes() From 8567e54bb45547bd6b6a31d05123d5c80af626fe Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:04:33 +0200 Subject: [PATCH 03/31] Fix label --- .../maya/plugins/publish/validate_alembic_options_defaults.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 940e4f3869..1045ef3c70 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -85,6 +85,6 @@ class ValidateAlembicDefaultsAnimation( The defaults are defined in the project settings. """ - label = "Validate Alembic Options Defaults" + label = "Validate Alembic Options Defaults" families = ["animation"] plugin_name = "ExtractAnimation" From 665a4e226a6cc42039afe938b57ea33d269592d4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:12:17 +0200 Subject: [PATCH 04/31] Fix `writeCreases` support --- .../hosts/maya/plugins/publish/extract_pointcache.py | 8 ++++++++ server_addon/maya/server/settings/publishers.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py index d7f9594374..d34634bff8 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py @@ -63,6 +63,7 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): wholeFrameGeo = False worldSpace = True writeColorSets = False + writeCreases = False writeFaceSets = False writeNormals = True writeUVSets = False @@ -354,6 +355,13 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): default=cls.writeColorSets, tooltip="Write vertex colors with the geometry." ), + "writeCreases": BoolDef( + "writeCreases", + label="Write Creases", + default=cls.writeCreases, + tooltip="Write the geometry's edge and vertex crease " + "information." + ), "writeFaceSets": BoolDef( "writeFaceSets", label="Write Face Sets", diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index 8dcffbb59a..ee74eaa553 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -406,6 +406,10 @@ class ExtractAlembicModel(BaseSettingsModel): title="Write Color Sets", description="Write vertex colors with the geometry." ) + writeCreases: bool = SettingsField( + title="Write Creases", + description="Write the geometry's edge and vertex crease information." + ) writeFaceSets: bool = SettingsField( title="Write Face Sets", description="Write face sets with the geometry." @@ -1643,6 +1647,7 @@ DEFAULT_PUBLISH_SETTINGS = { "wholeFrameGeo": False, "worldSpace": True, "writeColorSets": False, + "writeCreases": False, "writeFaceSets": False, "writeNormals": True, "writeUVSets": False, From 141767ef717cf8b15baec850de71f0dc2f013871 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:13:49 +0200 Subject: [PATCH 05/31] Cosmetics --- .../maya/plugins/publish/validate_alembic_options_defaults.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 1045ef3c70..476f837135 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -36,7 +36,6 @@ class ValidateAlembicDefaultsPointcache( return settings = self._get_settings(instance.context) - attributes = self._get_publish_attributes(instance) msg = ( From 0352c17a09108cfcf768aac58da2fef5c67cf12a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:18:20 +0200 Subject: [PATCH 06/31] Add support for extracting the user attributes --- client/ayon_core/hosts/maya/api/alembic.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/client/ayon_core/hosts/maya/api/alembic.py b/client/ayon_core/hosts/maya/api/alembic.py index bf887df4c7..954c0a0888 100644 --- a/client/ayon_core/hosts/maya/api/alembic.py +++ b/client/ayon_core/hosts/maya/api/alembic.py @@ -63,6 +63,8 @@ def extract_alembic( startFrame=None, step=1.0, stripNamespaces=True, + userAttr=None, + userAttrPrefix=None, uvWrite=True, verbose=False, wholeFrameGeo=False, @@ -137,6 +139,12 @@ def extract_alembic( object with the namespace taco:foo:bar appears as bar in the Alembic file. + userAttr (list of str, optional): A specific user defined attribute to + write out. Defaults to []. + + userAttrPrefix (list of str, optional): Prefix filter for determining + which user defined attributes to write out. Defaults to []. + uvWrite (bool): When on, UV data from polygon meshes and subdivision objects are written to the Alembic file. Only the current UV map is included. @@ -183,6 +191,8 @@ def extract_alembic( # Ensure list arguments are valid. attr = attr or [] attrPrefix = attrPrefix or [] + userAttr = userAttr or [] + userAttrPrefix = userAttrPrefix or [] root = root or [] # Pass the start and end frame on as `frameRange` so that it @@ -226,6 +236,8 @@ def extract_alembic( "step": step, "attr": attr, "attrPrefix": attrPrefix, + "userAttr": userAttr, + "userAttrPrefix": userAttrPrefix, "stripNamespaces": stripNamespaces, "verbose": verbose, "preRollStartFrame": preRollStartFrame From 367eba0f493d196525a308bac3085d87772553d9 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:25:00 +0200 Subject: [PATCH 07/31] Remove `autoSubd` in favor of legacy `writeCreases` usage across the codebase and existing instances --- .../plugins/publish/extract_pointcache.py | 20 +------------------ .../maya/server/settings/publishers.py | 13 ------------ 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py index d34634bff8..cff32ebb67 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py @@ -40,7 +40,6 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): # From settings attr = [] attrPrefix = [] - autoSubd = False bake_attributes = [] bake_attribute_prefixes = [] dataFormat = "ogawa" @@ -174,9 +173,6 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): "writeVisibility": attribute_values.get( "writeVisibility", self.writeVisibility ), - "autoSubd": attribute_values.get( - "autoSubd", self.autoSubd - ), "uvsOnly": attribute_values.get( "uvsOnly", self.uvsOnly ), @@ -250,7 +246,7 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): with maintained_selection(): cmds.select(instance.data["proxy"]) extract_alembic(**kwargs) - + raise RuntimeError("FAIL") representation = { "name": "proxy", "ext": "abc", @@ -269,20 +265,6 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): return [] override_defs = OrderedDict({ - "autoSubd": BoolDef( - "autoSubd", - label="Auto Subd", - default=cls.autoSubd, - tooltip=( - "If this flag is present and the mesh has crease edges, " - "crease vertices or holes, the mesh (OPolyMesh) would now " - "be written out as an OSubD and crease info will be stored" - " in the Alembic file. Otherwise, creases info won't be " - "preserved in Alembic file unless a custom Boolean " - "attribute SubDivisionMesh has been added to mesh node and" - " its value is true." - ) - ), "eulerFilter": BoolDef( "eulerFilter", label="Euler Filter", diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index ee74eaa553..3a82d649e1 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -46,7 +46,6 @@ def extract_alembic_overrides_enum(): return [ {"label": "Custom Attributes", "value": "attr"}, {"label": "Custom Attributes Prefix", "value": "attrPrefix"}, - {"label": "Auto Subd", "value": "autoSubd"}, {"label": "Data Format", "value": "dataFormat"}, {"label": "Euler Filter", "value": "eulerFilter"}, {"label": "Mel Per Frame Callback", "value": "melPerFrameCallback"}, @@ -344,17 +343,6 @@ class ExtractAlembicModel(BaseSettingsModel): families: list[str] = SettingsField( default_factory=list, title="Families") - autoSubd: bool = SettingsField( - title="Auto Subd", - description=( - "If this flag is present and the mesh has crease edges, crease " - "vertices or holes, the mesh (OPolyMesh) would now be written out " - "as an OSubD and crease info will be stored in the Alembic file. " - "Otherwise, creases info won't be preserved in Alembic file unless" - " a custom Boolean attribute SubDivisionMesh has been added to " - "mesh node and its value is true." - ) - ) eulerFilter: bool = SettingsField( title="Euler Filter", description="Apply Euler filter while sampling rotations." @@ -1615,7 +1603,6 @@ DEFAULT_PUBLISH_SETTINGS = { ], "attr": "", "attrPrefix": "", - "autoSubd": False, "bake_attributes": [], "bake_attribute_prefixes": [], "dataFormat": "ogawa", From 26eb91781365c44036b02e8644f3fb2774e78c5a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:26:53 +0200 Subject: [PATCH 08/31] Add `uvsOnly` argument --- client/ayon_core/hosts/maya/api/alembic.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/ayon_core/hosts/maya/api/alembic.py b/client/ayon_core/hosts/maya/api/alembic.py index 954c0a0888..a815dc7465 100644 --- a/client/ayon_core/hosts/maya/api/alembic.py +++ b/client/ayon_core/hosts/maya/api/alembic.py @@ -65,6 +65,7 @@ def extract_alembic( stripNamespaces=True, userAttr=None, userAttrPrefix=None, + uvsOnly=False, uvWrite=True, verbose=False, wholeFrameGeo=False, @@ -145,6 +146,9 @@ def extract_alembic( userAttrPrefix (list of str, optional): Prefix filter for determining which user defined attributes to write out. Defaults to []. + uvsOnly (bool): When on, only uv data for PolyMesh and SubD shapes + will be written to the Alembic file. + uvWrite (bool): When on, UV data from polygon meshes and subdivision objects are written to the Alembic file. Only the current UV map is included. @@ -225,6 +229,7 @@ def extract_alembic( "preRoll": preRoll, "renderableOnly": renderableOnly, "uvWrite": uvWrite, + "uvsOnly": uvsOnly, "writeColorSets": writeColorSets, "writeFaceSets": writeFaceSets, "wholeFrameGeo": wholeFrameGeo, From e43a4ba481e7f307ec114cae2b735dfbdbfae704 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:28:27 +0200 Subject: [PATCH 09/31] Fix usage of `root` argument --- client/ayon_core/hosts/maya/api/alembic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/client/ayon_core/hosts/maya/api/alembic.py b/client/ayon_core/hosts/maya/api/alembic.py index a815dc7465..3722774bba 100644 --- a/client/ayon_core/hosts/maya/api/alembic.py +++ b/client/ayon_core/hosts/maya/api/alembic.py @@ -227,6 +227,7 @@ def extract_alembic( "eulerFilter": eulerFilter, "noNormals": noNormals, "preRoll": preRoll, + "root": root, "renderableOnly": renderableOnly, "uvWrite": uvWrite, "uvsOnly": uvsOnly, From 828f7bbce2038a1a38a6fbde66d71fc8143083ae Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:37:42 +0200 Subject: [PATCH 10/31] Fix `writeNormals` usage --- .../hosts/maya/plugins/publish/extract_pointcache.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py index cff32ebb67..3c0350ec65 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py @@ -176,9 +176,6 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): "uvsOnly": attribute_values.get( "uvsOnly", self.uvsOnly ), - "writeNormals": attribute_values.get( - "writeNormals", self.writeNormals - ), "melPerFrameCallback": attribute_values.get( "melPerFrameCallback", self.melPerFrameCallback ), @@ -190,7 +187,12 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): ), "pythonPostJobCallback": attribute_values.get( "pythonPostJobCallback", self.pythonPostJobCallback - ) + ), + # Note that this converts `writeNormals` to `noNormals` for the + # `AbcExport` equivalent in `extract_alembic` + "noNormals": not attribute_values.get( + "writeNormals", self.writeNormals + ), } if instance.data.get("visibleOnly", False): From 5193d2664fed856399690869572f6a33dbb9f94a Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:38:01 +0200 Subject: [PATCH 11/31] Fix passing of callbacks --- client/ayon_core/hosts/maya/api/alembic.py | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client/ayon_core/hosts/maya/api/alembic.py b/client/ayon_core/hosts/maya/api/alembic.py index 3722774bba..e9bf6d71ca 100644 --- a/client/ayon_core/hosts/maya/api/alembic.py +++ b/client/ayon_core/hosts/maya/api/alembic.py @@ -54,9 +54,13 @@ def extract_alembic( endFrame=None, eulerFilter=True, frameRange="", + melPerFrameCallback=None, + melPostJobCallback=None, noNormals=False, preRoll=False, preRollStartFrame=0, + pythonPerFrameCallback=None, + pythonPostJobCallback=None, renderableOnly=False, root=None, selection=True, @@ -105,6 +109,11 @@ def extract_alembic( string formatted as: "startFrame endFrame". This argument overrides `startFrame` and `endFrame` arguments. + melPerFrameCallback (Optional[str]): MEL callback run per frame. + + melPostJobCallback (Optional[str]): MEL callback after last frame is + written. + noNormals (bool): When on, normal data from the original polygon objects is not included in the exported Alembic cache file. @@ -116,6 +125,11 @@ def extract_alembic( dependent translations and can be used to evaluate run-up that isn't actually translated. Defaults to 0. + pythonPerFrameCallback (Optional[str]): Python callback run per frame. + + pythonPostJobCallback (Optional[str]): Python callback after last frame + is written. + renderableOnly (bool): When on, any non-renderable nodes or hierarchy, such as hidden objects, are not included in the Alembic file. Defaults to False. @@ -282,6 +296,17 @@ def extract_alembic( if maya_version >= 2018: options['autoSubd'] = options.pop('writeCreases', False) + # Only add callbacks if they are set so that we're not passing `None` + callbacks = { + "melPerFrameCallback": melPerFrameCallback, + "melPostJobCallback": melPostJobCallback, + "pythonPerFrameCallback": pythonPerFrameCallback, + "pythonPostJobCallback": pythonPostJobCallback, + } + for key, callback in callbacks.items(): + if callback: + options[key] = str(callback) + # Format the job string from options job_args = list() for key, value in options.items(): From ba50a64a3842930ef77cf985093f139aa4cc1961 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:39:45 +0200 Subject: [PATCH 12/31] Remove debugging error --- .../ayon_core/hosts/maya/plugins/publish/extract_pointcache.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py index 3c0350ec65..05deaa0834 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py @@ -248,7 +248,6 @@ class ExtractAlembic(publish.Extractor, AYONPyblishPluginMixin): with maintained_selection(): cmds.select(instance.data["proxy"]) extract_alembic(**kwargs) - raise RuntimeError("FAIL") representation = { "name": "proxy", "ext": "abc", From 02ccceaf24caaa8ca52c447a21065001029fc57f Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 16:48:36 +0200 Subject: [PATCH 13/31] Bump Maya addon version --- server_addon/maya/package.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/package.py b/server_addon/maya/package.py index 5c6ce923aa..fe3e3039f5 100644 --- a/server_addon/maya/package.py +++ b/server_addon/maya/package.py @@ -1,3 +1,3 @@ name = "maya" title = "Maya" -version = "0.1.17" +version = "0.1.18" From 2bf6ed71156d912aa2ce4329e6091761fc47fd5b Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 17:18:23 +0200 Subject: [PATCH 14/31] Do not modify `roots` in-place so that `roots` remains the roots and doesn't contain the descendendants + ignore intermediate objects since they would not be exported anyway --- .../hosts/maya/plugins/publish/extract_pointcache.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py index 05deaa0834..cc930e49cc 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py +++ b/client/ayon_core/hosts/maya/plugins/publish/extract_pointcache.py @@ -6,6 +6,7 @@ from maya import cmds from ayon_core.pipeline import publish from ayon_core.hosts.maya.api.alembic import extract_alembic from ayon_core.hosts.maya.api.lib import ( + get_all_children, suspended_refresh, maintained_selection, iter_visible_nodes_in_range @@ -518,9 +519,7 @@ class ExtractAnimation(ExtractAlembic): roots = cmds.sets(out_set, query=True) or [] # Include all descendants - nodes = roots - nodes += cmds.listRelatives( - roots, allDescendents=True, fullPath=True - ) or [] + nodes = roots.copy() + nodes.extend(get_all_children(roots, ignore_intermediate_objects=True)) return nodes, roots From 1513660b7e842f31bc33bacf464e44ea0edc62b4 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 22:51:36 +0200 Subject: [PATCH 15/31] Pass `preRollStartFrame` as separate argument --- client/ayon_core/hosts/maya/api/alembic.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/hosts/maya/api/alembic.py b/client/ayon_core/hosts/maya/api/alembic.py index e9bf6d71ca..6bd00e1cb1 100644 --- a/client/ayon_core/hosts/maya/api/alembic.py +++ b/client/ayon_core/hosts/maya/api/alembic.py @@ -22,7 +22,6 @@ ALEMBIC_ARGS = { "melPostJobCallback": str, "noNormals": bool, "preRoll": bool, - "preRollStartFrame": int, "pythonPerFrameCallback": str, "pythonPostJobCallback": str, "renderableOnly": bool, @@ -259,8 +258,7 @@ def extract_alembic( "userAttr": userAttr, "userAttrPrefix": userAttrPrefix, "stripNamespaces": stripNamespaces, - "verbose": verbose, - "preRollStartFrame": preRollStartFrame + "verbose": verbose } # Validate options @@ -340,7 +338,11 @@ def extract_alembic( # exports are made. (PLN-31) # TODO: Make sure this actually fixes the issues with evaluation("off"): - cmds.AbcExport(j=job_str, verbose=verbose) + cmds.AbcExport( + j=job_str, + verbose=verbose, + preRollStartFrame=preRollStartFrame + ) if verbose: log.debug("Extracted Alembic to: %s", file) From 0e23615cbd037af3638972bf9694ebaa674989bd Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Wed, 1 May 2024 22:54:45 +0200 Subject: [PATCH 16/31] Enable uvWrite in settings by default --- server_addon/maya/server/settings/publishers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index 3a82d649e1..c3983e0067 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -1626,7 +1626,7 @@ DEFAULT_PUBLISH_SETTINGS = { "renderableOnly": False, "stripNamespaces": True, "uvsOnly": False, - "uvWrite": False, + "uvWrite": True, "userAttr": "", "userAttrPrefix": "", "verbose": False, From 99e5cf99602c3b2321445776bf63e6cefe85a19c Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 May 2024 16:49:23 +0200 Subject: [PATCH 17/31] Tweak the validation report --- .../validate_alembic_options_defaults.py | 37 +++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 476f837135..c19bc6a0f4 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -1,3 +1,4 @@ +import inspect import pyblish.api from ayon_core.pipeline import OptionalPyblishPluginMixin @@ -39,11 +40,11 @@ class ValidateAlembicDefaultsPointcache( attributes = self._get_publish_attributes(instance) msg = ( - "Alembic Extract setting \"{}\" is not the default value:" - "\nCurrent: {}" - "\nDefault Value: {}\n" + "Alembic extract setting \"{}\" is not the default value:" + "\n- Current: {}" + "\n- Default: {}\n" ) - errors = [] + invalid = False for key, value in attributes.items(): default_value = settings[key] @@ -54,10 +55,32 @@ class ValidateAlembicDefaultsPointcache( default_value = sorted(default_value) if value != default_value: - errors.append(msg.format(key, value, default_value)) + self.log.error( + msg.format(key, value, default_value) + ) + invalid = True - if errors: - raise PublishValidationError("\n".join(errors)) + if invalid: + raise PublishValidationError( + "Detected alembic options that differ from the default value.", + description=self.get_description() + ) + + @staticmethod + def get_description(): + return inspect.cleandoc( + """### Alembic Extract settings differ from defaults + + The alembic export options differ from the project default values. + + If this is intentional you can disable this validation by + disabling **Validate Alembic Options Default**. + + If not you may use the "Repair" action to revert all the options to + their default values. + + """ + ) @classmethod def repair(cls, instance): From 4ac8123cb92c0220781b5023b0616d01ce68e042 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 May 2024 16:57:17 +0200 Subject: [PATCH 18/31] Simplify messaging --- .../validate_alembic_options_defaults.py | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index c19bc6a0f4..800c05c8a6 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -39,12 +39,7 @@ class ValidateAlembicDefaultsPointcache( settings = self._get_settings(instance.context) attributes = self._get_publish_attributes(instance) - msg = ( - "Alembic extract setting \"{}\" is not the default value:" - "\n- Current: {}" - "\n- Default: {}\n" - ) - invalid = False + invalid = {} for key, value in attributes.items(): default_value = settings[key] @@ -55,14 +50,17 @@ class ValidateAlembicDefaultsPointcache( default_value = sorted(default_value) if value != default_value: - self.log.error( - msg.format(key, value, default_value) - ) - invalid = True + invalid[key] = value, default_value if invalid: + non_defaults = "\n".join( + f"- {key}: {value} \t(default: {default_value})" + for key, (value, default_value) in invalid.items() + ) + raise PublishValidationError( - "Detected alembic options that differ from the default value.", + "Alembic extract options differ from default values:\n" + f"{non_defaults}", description=self.get_description() ) From b4b1e2af4cab5b442ce84592f97b9c27b51b16b3 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 3 May 2024 17:02:26 +0200 Subject: [PATCH 19/31] Ignore attributes not found in settings with a warning --- .../publish/validate_alembic_options_defaults.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 800c05c8a6..0abb734c9b 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -41,6 +41,17 @@ class ValidateAlembicDefaultsPointcache( invalid = {} for key, value in attributes.items(): + if key not in settings: + # This may occur if attributes have changed over time and an + # existing instance has older legacy attributes that do not + # match the current settings definition. + self.log.warning( + "Publish attribute %s not found in Alembic Export " + "default settings. Ignoring validation for attribute.", + key + ) + continue + default_value = settings[key] # Lists are best to compared sorted since we cant rely on the order From bd1f7dce4a55407c3e200b84a64083957b9b3234 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Mon, 6 May 2024 23:52:18 +0200 Subject: [PATCH 20/31] Fix repair for instances with older publish attributes that mismatch settings --- .../publish/validate_alembic_options_defaults.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py index 0abb734c9b..11f4c313fa 100644 --- a/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py +++ b/client/ayon_core/hosts/maya/plugins/publish/validate_alembic_options_defaults.py @@ -100,11 +100,20 @@ class ValidateAlembicDefaultsPointcache( ) # Set the settings values on the create context then save to workfile. - attributes = cls._get_publish_attributes(instance) settings = cls._get_settings(instance.context) - create_publish_attributes = create_instance.data["publish_attributes"] + attributes = cls._get_publish_attributes(create_instance) for key in attributes: - create_publish_attributes[cls.plugin_name][key] = settings[key] + if key not in settings: + # This may occur if attributes have changed over time and an + # existing instance has older legacy attributes that do not + # match the current settings definition. + cls.log.warning( + "Publish attribute %s not found in Alembic Export " + "default settings. Ignoring repair for attribute.", + key + ) + continue + attributes[key] = settings[key] create_context.save_changes() From ab1b49b988183d0de95db27a249e89cfb59ed364 Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Thu, 29 Feb 2024 12:23:57 +1300 Subject: [PATCH 21/31] enhancement/AY-1456_double_click_at_instance_switch_to_publish_tab --- .../tools/publisher/widgets/card_view_widgets.py | 11 +++++++++++ .../tools/publisher/widgets/list_view_widgets.py | 6 ++++++ .../tools/publisher/widgets/overview_widget.py | 10 ++++++++++ 3 files changed, 27 insertions(+) diff --git a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py index 47c5399cf7..7d178e98e5 100644 --- a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py @@ -534,6 +534,8 @@ class InstanceCardView(AbstractInstanceView): Wrapper of all widgets in card view. """ + double_clicked = QtCore.Signal() + def __init__(self, controller, parent): super(InstanceCardView, self).__init__(parent) @@ -578,6 +580,9 @@ class InstanceCardView(AbstractInstanceView): self.sizePolicy().verticalPolicy() ) + def mouseDoubleClickEvent(self, event): + self.double_clicked.emit() + def sizeHint(self): """Modify sizeHint based on visibility of scroll bars.""" # Calculate width hint by content widget and vertical scroll bar @@ -715,6 +720,7 @@ class InstanceCardView(AbstractInstanceView): ) group_widget.active_changed.connect(self._on_active_changed) group_widget.selected.connect(self._on_widget_selection) + # group_widget.double_clicked.connect(self._on_widget_double_clicked) self._content_layout.insertWidget(widget_idx, group_widget) self._widgets_by_group[group_name] = group_widget @@ -825,6 +831,11 @@ class InstanceCardView(AbstractInstanceView): self.selection_changed.emit() + # def _on_widget_double_clicked(self): + # print("_on_widget_double_clicked") + # widgets = self._get_selected_widgets() + # print(widgets) + def _select_item_clear(self, instance_id, group_name, new_widget): """Select specific item by instance id and clear previous selection. diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index 3322a73be6..8dfabed8e9 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -425,6 +425,9 @@ class InstanceListView(AbstractInstanceView): This is public access to and from list view. """ + + double_clicked = QtCore.Signal() + def __init__(self, controller, parent): super(InstanceListView, self).__init__(parent) @@ -474,6 +477,9 @@ class InstanceListView(AbstractInstanceView): self._active_toggle_enabled = True + def mouseDoubleClickEvent(self, event): + self.double_clicked.emit() + def _on_expand(self, index): self._update_widget_expand_state(index, True) diff --git a/client/ayon_core/tools/publisher/widgets/overview_widget.py b/client/ayon_core/tools/publisher/widgets/overview_widget.py index dd82185830..82e4153681 100644 --- a/client/ayon_core/tools/publisher/widgets/overview_widget.py +++ b/client/ayon_core/tools/publisher/widgets/overview_widget.py @@ -113,9 +113,15 @@ class OverviewWidget(QtWidgets.QFrame): product_list_view.selection_changed.connect( self._on_product_change ) + product_list_view.double_clicked.connect( + self._on_double_clicked + ) product_view_cards.selection_changed.connect( self._on_product_change ) + product_view_cards.double_clicked.connect( + self._on_double_clicked + ) # Active instances changed product_list_view.active_changed.connect( self._on_active_changed @@ -293,6 +299,10 @@ class OverviewWidget(QtWidgets.QFrame): instances, context_selected, convertor_identifiers ) + def _on_double_clicked(self): + from ayon_core.tools.utils import host_tools + host_tools.show_publisher(tab="publish") + def _on_active_changed(self): if self._refreshing_instances: return From 427d36c5ac796fdb6993ae34483e8eebf06ff874 Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Thu, 29 Feb 2024 12:25:02 +1300 Subject: [PATCH 22/31] enhancement/AY-1456_double_click_at_instance_switch_to_publish_tab --- .../ayon_core/tools/publisher/widgets/card_view_widgets.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py index 7d178e98e5..d1d062c18f 100644 --- a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py @@ -720,7 +720,6 @@ class InstanceCardView(AbstractInstanceView): ) group_widget.active_changed.connect(self._on_active_changed) group_widget.selected.connect(self._on_widget_selection) - # group_widget.double_clicked.connect(self._on_widget_double_clicked) self._content_layout.insertWidget(widget_idx, group_widget) self._widgets_by_group[group_name] = group_widget @@ -831,11 +830,6 @@ class InstanceCardView(AbstractInstanceView): self.selection_changed.emit() - # def _on_widget_double_clicked(self): - # print("_on_widget_double_clicked") - # widgets = self._get_selected_widgets() - # print(widgets) - def _select_item_clear(self, instance_id, group_name, new_widget): """Select specific item by instance id and clear previous selection. From 58998d970c41d1a17275722c3eb97df7dd645325 Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Thu, 29 Feb 2024 15:25:43 +1300 Subject: [PATCH 23/31] enhancement/AY-1456_double_click_at_instance_switch_to_publish_tab --- client/ayon_core/tools/publisher/widgets/list_view_widgets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index 8dfabed8e9..90f5f3fab9 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -457,6 +457,7 @@ class InstanceListView(AbstractInstanceView): instance_view.collapsed.connect(self._on_collapse) instance_view.expanded.connect(self._on_expand) instance_view.toggle_requested.connect(self._on_toggle_request) + instance_view.doubleClicked.connect(self._on_double_clicked) self._group_items = {} self._group_widgets = {} @@ -477,7 +478,7 @@ class InstanceListView(AbstractInstanceView): self._active_toggle_enabled = True - def mouseDoubleClickEvent(self, event): + def _on_double_clicked(self, event): self.double_clicked.emit() def _on_expand(self, index): From 2f326c1467ca26dbedf76a56784d2a37b9dbf2b8 Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Tue, 5 Mar 2024 09:57:08 +1300 Subject: [PATCH 24/31] enhancement/AY-1456_double_click_at_instance_switch_to_publish_tab --- .../ayon_core/tools/publisher/widgets/list_view_widgets.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index 90f5f3fab9..7c4c07baea 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -457,7 +457,7 @@ class InstanceListView(AbstractInstanceView): instance_view.collapsed.connect(self._on_collapse) instance_view.expanded.connect(self._on_expand) instance_view.toggle_requested.connect(self._on_toggle_request) - instance_view.doubleClicked.connect(self._on_double_clicked) + instance_view.doubleClicked.connect(self.double_clicked) self._group_items = {} self._group_widgets = {} @@ -478,9 +478,6 @@ class InstanceListView(AbstractInstanceView): self._active_toggle_enabled = True - def _on_double_clicked(self, event): - self.double_clicked.emit() - def _on_expand(self, index): self._update_widget_expand_state(index, True) From dd776b728ba510283ea17b96dc6b65fa65a8809e Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Tue, 5 Mar 2024 10:02:23 +1300 Subject: [PATCH 25/31] enhancement/AY-1456_double_click_at_instance_switch_to_publish_tab --- .../ayon_core/tools/publisher/widgets/overview_widget.py | 9 +++------ client/ayon_core/tools/publisher/window.py | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/overview_widget.py b/client/ayon_core/tools/publisher/widgets/overview_widget.py index 82e4153681..cedf52ae01 100644 --- a/client/ayon_core/tools/publisher/widgets/overview_widget.py +++ b/client/ayon_core/tools/publisher/widgets/overview_widget.py @@ -18,6 +18,7 @@ class OverviewWidget(QtWidgets.QFrame): instance_context_changed = QtCore.Signal() create_requested = QtCore.Signal() convert_requested = QtCore.Signal() + publish_tab_requested = QtCore.Signal() anim_end_value = 200 anim_duration = 200 @@ -114,13 +115,13 @@ class OverviewWidget(QtWidgets.QFrame): self._on_product_change ) product_list_view.double_clicked.connect( - self._on_double_clicked + self.publish_tab_requested ) product_view_cards.selection_changed.connect( self._on_product_change ) product_view_cards.double_clicked.connect( - self._on_double_clicked + self.publish_tab_requested ) # Active instances changed product_list_view.active_changed.connect( @@ -299,10 +300,6 @@ class OverviewWidget(QtWidgets.QFrame): instances, context_selected, convertor_identifiers ) - def _on_double_clicked(self): - from ayon_core.tools.utils import host_tools - host_tools.show_publisher(tab="publish") - def _on_active_changed(self): if self._refreshing_instances: return diff --git a/client/ayon_core/tools/publisher/window.py b/client/ayon_core/tools/publisher/window.py index 123864ff6c..1b13ced317 100644 --- a/client/ayon_core/tools/publisher/window.py +++ b/client/ayon_core/tools/publisher/window.py @@ -258,6 +258,9 @@ class PublisherWindow(QtWidgets.QDialog): overview_widget.convert_requested.connect( self._on_convert_requested ) + overview_widget.publish_tab_requested.connect( + self._go_to_publish_tab + ) save_btn.clicked.connect(self._on_save_clicked) reset_btn.clicked.connect(self._on_reset_clicked) From b8f0d590f16cf0d7a6e4add5daef27cfb5140a1e Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Mon, 11 Mar 2024 10:30:42 +1300 Subject: [PATCH 26/31] right clicking tree view doen't switch tab --- .../tools/publisher/widgets/card_view_widgets.py | 3 ++- .../tools/publisher/widgets/list_view_widgets.py | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py index d1d062c18f..28ed237fe6 100644 --- a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py @@ -581,7 +581,8 @@ class InstanceCardView(AbstractInstanceView): ) def mouseDoubleClickEvent(self, event): - self.double_clicked.emit() + if event.button() == QtCore.Qt.LeftButton: + self.double_clicked.emit() def sizeHint(self): """Modify sizeHint based on visibility of scroll bars.""" diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index 7c4c07baea..eb5f41be4a 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -379,7 +379,7 @@ class InstanceTreeView(QtWidgets.QTreeView): "double click" as 2x "single click". """ if event.button() != QtCore.Qt.LeftButton: - return + return False pressed_group_index = None pos_index = self.indexAt(event.pos()) @@ -388,13 +388,17 @@ class InstanceTreeView(QtWidgets.QTreeView): self._pressed_group_index = pressed_group_index + return True + def mousePressEvent(self, event): - self._mouse_press(event) - super(InstanceTreeView, self).mousePressEvent(event) + handled = self._mouse_press(event) + if handled: + super(InstanceTreeView, self).mousePressEvent(event) def mouseDoubleClickEvent(self, event): - self._mouse_press(event) - super(InstanceTreeView, self).mouseDoubleClickEvent(event) + handled = self._mouse_press(event) + if handled: + super(InstanceTreeView, self).mouseDoubleClickEvent(event) def _mouse_release(self, event, pressed_index): if event.button() != QtCore.Qt.LeftButton: From 7c028a752cd012e9914c1d3a29829869708c032c Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Mon, 11 Mar 2024 10:52:27 +1300 Subject: [PATCH 27/31] clicking in empty area in tree view should switch tab --- client/ayon_core/tools/publisher/widgets/list_view_widgets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index eb5f41be4a..f142faff83 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -317,6 +317,7 @@ class InstanceListGroupWidget(QtWidgets.QFrame): class InstanceTreeView(QtWidgets.QTreeView): """View showing instances and their groups.""" toggle_requested = QtCore.Signal(int) + double_clicked = QtCore.Signal() def __init__(self, *args, **kwargs): super(InstanceTreeView, self).__init__(*args, **kwargs) @@ -396,6 +397,7 @@ class InstanceTreeView(QtWidgets.QTreeView): super(InstanceTreeView, self).mousePressEvent(event) def mouseDoubleClickEvent(self, event): + self.double_clicked.emit() handled = self._mouse_press(event) if handled: super(InstanceTreeView, self).mouseDoubleClickEvent(event) @@ -461,7 +463,7 @@ class InstanceListView(AbstractInstanceView): instance_view.collapsed.connect(self._on_collapse) instance_view.expanded.connect(self._on_expand) instance_view.toggle_requested.connect(self._on_toggle_request) - instance_view.doubleClicked.connect(self.double_clicked) + instance_view.double_clicked.connect(self.double_clicked) self._group_items = {} self._group_widgets = {} From 55256d59a3ad315974ce3a6aa9f70d00e26561af Mon Sep 17 00:00:00 2001 From: Braden Jennings Date: Mon, 11 Mar 2024 10:56:15 +1300 Subject: [PATCH 28/31] clicking in empty area in tree view should switch tab --- client/ayon_core/tools/publisher/widgets/list_view_widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index f142faff83..6a7335bd74 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -397,9 +397,9 @@ class InstanceTreeView(QtWidgets.QTreeView): super(InstanceTreeView, self).mousePressEvent(event) def mouseDoubleClickEvent(self, event): - self.double_clicked.emit() handled = self._mouse_press(event) if handled: + self.double_clicked.emit() super(InstanceTreeView, self).mouseDoubleClickEvent(event) def _mouse_release(self, event, pressed_index): From e2849b83e0fbb3d90edf637b3a3161172facecf8 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 9 May 2024 10:58:24 +0200 Subject: [PATCH 29/31] card widgets can tell if they should trigger double click --- .../publisher/widgets/card_view_widgets.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py index 28ed237fe6..4e34f9b58c 100644 --- a/client/ayon_core/tools/publisher/widgets/card_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/card_view_widgets.py @@ -52,6 +52,7 @@ class SelectionTypes: class BaseGroupWidget(QtWidgets.QWidget): selected = QtCore.Signal(str, str, str) removed_selected = QtCore.Signal() + double_clicked = QtCore.Signal() def __init__(self, group_name, parent): super(BaseGroupWidget, self).__init__(parent) @@ -192,6 +193,7 @@ class ConvertorItemsGroupWidget(BaseGroupWidget): else: widget = ConvertorItemCardWidget(item, self) widget.selected.connect(self._on_widget_selection) + widget.double_clicked(self.double_clicked) self._widgets_by_id[item.id] = widget self._content_layout.insertWidget(widget_idx, widget) widget_idx += 1 @@ -254,6 +256,7 @@ class InstanceGroupWidget(BaseGroupWidget): ) widget.selected.connect(self._on_widget_selection) widget.active_changed.connect(self._on_active_changed) + widget.double_clicked.connect(self.double_clicked) self._widgets_by_id[instance.id] = widget self._content_layout.insertWidget(widget_idx, widget) widget_idx += 1 @@ -271,6 +274,7 @@ class CardWidget(BaseClickableFrame): # Group identifier of card # - this must be set because if send when mouse is released with card id _group_identifier = None + double_clicked = QtCore.Signal() def __init__(self, parent): super(CardWidget, self).__init__(parent) @@ -279,6 +283,11 @@ class CardWidget(BaseClickableFrame): self._selected = False self._id = None + def mouseDoubleClickEvent(self, event): + super(CardWidget, self).mouseDoubleClickEvent(event) + if self._is_valid_double_click(event): + self.double_clicked.emit() + @property def id(self): """Id of card.""" @@ -312,6 +321,9 @@ class CardWidget(BaseClickableFrame): self.selected.emit(self._id, self._group_identifier, selection_type) + def _is_valid_double_click(self, event): + return True + class ContextCardWidget(CardWidget): """Card for global context. @@ -527,6 +539,15 @@ class InstanceCardWidget(CardWidget): def _on_expend_clicked(self): self._set_expanded() + def _is_valid_double_click(self, event): + widget = self.childAt(event.pos()) + if ( + widget is self._active_checkbox + or widget is self._expand_btn + ): + return False + return True + class InstanceCardView(AbstractInstanceView): """Publish access to card view. @@ -580,10 +601,6 @@ class InstanceCardView(AbstractInstanceView): self.sizePolicy().verticalPolicy() ) - def mouseDoubleClickEvent(self, event): - if event.button() == QtCore.Qt.LeftButton: - self.double_clicked.emit() - def sizeHint(self): """Modify sizeHint based on visibility of scroll bars.""" # Calculate width hint by content widget and vertical scroll bar @@ -721,6 +738,7 @@ class InstanceCardView(AbstractInstanceView): ) group_widget.active_changed.connect(self._on_active_changed) group_widget.selected.connect(self._on_widget_selection) + group_widget.double_clicked.connect(self.double_clicked) self._content_layout.insertWidget(widget_idx, group_widget) self._widgets_by_group[group_name] = group_widget @@ -761,6 +779,7 @@ class InstanceCardView(AbstractInstanceView): widget = ContextCardWidget(self._content_widget) widget.selected.connect(self._on_widget_selection) + widget.double_clicked.connect(self.double_clicked) self._context_widget = widget @@ -784,6 +803,7 @@ class InstanceCardView(AbstractInstanceView): CONVERTOR_ITEM_GROUP, self._content_widget ) group_widget.selected.connect(self._on_widget_selection) + group_widget.double_clicked.connect(self.double_clicked) self._content_layout.insertWidget(1, group_widget) self._convertor_items_group = group_widget From 8b17cf5485c52bf72c5b624ee4a1c9788f83fe92 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 9 May 2024 10:58:48 +0200 Subject: [PATCH 30/31] list view widgets can tell if should trigger double click --- .../publisher/widgets/list_view_widgets.py | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index 6a7335bd74..aa8f26998a 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -110,6 +110,7 @@ class InstanceListItemWidget(QtWidgets.QWidget): This is required to be able use custom checkbox on custom place. """ active_changed = QtCore.Signal(str, bool) + double_clicked = QtCore.Signal() def __init__(self, instance, parent): super(InstanceListItemWidget, self).__init__(parent) @@ -149,6 +150,12 @@ class InstanceListItemWidget(QtWidgets.QWidget): self._set_valid_property(instance.has_valid_context) + def mouseDoubleClickEvent(self, event): + widget = self.childAt(event.pos()) + super(InstanceListItemWidget, self).mouseDoubleClickEvent(event) + if widget is not self._active_checkbox: + self.double_clicked.emit() + def _set_valid_property(self, valid): if self._has_valid_context == valid: return @@ -209,6 +216,8 @@ class InstanceListItemWidget(QtWidgets.QWidget): class ListContextWidget(QtWidgets.QFrame): """Context (or global attributes) widget.""" + double_clicked = QtCore.Signal() + def __init__(self, parent): super(ListContextWidget, self).__init__(parent) @@ -225,6 +234,10 @@ class ListContextWidget(QtWidgets.QFrame): self.label_widget = label_widget + def mouseDoubleClickEvent(self, event): + super(ListContextWidget, self).mouseDoubleClickEvent(event) + self.double_clicked.emit() + class InstanceListGroupWidget(QtWidgets.QFrame): """Widget representing group of instances. @@ -392,15 +405,12 @@ class InstanceTreeView(QtWidgets.QTreeView): return True def mousePressEvent(self, event): - handled = self._mouse_press(event) - if handled: - super(InstanceTreeView, self).mousePressEvent(event) + self._mouse_press(event) + super(InstanceTreeView, self).mousePressEvent(event) def mouseDoubleClickEvent(self, event): - handled = self._mouse_press(event) - if handled: - self.double_clicked.emit() - super(InstanceTreeView, self).mouseDoubleClickEvent(event) + self._mouse_press(event) + super(InstanceTreeView, self).mouseDoubleClickEvent(event) def _mouse_release(self, event, pressed_index): if event.button() != QtCore.Qt.LeftButton: @@ -697,6 +707,7 @@ class InstanceListView(AbstractInstanceView): self._active_toggle_enabled ) widget.active_changed.connect(self._on_active_changed) + widget.double_clicked.connect(self.double_clicked) self._instance_view.setIndexWidget(proxy_index, widget) self._widgets_by_id[instance.id] = widget @@ -727,6 +738,7 @@ class InstanceListView(AbstractInstanceView): ) proxy_index = self._proxy_model.mapFromSource(index) widget = ListContextWidget(self._instance_view) + widget.double_clicked.connect(self.double_clicked) self._instance_view.setIndexWidget(proxy_index, widget) self._context_widget = widget From 168f8cdcc20435105bcf2f73bbca0ea22b08b298 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Thu, 9 May 2024 10:59:05 +0200 Subject: [PATCH 31/31] revert output of '_mouse_press' --- client/ayon_core/tools/publisher/widgets/list_view_widgets.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py index aa8f26998a..71be0ab1a4 100644 --- a/client/ayon_core/tools/publisher/widgets/list_view_widgets.py +++ b/client/ayon_core/tools/publisher/widgets/list_view_widgets.py @@ -393,7 +393,7 @@ class InstanceTreeView(QtWidgets.QTreeView): "double click" as 2x "single click". """ if event.button() != QtCore.Qt.LeftButton: - return False + return pressed_group_index = None pos_index = self.indexAt(event.pos()) @@ -402,8 +402,6 @@ class InstanceTreeView(QtWidgets.QTreeView): self._pressed_group_index = pressed_group_index - return True - def mousePressEvent(self, event): self._mouse_press(event) super(InstanceTreeView, self).mousePressEvent(event)