From eeda206278a5cc4d0a627513798394ef326907cb Mon Sep 17 00:00:00 2001 From: iLLiCiTiT Date: Mon, 27 Sep 2021 18:07:26 +0200 Subject: [PATCH] ValidateInstanceInContext was split into 2 separated plugins with own settings in maya and nuke host --- .../publish/validate_instance_in_context.py | 57 +++------ .../publish/validate_instance_in_context.py | 110 ++++++++++++++++++ .../defaults/project_settings/maya.json | 5 + .../defaults/project_settings/nuke.json | 5 + .../schemas/schema_maya_publish.json | 10 ++ .../schemas/schema_nuke_publish.json | 10 ++ 6 files changed, 157 insertions(+), 40 deletions(-) rename openpype/{ => hosts/maya}/plugins/publish/validate_instance_in_context.py (65%) create mode 100644 openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py diff --git a/openpype/plugins/publish/validate_instance_in_context.py b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py similarity index 65% rename from openpype/plugins/publish/validate_instance_in_context.py rename to openpype/hosts/maya/plugins/publish/validate_instance_in_context.py index 61b4d82027..7b8c335062 100644 --- a/openpype/plugins/publish/validate_instance_in_context.py +++ b/openpype/hosts/maya/plugins/publish/validate_instance_in_context.py @@ -5,6 +5,8 @@ from __future__ import absolute_import import pyblish.api import openpype.api +from maya import cmds + class SelectInvalidInstances(pyblish.api.Action): """Select invalid instances in Outliner.""" @@ -18,13 +20,12 @@ class SelectInvalidInstances(pyblish.api.Action): # Get the errored instances failed = [] for result in context.data["results"]: - if result["error"] is None: - continue - if result["instance"] is None: - continue - if result["instance"] in failed: - continue - if result["plugin"] != plugin: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): continue failed.append(result["instance"]) @@ -44,25 +45,10 @@ class SelectInvalidInstances(pyblish.api.Action): self.deselect() def select(self, instances): - if "nuke" in pyblish.api.registered_hosts(): - import avalon.nuke.lib - import nuke - avalon.nuke.lib.select_nodes( - [nuke.toNode(str(x)) for x in instances] - ) - - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.select(instances, replace=True, noExpand=True) + cmds.select(instances, replace=True, noExpand=True) def deselect(self): - if "nuke" in pyblish.api.registered_hosts(): - import avalon.nuke.lib - avalon.nuke.lib.reset_selection() - - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.select(deselect=True) + cmds.select(deselect=True) class RepairSelectInvalidInstances(pyblish.api.Action): @@ -92,23 +78,14 @@ class RepairSelectInvalidInstances(pyblish.api.Action): context_asset = context.data["assetEntity"]["name"] for instance in instances: - if "nuke" in pyblish.api.registered_hosts(): - import openpype.hosts.nuke.api as nuke_api - origin_node = instance[0] - nuke_api.lib.recreate_instance( - origin_node, avalon_data={"asset": context_asset} - ) - else: - self.set_attribute(instance, context_asset) + self.set_attribute(instance, context_asset) def set_attribute(self, instance, context_asset): - if "maya" in pyblish.api.registered_hosts(): - from maya import cmds - cmds.setAttr( - instance.data.get("name") + ".asset", - context_asset, - type="string" - ) + cmds.setAttr( + instance.data.get("name") + ".asset", + context_asset, + type="string" + ) class ValidateInstanceInContext(pyblish.api.InstancePlugin): @@ -124,7 +101,7 @@ class ValidateInstanceInContext(pyblish.api.InstancePlugin): order = openpype.api.ValidateContentsOrder label = "Instance in same Context" optional = True - hosts = ["maya", "nuke"] + hosts = ["maya"] actions = [SelectInvalidInstances, RepairSelectInvalidInstances] def process(self, instance): diff --git a/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py b/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py new file mode 100644 index 0000000000..ddf46a0873 --- /dev/null +++ b/openpype/hosts/nuke/plugins/publish/validate_instance_in_context.py @@ -0,0 +1,110 @@ +# -*- coding: utf-8 -*- +"""Validate if instance asset is the same as context asset.""" +from __future__ import absolute_import + +import nuke + +import pyblish.api +import openpype.api +import avalon.nuke.lib +import openpype.hosts.nuke.api as nuke_api + + +class SelectInvalidInstances(pyblish.api.Action): + """Select invalid instances in Outliner.""" + + label = "Select Instances" + icon = "briefcase" + on = "failed" + + def process(self, context, plugin): + """Process invalid validators and select invalid instances.""" + # Get the errored instances + failed = [] + for result in context.data["results"]: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): + continue + + failed.append(result["instance"]) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(failed, plugin) + + if instances: + self.log.info( + "Selecting invalid nodes: %s" % ", ".join( + [str(x) for x in instances] + ) + ) + self.select(instances) + else: + self.log.info("No invalid nodes found.") + self.deselect() + + def select(self, instances): + avalon.nuke.lib.select_nodes( + [nuke.toNode(str(x)) for x in instances] + ) + + def deselect(self): + avalon.nuke.lib.reset_selection() + + +class RepairSelectInvalidInstances(pyblish.api.Action): + """Repair the instance asset.""" + + label = "Repair" + icon = "wrench" + on = "failed" + + def process(self, context, plugin): + # Get the errored instances + failed = [] + for result in context.data["results"]: + if ( + result["error"] is None + or result["instance"] is None + or result["instance"] in failed + or result["plugin"] != plugin + ): + continue + + failed.append(result["instance"]) + + # Apply pyblish.logic to get the instances for the plug-in + instances = pyblish.api.instances_by_plugin(failed, plugin) + + context_asset = context.data["assetEntity"]["name"] + for instance in instances: + origin_node = instance[0] + nuke_api.lib.recreate_instance( + origin_node, avalon_data={"asset": context_asset} + ) + + +class ValidateInstanceInContext(pyblish.api.InstancePlugin): + """Validator to check if instance asset match context asset. + + When working in per-shot style you always publish data in context of + current asset (shot). This validator checks if this is so. It is optional + so it can be disabled when needed. + + Action on this validator will select invalid instances in Outliner. + """ + + order = openpype.api.ValidateContentsOrder + label = "Instance in same Context" + hosts = ["nuke"] + actions = [SelectInvalidInstances, RepairSelectInvalidInstances] + optional = True + + def process(self, instance): + asset = instance.data.get("asset") + context_asset = instance.context.data["assetEntity"]["name"] + msg = "{} has asset {}".format(instance.name, asset) + assert asset == context_asset, msg diff --git a/openpype/settings/defaults/project_settings/maya.json b/openpype/settings/defaults/project_settings/maya.json index 3540c3eb29..13d417581e 100644 --- a/openpype/settings/defaults/project_settings/maya.json +++ b/openpype/settings/defaults/project_settings/maya.json @@ -156,6 +156,11 @@ "CollectMayaRender": { "sync_workfile_version": false }, + "ValidateInstanceInContext": { + "enabled": true, + "optional": true, + "active": true + }, "ValidateContainers": { "enabled": true, "optional": true, diff --git a/openpype/settings/defaults/project_settings/nuke.json b/openpype/settings/defaults/project_settings/nuke.json index ac35349415..9254e0c8f6 100644 --- a/openpype/settings/defaults/project_settings/nuke.json +++ b/openpype/settings/defaults/project_settings/nuke.json @@ -38,6 +38,11 @@ "render" ] }, + "ValidateInstanceInContext": { + "enabled": true, + "optional": true, + "active": true + }, "ValidateContainers": { "enabled": true, "optional": true, 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 89cd30aed0..b5b035b9e6 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 @@ -28,6 +28,16 @@ "type": "label", "label": "Validators" }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateInstanceInContext", + "label": "Validate Instance In Context" + } + ] + }, { "type": "schema_template", "name": "template_publish_plugin", diff --git a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json index c73453f8aa..74b2592d29 100644 --- a/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json +++ b/openpype/settings/entities/schemas/projects_schema/schemas/schema_nuke_publish.json @@ -50,6 +50,16 @@ "type": "label", "label": "Validators" }, + { + "type": "schema_template", + "name": "template_publish_plugin", + "template_data": [ + { + "key": "ValidateInstanceInContext", + "label": "Validate Instance In Context" + } + ] + }, { "type": "schema_template", "name": "template_publish_plugin",