From 082fb1d29dfe151809c8a63767a9fc941462a23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Wed, 8 Jun 2022 12:09:13 +0200 Subject: [PATCH 1/4] :sparkles: settings for camera content validator --- .../publish/validate_camera_contents.py | 3 +++ .../defaults/project_settings/maya.json | 5 ++++ .../schemas/schema_maya_publish.json | 24 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py index 20af8d2315..38cf65f006 100644 --- a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py @@ -20,6 +20,7 @@ class ValidateCameraContents(pyblish.api.InstancePlugin): hosts = ['maya'] label = 'Camera Contents' actions = [openpype.hosts.maya.api.action.SelectInvalidAction] + validate_shapes = True @classmethod def get_invalid(cls, instance): @@ -49,6 +50,8 @@ class ValidateCameraContents(pyblish.api.InstancePlugin): raise RuntimeError("No cameras found in empty instance.") + if not cls.validate_shapes: + return # non-camera shapes valid_shapes = cmds.ls(shapes, type=('camera', 'locator'), long=True) shapes = set(shapes) - set(valid_shapes) diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index efd22e13c8..b39beeb305 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -413,6 +413,11 @@ "optional": true, "active": true }, + "ValidateCameraContents": { + "enabled": true, + "optional": true, + "validate_shapes": true + }, "ExtractPlayblast": { "capture_preset": { "Codec": { 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 9877b5ff0d..dca0e85acb 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 @@ -570,6 +570,30 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "key": "ValidateCameraContents", + "label": "Validate Camera Content", + "checkbox_key": "enabled", + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "boolean", + "key": "validate_shapes", + "label": "Validate presence of shapes" + } + ] + }, { "type": "splitter" }, From ca6d77fff79edd8d7073b6b36ce17990ce22edc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Wed, 8 Jun 2022 16:25:51 +0200 Subject: [PATCH 2/4] :art: modify camera extractor to allow more data --- .../plugins/publish/extract_camera_alembic.py | 17 +++++++++----- .../publish/extract_camera_mayaScene.py | 22 ++++++++++++++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/extract_camera_alembic.py b/openpype/hosts/maya/plugins/publish/extract_camera_alembic.py index 5ad6b79d5c..4110ad474d 100644 --- a/openpype/hosts/maya/plugins/publish/extract_camera_alembic.py +++ b/openpype/hosts/maya/plugins/publish/extract_camera_alembic.py @@ -34,7 +34,6 @@ class ExtractCameraAlembic(openpype.api.Extractor): dag=True, type="camera") # validate required settings - assert len(cameras) == 1, "Not a single camera found in extraction" assert isinstance(step, float), "Step must be a float value" camera = cameras[0] @@ -44,8 +43,12 @@ class ExtractCameraAlembic(openpype.api.Extractor): path = os.path.join(dir_path, filename) # Perform alembic extraction + member_shapes = cmds.ls( + members, leaf=True, shapes=True, long=True, dag=True) with lib.maintained_selection(): - cmds.select(camera, replace=True, noExpand=True) + cmds.select( + member_shapes, + replace=True, noExpand=True) # Enforce forward slashes for AbcExport because we're # embedding it into a job string @@ -57,10 +60,12 @@ class ExtractCameraAlembic(openpype.api.Extractor): job_str += ' -step {0} '.format(step) if bake_to_worldspace: - transform = cmds.listRelatives(camera, - parent=True, - fullPath=True)[0] - job_str += ' -worldSpace -root {0}'.format(transform) + job_str += ' -worldSpace' + for member in member_shapes: + self.log.info(f"processing {member}") + transform = cmds.listRelatives( + member, parent=True, fullPath=True)[0] + job_str += ' -root {0}'.format(transform) job_str += ' -file "{0}"'.format(path) diff --git a/openpype/hosts/maya/plugins/publish/extract_camera_mayaScene.py b/openpype/hosts/maya/plugins/publish/extract_camera_mayaScene.py index 49c156f9cd..1cb30e65ea 100644 --- a/openpype/hosts/maya/plugins/publish/extract_camera_mayaScene.py +++ b/openpype/hosts/maya/plugins/publish/extract_camera_mayaScene.py @@ -131,12 +131,12 @@ class ExtractCameraMayaScene(openpype.api.Extractor): "bake to world space is ignored...") # get cameras - members = instance.data['setMembers'] + members = cmds.ls(instance.data['setMembers'], leaf=True, shapes=True, + long=True, dag=True) cameras = cmds.ls(members, leaf=True, shapes=True, long=True, dag=True, type="camera") # validate required settings - 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) @@ -158,15 +158,24 @@ class ExtractCameraMayaScene(openpype.api.Extractor): frame_range=[start, end], step=step ) - baked_shapes = cmds.ls(baked, + baked_camera_shapes = cmds.ls(baked, type="camera", dag=True, shapes=True, long=True) + + members = members + baked_camera_shapes + members.remove(camera) else: - baked_shapes = cameras + baked_camera_shapes = cmds.ls(cameras, + type="camera", + dag=True, + shapes=True, + long=True) # Fix PLN-178: Don't allow background color to be non-black - for cam in baked_shapes: + for cam in cmds.ls( + baked_camera_shapes, type="camera", dag=True, + shapes=True, long=True): attrs = {"backgroundColorR": 0.0, "backgroundColorG": 0.0, "backgroundColorB": 0.0, @@ -177,7 +186,8 @@ class ExtractCameraMayaScene(openpype.api.Extractor): cmds.setAttr(plug, value) self.log.info("Performing extraction..") - cmds.select(baked_shapes, noExpand=True) + cmds.select(cmds.ls(members, dag=True, + shapes=True, long=True), noExpand=True) cmds.file(path, force=True, typ="mayaAscii" if self.scene_type == "ma" else "mayaBinary", # noqa: E501 From 73fb899e905efa2f7cfe9a54dcf8f4ccd06e6d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 14 Jun 2022 13:46:45 +0200 Subject: [PATCH 3/4] :construction: wip on validation of parent relationships --- .../publish/validate_camera_contents.py | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py index 38cf65f006..eb93245f93 100644 --- a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py @@ -33,7 +33,7 @@ class ValidateCameraContents(pyblish.api.InstancePlugin): invalid = [] cameras = cmds.ls(shapes, type='camera', long=True) if len(cameras) != 1: - cls.log.warning("Camera instance must have a single camera. " + cls.log.error("Camera instance must have a single camera. " "Found {0}: {1}".format(len(cameras), cameras)) invalid.extend(cameras) @@ -51,16 +51,32 @@ class ValidateCameraContents(pyblish.api.InstancePlugin): raise RuntimeError("No cameras found in empty instance.") if not cls.validate_shapes: - return + cls.log.info("not validating shapes in the content") + + for member in members: + parents = cmds.ls(member, long=True)[0].split("|")[1:-1] + cls.log.info(parents) + parents_long_named = [ + "|".join(parents[:i]) for i in range(1, 1 + len(parents)) + ] + cls.log.info(parents_long_named) + if cameras[0] in parents_long_named: + cls.log.error( + "{} is parented under camera {}".format(member, cameras[0])) + invalid.extend(member) + return invalid + # non-camera shapes valid_shapes = cmds.ls(shapes, type=('camera', 'locator'), long=True) shapes = set(shapes) - set(valid_shapes) if shapes: shapes = list(shapes) - cls.log.warning("Camera instance should only contain camera " + cls.log.error("Camera instance should only contain camera " "shapes. Found: {0}".format(shapes)) invalid.extend(shapes) + + invalid = list(set(invalid)) return invalid From 28d7e2ab517f0a311b689bb18582dcd737308ed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Samohel?= Date: Tue, 21 Jun 2022 14:50:59 +0200 Subject: [PATCH 4/4] :recycle: clean up some superfluous output --- .../hosts/maya/plugins/publish/validate_camera_contents.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py index eb93245f93..87712a4cea 100644 --- a/openpype/hosts/maya/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/maya/plugins/publish/validate_camera_contents.py @@ -51,18 +51,17 @@ class ValidateCameraContents(pyblish.api.InstancePlugin): raise RuntimeError("No cameras found in empty instance.") if not cls.validate_shapes: - cls.log.info("not validating shapes in the content") + cls.log.info("Not validating shapes in the content.") for member in members: parents = cmds.ls(member, long=True)[0].split("|")[1:-1] - cls.log.info(parents) parents_long_named = [ "|".join(parents[:i]) for i in range(1, 1 + len(parents)) ] - cls.log.info(parents_long_named) if cameras[0] in parents_long_named: cls.log.error( - "{} is parented under camera {}".format(member, cameras[0])) + "{} is parented under camera {}".format( + member, cameras[0])) invalid.extend(member) return invalid