diff --git a/openpype/hosts/max/plugins/create/create_camera.py b/openpype/hosts/max/plugins/create/create_camera.py index 45f437b7ee..91d0d4d3dc 100644 --- a/openpype/hosts/max/plugins/create/create_camera.py +++ b/openpype/hosts/max/plugins/create/create_camera.py @@ -13,11 +13,11 @@ class CreateCamera(plugin.MaxCreator): def create(self, subset_name, instance_data, pre_create_data): from pymxs import runtime as rt sel_obj = list(rt.selection) - _ = super(CreateCamera, self).create( + instance = super(CreateCamera, self).create( subset_name, instance_data, pre_create_data) # type: CreatedInstance - container = rt.getNodeByName(subset_name) + container = rt.getNodeByName(instance.data.get("instance_node")) # TODO: Disable "Add to Containers?" Panel # parent the selected cameras into the container for obj in sel_obj: diff --git a/openpype/hosts/max/plugins/publish/extract_camera_abc.py b/openpype/hosts/max/plugins/publish/extract_camera_abc.py index 38afbd8441..5f88df041b 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_abc.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_abc.py @@ -1,6 +1,9 @@ import os import pyblish.api -from openpype.pipeline import publish +from openpype.pipeline import ( + publish, + OptionalPyblishPluginMixin +) from pymxs import runtime as rt from openpype.hosts.max.api import ( maintained_selection, @@ -8,7 +11,8 @@ from openpype.hosts.max.api import ( ) -class ExtractCameraAlembic(publish.Extractor): +class ExtractAlembicCamera(publish.Extractor, + OptionalPyblishPluginMixin): """ Extract Camera with AlembicExport """ @@ -20,6 +24,8 @@ class ExtractCameraAlembic(publish.Extractor): optional = True def process(self, instance): + if not self.is_active(instance.data): + return start = float(instance.data.get("frameStartHandle", 1)) end = float(instance.data.get("frameEndHandle", 1)) diff --git a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py index 5a68edfbe8..7e92f355ed 100644 --- a/openpype/hosts/max/plugins/publish/extract_camera_fbx.py +++ b/openpype/hosts/max/plugins/publish/extract_camera_fbx.py @@ -1,6 +1,9 @@ import os import pyblish.api -from openpype.pipeline import publish +from openpype.pipeline import ( + publish, + OptionalPyblishPluginMixin +) from pymxs import runtime as rt from openpype.hosts.max.api import ( maintained_selection, @@ -8,7 +11,8 @@ from openpype.hosts.max.api import ( ) -class ExtractCameraFbx(publish.Extractor): +class ExtractCameraFbx(publish.Extractor, + OptionalPyblishPluginMixin): """ Extract Camera with FbxExporter """ @@ -17,8 +21,11 @@ class ExtractCameraFbx(publish.Extractor): label = "Extract Fbx Camera" hosts = ["max"] families = ["camera"] + optional = True def process(self, instance): + if not self.is_active(instance.data): + return container = instance.data["instance_node"] self.log.info("Extracting Camera ...") @@ -65,4 +72,4 @@ exportFile @"{filepath}" #noPrompt selectedOnly:true using:FBXEXP } instance.data["representations"].append(representation) self.log.info("Extracted instance '%s' to: %s" % (instance.name, - filepath)) \ No newline at end of file + filepath)) diff --git a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py index 4524609a02..7ac072b829 100644 --- a/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py +++ b/openpype/hosts/max/plugins/publish/extract_max_scene_raw.py @@ -1,6 +1,9 @@ import os import pyblish.api -from openpype.pipeline import publish +from openpype.pipeline import ( + publish, + OptionalPyblishPluginMixin +) from pymxs import runtime as rt from openpype.hosts.max.api import ( maintained_selection, @@ -8,7 +11,8 @@ from openpype.hosts.max.api import ( ) -class ExtractMaxSceneRaw(publish.Extractor): +class ExtractMaxSceneRaw(publish.Extractor, + OptionalPyblishPluginMixin): """ Extract Raw Max Scene with SaveSelected """ @@ -17,12 +21,15 @@ class ExtractMaxSceneRaw(publish.Extractor): label = "Max Scene(Raw)" hosts = ["max"] families = ["camera"] + optional = True def process(self, instance): + if not self.is_active(instance.data): + return container = instance.data["instance_node"] # publish the raw scene for camera - self.log.info("Extracting Camera ...") + self.log.info("Extracting Raw Max Scene ...") stagingdir = self.staging_dir(instance) filename = "{name}.max".format(**instance.data) @@ -34,29 +41,14 @@ class ExtractMaxSceneRaw(publish.Extractor): if "representations" not in instance.data: instance.data["representations"] = [] - #add extra blacklash for saveNodes in MaxScript - re_max_path = stagingdir + "\\\\" + filename # saving max scene - raw_export_cmd = ( - f""" -sel = getCurrentSelection() -for s in sel do -( - select s - f="{re_max_path}" - print f - saveNodes selection f quiet:true -) - """) - - self.log.debug(f"Executing Maxscript command: {raw_export_cmd}") - with maintained_selection(): # need to figure out how to select the camera rt.select(get_all_children(rt.getNodeByName(container))) - rt.execute(raw_export_cmd) + rt.execute(f'saveNodes selection "{max_path}" quiet:true') self.log.info("Performing Extraction ...") + representation = { 'name': 'max', 'ext': 'max', @@ -65,4 +57,4 @@ for s in sel do } instance.data["representations"].append(representation) self.log.info("Extracted instance '%s' to: %s" % (instance.name, - max_path)) \ No newline at end of file + max_path)) diff --git a/openpype/hosts/max/plugins/publish/validate_camera_contents.py b/openpype/hosts/max/plugins/publish/validate_camera_contents.py index 3990103e61..c81e28a61f 100644 --- a/openpype/hosts/max/plugins/publish/validate_camera_contents.py +++ b/openpype/hosts/max/plugins/publish/validate_camera_contents.py @@ -2,7 +2,6 @@ import pyblish.api from openpype.pipeline import PublishValidationError from pymxs import runtime as rt -from openpype.hosts.max.api import get_all_children class ValidateCameraContent(pyblish.api.InstancePlugin): @@ -24,7 +23,6 @@ class ValidateCameraContent(pyblish.api.InstancePlugin): raise PublishValidationError("Camera instance must only include" "camera (and camera target)") - def get_invalid(self, instance): """ Get invalid nodes if the instance is not camera @@ -32,26 +30,19 @@ class ValidateCameraContent(pyblish.api.InstancePlugin): invalid = list() container = instance.data["instance_node"] self.log.info("Validating look content for " - "'{}'".format(container)) + "{}".format(container)) con = rt.getNodeByName(container) - selection_list = self.list_children(con) - validation_msg = list() + selection_list = list(con.Children) for sel in selection_list: # to avoid Attribute Error from pymxs wrapper sel_tmp = str(sel) + found = False for cam in self.camera_type: if sel_tmp.startswith(cam): - validation_msg.append("Camera Found") - else: - validation_msg.append("Camera Not Found") - if "Camera Found" not in validation_msg: + found = True + break + if not found: + self.log.error("Camera not found") invalid.append(sel) - # go through the camera type to see if there are same name return invalid - - def list_children(self, node): - children = [] - for c in node.Children: - children.append(c) - return children diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index c89b41a3e4..31591bf734 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -1,5 +1,13 @@ { "imageio": { + "ocio_config": { + "enabled": false, + "filepath": [] + }, + "file_rules": { + "enabled": false, + "rules": {} + }, "colorManagementPreference_v2": { "enabled": true, "configFilePath": { @@ -158,24 +166,6 @@ "Main" ] }, - "CreateMultiverseUsd": { - "enabled": true, - "defaults": [ - "Main" - ] - }, - "CreateMultiverseUsdComp": { - "enabled": true, - "defaults": [ - "Main" - ] - }, - "CreateMultiverseUsdOver": { - "enabled": true, - "defaults": [ - "Main" - ] - }, "CreateAss": { "enabled": true, "defaults": [ @@ -196,6 +186,24 @@ "maskColor_manager": false, "maskOperator": false }, + "CreateMultiverseUsd": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateMultiverseUsdComp": { + "enabled": true, + "defaults": [ + "Main" + ] + }, + "CreateMultiverseUsdOver": { + "enabled": true, + "defaults": [ + "Main" + ] + }, "CreateAssembly": { "enabled": true, "defaults": [ @@ -338,6 +346,45 @@ "rig" ] }, + "ValidatePluginPathAttributes": { + "enabled": true, + "optional": false, + "active": true, + "attribute": { + "AlembicNode": "abc_File", + "VRayProxy": "fileName", + "RenderManArchive": "filename", + "pgYetiMaya": "cacheFileName", + "aiStandIn": "dso", + "RedshiftSprite": "tex0", + "RedshiftBokeh": "dofBokehImage", + "RedshiftCameraMap": "tex0", + "RedshiftEnvironment": "tex2", + "RedshiftDomeLight": "tex1", + "RedshiftIESLight": "profile", + "RedshiftLightGobo": "tex0", + "RedshiftNormalMap": "tex0", + "RedshiftProxyMesh": "fileName", + "RedshiftVolumeShape": "fileName", + "VRayTexGLSL": "fileName", + "VRayMtlGLSL": "fileName", + "VRayVRmatMtl": "fileName", + "VRayPtex": "ptexFile", + "VRayLightIESShape": "iesFile", + "VRayMesh": "materialAssignmentsFile", + "VRayMtlOSL": "fileName", + "VRayTexOSL": "fileName", + "VRayTexOCIO": "ocioConfigFile", + "VRaySettingsNode": "pmap_autoSaveFile2", + "VRayScannedMtl": "file", + "VRayScene": "parameterOverrideFilePath", + "VRayMtlMDL": "filename", + "VRaySimbiont": "file", + "dlOpenVDBShape": "filename", + "pgYetiMayaShape": "liveABCFilename", + "gpuCache": "cacheFileName" + } + }, "ValidateRenderSettings": { "arnold_render_attributes": [], "vray_render_attributes": [], @@ -349,11 +396,6 @@ "optional": false, "active": true }, - "ValidateGLTFTexturesNames": { - "enabled": false, - "optional": false, - "active": true - }, "ValidateRenderImageRule": { "enabled": true, "optional": false, @@ -829,12 +871,6 @@ } } }, - "ConvertGLSLShader": { - "enabled": false, - "optional": true, - "active": true, - "ogsfx_path": "" - }, "ExtractMayaSceneRaw": { "enabled": true, "add_for_families": [ @@ -1051,4 +1087,4 @@ "ValidateNoAnimation": false } } -} +} \ No newline at end of file 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 a124aec1b3..873bb79c95 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 @@ -313,6 +313,45 @@ } ] }, + { + "type": "dict", + "collapsible": true, + "checkbox_key": "enabled", + "key": "ValidatePluginPathAttributes", + "label": "Plug-in Path Attributes", + "is_group": true, + "children": [ + { + "type": "boolean", + "key": "enabled", + "label": "Enabled" + }, + { + "type": "boolean", + "key": "optional", + "label": "Optional" + }, + { + "type": "boolean", + "key": "active", + "label": "Active" + }, + { + "type": "label", + "label": "Fill in the node types and attributes you want to validate.

e.g. AlembicNode.abc_file, the node type is AlembicNode and the node attribute is abc_file" + }, + { + "type": "dict-modifiable", + "collapsible": true, + "key": "attribute", + "label": "File Attribute", + "use_label_wrap": true, + "object_type": { + "type": "text" + } + } + ] + }, { "type": "dict", "collapsible": true, @@ -369,10 +408,6 @@ "key": "ValidateCurrentRenderLayerIsRenderable", "label": "Validate Current Render Layer Has Renderable Camera" }, - { - "key": "ValidateGLTFTexturesNames", - "label": "Validate GLTF Textures Names" - }, { "key": "ValidateRenderImageRule", "label": "Validate Images File Rule (Workspace)" @@ -864,35 +899,6 @@ "type": "schema", "name": "schema_maya_capture" }, - { - "type": "dict", - "collapsible": true, - "key": "ConvertGLSLShader", - "label": "Convert PBS Shader to GLSL Shader", - "checkbox_key": "enabled", - "children": [ - { - "type": "boolean", - "key": "enabled", - "label": "Enabled" - }, - { - "type": "boolean", - "key": "optional", - "label": "Optional" - }, - { - "type": "boolean", - "key": "active", - "label": "Active" - }, - { - "type": "text", - "key": "ogsfx_path", - "label": "GLSL Shader Directory" - } - ] - }, { "type": "dict", "collapsible": true,