From e64984d510d84afb238df73296d8320cb3de2f3a Mon Sep 17 00:00:00 2001 From: Kayla Man Date: Wed, 13 Sep 2023 13:34:44 +0800 Subject: [PATCH] update fbx param to support skeleton definition exports and add the optional validators to make sure it's always a top group hierarchy of the rig in the sets --- openpype/hosts/maya/api/fbx.py | 8 +-- .../plugins/publish/collect_rig_for_fbx.py | 3 +- .../plugins/publish/extract_fbx_animation.py | 1 + .../maya/plugins/publish/extract_rig_fbx.py | 3 +- .../validate_skeleton_top_group_hierarchy.py | 49 +++++++++++++++++++ .../schemas/schema_maya_publish.json | 4 ++ .../maya/server/settings/publishers.py | 9 ++++ 7 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 openpype/hosts/maya/plugins/publish/validate_skeleton_top_group_hierarchy.py diff --git a/openpype/hosts/maya/api/fbx.py b/openpype/hosts/maya/api/fbx.py index 18b28f5154..306b7efe0b 100644 --- a/openpype/hosts/maya/api/fbx.py +++ b/openpype/hosts/maya/api/fbx.py @@ -40,7 +40,7 @@ class FBXExtractor: the option is not included and a warning is logged. """ - + #TODO: add skeletonDefinition return { "cameras": bool, "smoothingGroups": bool, @@ -65,7 +65,8 @@ class FBXExtractor: "inputConnections": bool, "upAxis": str, # x, y or z, "triangulate": bool, - "FileVersion": str + "FileVersion": str, + "skeletonDefinitions": bool } @property @@ -107,7 +108,8 @@ class FBXExtractor: "inputConnections": True, "upAxis": "y", "triangulate": False, - "fileVersion": "FBX202000" + "fileVersion": "FBX202000", + "skeletonDefinitions": False } def __init__(self, log=None): diff --git a/openpype/hosts/maya/plugins/publish/collect_rig_for_fbx.py b/openpype/hosts/maya/plugins/publish/collect_rig_for_fbx.py index d571975438..c9f3fea027 100644 --- a/openpype/hosts/maya/plugins/publish/collect_rig_for_fbx.py +++ b/openpype/hosts/maya/plugins/publish/collect_rig_for_fbx.py @@ -33,7 +33,8 @@ class CollectRigFbx(pyblish.api.InstancePlugin): skeleton_content = cmds.sets(skeleton_set, query=True) if skeleton_content: instance.data["animated_rigs"] += skeleton_content - self.log.debug(f"Collected skeleton data: {skeleton_content}") + self.log.debug("Collected skeleton" + f" data: {skeleton_content}") if skeleton_mesh_sets: instance.data["families"].append("rig.fbx") for skeleton_mesh_set in skeleton_mesh_sets: diff --git a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py index 2ac4734d21..b35cfbc271 100644 --- a/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py +++ b/openpype/hosts/maya/plugins/publish/extract_fbx_animation.py @@ -42,6 +42,7 @@ class ExtractRigFBX(publish.Extractor, out_set = instance.data.get("animated_skeleton", []) instance.data["constraints"] = True + instance.data["skeletonDefinitions"] = True instance.data["animationOnly"] = True fbx_exporter.set_options_from_instance(instance) diff --git a/openpype/hosts/maya/plugins/publish/extract_rig_fbx.py b/openpype/hosts/maya/plugins/publish/extract_rig_fbx.py index 0df602fa29..122cfecf3c 100644 --- a/openpype/hosts/maya/plugins/publish/extract_rig_fbx.py +++ b/openpype/hosts/maya/plugins/publish/extract_rig_fbx.py @@ -42,6 +42,7 @@ class ExtractRigFBX(publish.Extractor, out_set = instance.data.get("skeleton_mesh", []) instance.data["constraints"] = True + instance.data["skeletonDefinitions"] = True fbx_exporter.set_options_from_instance(instance) @@ -50,7 +51,6 @@ class ExtractRigFBX(publish.Extractor, if "representations" not in instance.data: instance.data["representations"] = [] - self.log.debug("Families: {}".format(instance.data["families"])) representation = { 'name': 'fbx', @@ -59,6 +59,5 @@ class ExtractRigFBX(publish.Extractor, "stagingDir": staging_dir, } instance.data["representations"].append(representation) - self.log.debug("Representation: {}".format(representation)) self.log.debug("Extract FBX successful to: {0}".format(path)) diff --git a/openpype/hosts/maya/plugins/publish/validate_skeleton_top_group_hierarchy.py b/openpype/hosts/maya/plugins/publish/validate_skeleton_top_group_hierarchy.py new file mode 100644 index 0000000000..df434f132d --- /dev/null +++ b/openpype/hosts/maya/plugins/publish/validate_skeleton_top_group_hierarchy.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +"""Plugin for validating naming conventions.""" +from maya import cmds + +import pyblish.api + +from openpype.pipeline.publish import ( + ValidateContentsOrder, + OptionalPyblishPluginMixin, + PublishValidationError +) + + +class ValidateSkeletonTopGroupHierarchy(pyblish.api.InstancePlugin, + OptionalPyblishPluginMixin): + """Validates top group hierarchy in the SETs + Make sure the object inside the SETs are always top + group of the hierarchy + + """ + order = ValidateContentsOrder + 0.05 + label = "Top Group Hierarchy" + families = ["rig"] + + def process(self, instance): + invalid = [] + skeleton_data = instance.data.get(("animated_rigs"), []) + skeletonMesh_data = instance.data(("skeleton_mesh"), []) + if skeleton_data: + invalid = self.get_top_hierarchy(skeleton_data) + if invalid: + raise PublishValidationError( + "The set includes the object which " + f"is not at the top hierarchy: {invalid}") + if skeletonMesh_data: + invalid = self.get_top_hierarchy(skeletonMesh_data) + if invalid: + raise PublishValidationError( + "The set includes the object which " + f"is not at the top hierarchy: {invalid}") + + def get_top_hierarchy(self, targets): + non_top_hierarchy_list = [] + for target in targets: + long_names = cmds.ls(target, long=True) + for name in long_names: + if len(name.split["|"]) > 2: + non_top_hierarchy_list.append(name) + return non_top_hierarchy_list diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json index e8300282d7..e5fe367e77 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_maya_publish.json @@ -824,6 +824,10 @@ { "key": "ValidateSkeletonRigOutputIds", "label": "Validate Skeleton Rig Output Ids" + }, + { + "key": "ValidateSkeletonTopGroupHierarchy", + "label": "Validate Skeleton Top Group Hierarchy" } ] }, diff --git a/server_addon/maya/server/settings/publishers.py b/server_addon/maya/server/settings/publishers.py index 6e3179b78e..0c733d9cbc 100644 --- a/server_addon/maya/server/settings/publishers.py +++ b/server_addon/maya/server/settings/publishers.py @@ -676,6 +676,10 @@ class PublishersModel(BaseSettingsModel): default_factory=BasicValidateModel, title="Validate Skeleton Rig Output Ids" ) + ValidateSkeletonTopGroupHierarchy: BasicValidateModel = Field( + default_factory=BasicValidateModel, + title="Validate Skeleton Top Group Hierarchy", + ) ValidateRigOutSetNodeIds: ValidateRigOutSetNodeIdsModel = Field( default_factory=ValidateRigOutSetNodeIdsModel, title="Validate Rig Out Set Node Ids", @@ -1209,6 +1213,11 @@ DEFAULT_PUBLISH_SETTINGS = { "optional": True, "active": True }, + "ValidateSkeletonTopGroupHierarchy": { + "enabled": False, + "optional": True, + "active": True + }, "ValidateCameraAttributes": { "enabled": False, "optional": True,