enable the skeleton rig content validator and make the fbx animation collector optional and use the asset as both asset_name and asset_type data for custom subset in the loader

This commit is contained in:
Kayla 2023-09-20 21:26:02 +08:00
parent 7252acceb8
commit b7995a41a7
9 changed files with 72 additions and 31 deletions

View file

@ -4113,6 +4113,7 @@ def create_rig_animation_instance(
node.endswith("skeletonAnim_SET")), None)
if not anim_skeleton:
log.debug("No skeletonAnim_SET in rig")
skeleton_mesh = next((node for node in nodes if
node.endswith("skeletonMesh_SET")), None)
if not skeleton_mesh:
@ -4128,8 +4129,9 @@ def create_rig_animation_instance(
if custom_subset:
formatting_data = {
# TODO remove 'asset_type' and replace 'asset_name' with 'asset'
"asset_name": context['asset']['name'],
"asset_type": context['asset']['type'],
# "asset_name": context['asset']['name'],
# "asset_type": context['asset']['type'],
"asset": context["asset"],
"subset": context['subset']['name'],
"family": (
context['subset']['data'].get('family') or

View file

@ -1,17 +1,22 @@
# -*- coding: utf-8 -*-
from maya import cmds # noqa
import pyblish.api
from openpype.lib import BoolDef
from openpype.pipeline import OptionalPyblishPluginMixin
class CollectFbxAnimation(pyblish.api.InstancePlugin):
class CollectFbxAnimation(pyblish.api.InstancePlugin,
OptionalPyblishPluginMixin):
"""Collect Animated Rig Data for FBX Extractor."""
order = pyblish.api.CollectorOrder + 0.2
label = "Collect Fbx Animation"
hosts = ["maya"]
families = ["animation"]
optional = True
def process(self, instance):
if not self.is_active(instance.data):
return
skeleton_sets = [
i for i in instance
if i.lower().endswith("skeletonanim_set")

View file

@ -29,6 +29,7 @@ class CollectSkeletonMesh(pyblish.api.InstancePlugin):
"no skeleton_set or skeleton_mesh set was found....")
return
instance.data["skeleton_mesh"] = []
instance.data["skeleton_rig"] = []
if skeleton_mesh_sets:
instance.data["families"] += ["rig.fbx"]
@ -40,3 +41,12 @@ class CollectSkeletonMesh(pyblish.api.InstancePlugin):
self.log.debug(
"Collected skeleton "
f"mesh Set: {skeleton_mesh_content}")
if skeleton_sets:
for skeleton_set in skeleton_sets:
skeleton_content = cmds.sets(skeleton_set, query=True)
self.log.debug(
"Collected animated "
f"skeleton data: {skeleton_content}")
if skeleton_content:
instance.data["skeleton_rig"] += skeleton_content

View file

@ -5,12 +5,10 @@ from maya import cmds # noqa
import pyblish.api
from openpype.pipeline import publish
from openpype.pipeline.publish import OptionalPyblishPluginMixin
from openpype.hosts.maya.api import fbx
class ExtractRigFBX(publish.Extractor,
OptionalPyblishPluginMixin):
class ExtractFBXAnimation(publish.Extractor):
"""Extract Rig in FBX format from Maya.
This extracts the rig in fbx with the constraints
@ -25,8 +23,6 @@ class ExtractRigFBX(publish.Extractor,
families = ["animation.fbx"]
def process(self, instance):
if not self.is_active(instance.data):
return
# Define output path
staging_dir = self.staging_dir(instance)
filename = "{0}.fbx".format(instance.name)

View file

@ -12,7 +12,8 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
The rigs optionally contain at least two object sets:
"skeletonAnim_SET" - Set of only bone hierarchies
"skeletonMesh_SET" - Set of all cacheable meshes
"skeletonMesh_SET" - Set of the skinned meshes
with bone hierarchies
"""
@ -21,11 +22,10 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
hosts = ["maya"]
families = ["rig.fbx"]
accepted_output = ["mesh", "transform"]
accepted_controllers = ["transform"]
accepted_output = ["mesh", "transform", "locator"]
accepted_controllers = ["transform", "locator"]
def process(self, instance):
objectsets = ["skeletonAnim_SET", "skeletonMesh_SET"]
missing = [
key for key in objectsets if key not in instance.data["rig_sets"]
@ -36,8 +36,8 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
)
return
controls_set = instance.data["rig_sets"]["skeletonAnim_SET"]
out_set = instance.data["rig_sets"]["skeletonMesh_SET"]
skeleton_anim_set = instance.data["rig_sets"]["skeletonAnim_SET"]
skeleton_mesh_set = instance.data["rig_sets"]["skeletonMesh_SET"]
# Ensure there are at least some transforms or dag nodes
# in the rig instance
set_members = instance.data['setMembers']
@ -45,13 +45,13 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
self.log.debug("Skipping empty instance...")
return
# Ensure contents in sets and retrieve long path for all objects
output_content = cmds.sets(
out_set, query=True) or []
output_content = cmds.ls(output_content, long=True)
skeleton_mesh_content = cmds.sets(
skeleton_mesh_set, query=True) or []
skeleton_mesh_content = cmds.ls(skeleton_mesh_content, long=True)
controls_content = cmds.sets(
controls_set, query=True) or []
controls_content = cmds.ls(controls_content, long=True)
skeleton_anim_content = cmds.sets(
skeleton_anim_set, query=True) or []
skeleton_anim_content = cmds.ls(skeleton_anim_content, long=True)
# Validate members are inside the hierarchy from root node
root_node = cmds.ls(set_members, assemblies=True)
@ -60,16 +60,16 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
hierarchy = set(hierarchy)
invalid_hierarchy = []
if output_content:
for node in output_content:
if skeleton_mesh_content:
for node in skeleton_mesh_content:
if node not in hierarchy:
invalid_hierarchy.append(node)
invalid_geometry = self.validate_geometry(output_content)
if controls_content:
for node in controls_content:
invalid_geometry = self.validate_geometry(skeleton_mesh_content)
if skeleton_anim_content:
for node in skeleton_anim_content:
if node not in hierarchy:
invalid_hierarchy.append(node)
invalid_controls = self.validate_controls(controls_content)
invalid_controls = self.validate_controls(skeleton_anim_content)
error = False
if invalid_hierarchy:
@ -99,7 +99,7 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
Checks if the node types of the set members valid
Args:
set_members: list of nodes of the controls_SET
set_members: list of nodes of the skeleton_mesh_set
hierarchy: list of nodes which reside under the root node
Returns:
@ -126,7 +126,7 @@ class ValidateSkeletonRigContents(pyblish.api.InstancePlugin):
Checks if the node types of the set members valid
Args:
set_members: list of nodes of the controls_SET
set_members: list of nodes of the skeleton_anim_set
hierarchy: list of nodes which reside under the root node
Returns:

View file

@ -707,6 +707,9 @@
"CollectMayaRender": {
"sync_workfile_version": false
},
"CollectFbxAnimation": {
"enabled": true
},
"CollectFbxCamera": {
"enabled": false
},
@ -1141,7 +1144,7 @@
"active": true
},
"ValidateSkeletonRigContents": {
"enabled": false,
"enabled": true,
"optional": true,
"active": true
},

View file

@ -21,6 +21,20 @@
}
]
},
{
"type": "dict",
"collapsible": true,
"key": "CollectFbxAnimation",
"label": "Collect Fbx Animation",
"checkbox_key": "enabled",
"children": [
{
"type": "boolean",
"key": "enabled",
"label": "Enabled"
}
]
},
{
"type": "dict",
"collapsible": true,

View file

@ -129,6 +129,10 @@ class CollectMayaRenderModel(BaseSettingsModel):
)
class CollectFbxAnimationModel(BaseSettingsModel):
enabled: bool = Field(title="Collect Fbx Animation")
class CollectFbxCameraModel(BaseSettingsModel):
enabled: bool = Field(title="CollectFbxCamera")
@ -364,6 +368,10 @@ class PublishersModel(BaseSettingsModel):
title="Collect Render Layers",
section="Collectors"
)
CollectFbxAnimation: CollectFbxAnimationModel = Field(
default_factory=CollectFbxAnimationModel,
title="Collect FBX Animation",
)
CollectFbxCamera: CollectFbxCameraModel = Field(
default_factory=CollectFbxCameraModel,
title="Collect Camera for FBX export",
@ -768,6 +776,9 @@ DEFAULT_PUBLISH_SETTINGS = {
"CollectMayaRender": {
"sync_workfile_version": False
},
"CollectFbxAnimation": {
"enabled": True
},
"CollectFbxCamera": {
"enabled": False
},
@ -1184,7 +1195,7 @@ DEFAULT_PUBLISH_SETTINGS = {
"active": True
},
"ValidateSkeletonRigContents": {
"enabled": False,
"enabled": True,
"optional": True,
"active": True
},