Merged publish_maya into master

This commit is contained in:
Wijnand Koreman 2017-08-02 15:26:08 +02:00
commit 0655047efa
4 changed files with 38 additions and 151 deletions

View file

@ -1,11 +1,9 @@
# absolute_import is needed to counter the `module has no cmds error` in Maya
from __future__ import absolute_import
import os
import uuid
from maya import cmds
import pyblish.api
@ -164,7 +162,7 @@ class GenerateUUIDsOnInvalidAction(pyblish.api.Action):
instance = result["instance"]
errored_instances.append(instance)
# Apply pyblish.logic to get the instances for the plug-in
# Apply pyblish logic to get the instances for the plug-in
instances = pyblish.api.instances_by_plugin(errored_instances, plugin)
# Get the nodes from the all instances that ran through this plug-in
@ -178,78 +176,34 @@ class GenerateUUIDsOnInvalidAction(pyblish.api.Action):
self.log.info("No invalid nodes found.")
return
# Ensure unique (process each node only once)
# Ensure unique ( process each node only once )
invalid = list(set(invalid))
# Parse context from current file
self.log.info("Parsing current context..")
print(">>> DEBUG CONTEXT :", context)
print(">>> DEBUG CONTEXT DATA:", context.data)
self.log.info("Updating node IDs ...")
# Update the attributes
self._update_id_attribute(invalid)
# # Generate and add the ids to the nodes
node_ids = self.generate_ids(context, invalid)
self.apply_ids(node_ids)
self.log.info("Generated ids on nodes: {0}".format(invalid))
def get_context(self, instance=None):
def _update_id_attribute(self, nodes):
"""Delete the id attribute
PROJECT = os.environ["AVALON_PROJECT"]
ASSET = instance.data.get("asset") or os.environ["AVALON_ASSET"]
SILO = os.environ["AVALON_SILO"]
LOCATION = os.getenv("AVALON_LOCATION")
return {"project": PROJECT,
"asset": ASSET,
"silo": SILO,
"location": LOCATION}
def generate_ids(self, context, nodes):
"""Generate cb UUIDs for nodes.
The identifiers are formatted like:
assets:character/test:bluey:46D221D9-4150-8E49-6B17-43B04BFC26B6
This is a concatenation of:
- entity (shots or assets)
- folders (parent hierarchy)
- asset (the name of the asset)
- uuid (unique id for node in the scene)
Raises:
RuntimeError: When context can't be parsed of the current asset
Returns:
dict: node, uuid dictionary
"""
# Make a copy of the context
data = context.copy()
# Define folders
node_ids = dict()
for node in nodes:
# Generate a unique ID per node
data['uuid'] = uuid.uuid4()
unique_id = "{asset}:{item}:{uuid}".format(**data)
node_ids[node] = unique_id
return node_ids
def apply_ids(self, node_ids):
"""Apply the created unique IDs to the node
Args:
node_ids (dict): each node with a unique id
Returns:
None
nodes (list): all nodes to remove the attribute from
"""
attribute = "mbId"
for node, id in node_ids.items():
# check if node has attribute
if not cmds.attributeQuery(attribute, node=node, exists=True):
cmds.addAttr(node, longName=attribute, dataType="string")
for node in nodes:
# get the database asset id
attr = "{}.cbId".format(node)
id_attr = cmds.getAttr(attr)
asset_id = id_attr.split(":")[0]
# create a new unique id
_, uid = str(uuid.uuid4()).rsplit("-", 1)
cb_uid = "{}:{}".format(asset_id, uid)
# set the new id
cmds.setAttr(attr, cb_uid, type="string")
cmds.setAttr("{}.{}".format(node, attribute), id)

View file

@ -1,41 +0,0 @@
import pyblish.api
import colorbleed.api
class ValidateLookNodeIds(pyblish.api.InstancePlugin):
"""Validate nodes have colorbleed id attributes
All look sets should have id attributes.
"""
order = colorbleed.api.ValidatePipelineOrder
families = ['colorbleed.look']
hosts = ['maya']
label = 'Look Id Attributes'
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.GenerateUUIDsOnInvalidAction]
@staticmethod
def get_invalid(instance):
import maya.cmds as cmds
nodes = instance.data["lookSets"]
# Ensure all nodes have a cbId
invalid = list()
for node in nodes:
uuid = cmds.attributeQuery("mbId", node=node, exists=True)
if not uuid:
invalid.append(node)
return invalid
def process(self, instance):
"""Process all meshes"""
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("Nodes found without "
"asset IDs: {0}".format(invalid))

View file

@ -1,34 +0,0 @@
import re
import pyblish.api
import colorbleed.api
class ValidateNamingConvention(pyblish.api.InstancePlugin):
label = ""
families = ["colorbleed.model"]
host = ["maya"]
actions = [colorbleed.api.SelectInvalidAction]
@staticmethod
def get_invalid(instance):
invalid = []
# todo: change pattern to company standard
pattern = re.compile("[a-zA-Z]+_[A-Z]{3}")
nodes = list(instance)
for node in nodes:
match = pattern.match(node)
if not match:
invalid.append(node)
return invalid
def process(self, instance):
invalid = self.get_invalid(instance)
if invalid:
self.log.error("Found invalid naming convention. Failed noted :\n"
"%s" % invalid)

View file

@ -10,14 +10,17 @@ class ValidateUniqueNodeIds(pyblish.api.InstancePlugin):
"""Validate nodes have colorbleed id attributes"""
order = colorbleed.api.ValidatePipelineOrder
families = ['colorbleed.model']
hosts = ['maya']
label = 'Unique Id Attributes'
hosts = ['maya']
families = ['colorbleed.model',
'colorbleed.lookdev',
'colorbleed.rig']
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.GenerateUUIDsOnInvalidAction]
@staticmethod
def get_invalid_dict(instance):
@classmethod
def get_invalid_dict(cls, instance):
"""Return a dictionary mapping of id key to list of member nodes"""
uuid_attr = "cbId"
@ -25,18 +28,21 @@ class ValidateUniqueNodeIds(pyblish.api.InstancePlugin):
# Collect each id with their members
ids = defaultdict(list)
for member in instance:
has_attr = cmds.attributeQuery(uuid_attr, node=member, exists=True)
if not has_attr:
try:
object_id = cmds.getAttr("{}.{}".format(member, uuid_attr))
except Exception as exception:
# Object will node have the attribute so skip
cls.log.debug(exception)
continue
mbid = cmds.getAttr("{}.{}".format(member, uuid_attr))
ids[mbid].append(member)
ids[object_id].append(member)
# Skip those without IDs (if everything should have an ID that should
# be another validation)
ids.pop(None, None)
# Take only the ids with more than one member
invalid = dict((id, members) for id, members in ids.iteritems() if
invalid = dict((_id, members) for _id, members in ids.iteritems() if
len(members) > 1)
return invalid
@ -61,3 +67,5 @@ class ValidateUniqueNodeIds(pyblish.api.InstancePlugin):
if invalid:
raise RuntimeError("Nodes found with non-unique "
"asset IDs: {0}".format(invalid))