This commit is contained in:
Roy Nieterau 2017-08-11 14:58:53 +02:00
commit e6ff0e2dc0
6 changed files with 72 additions and 168 deletions

View file

@ -1,13 +1,14 @@
import pyblish.api
import colorbleed.api
import colorbleed.maya.lib as lib
class ValidateLookContents(pyblish.api.InstancePlugin):
"""Validate look instance contents
This is invalid when the collection was unable to collect the required
data for a look to be published correctly.
Rules:
* Look data must have `relationships` and `attributes` keys.
* At least one relationship must be collection.
* All relationship object sets at least have an ID value
"""
@ -22,7 +23,6 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
if not instance[:]:
raise RuntimeError("Instance is empty")
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("'{}' has invalid look "
@ -35,11 +35,12 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
cls.log.info("Validating look content for "
"'{}'".format(instance.name))
instance_items = cls.validate_instance_items(instance)
attributes = list(cls.validate_lookdata_attributes(instance))
relationships = list(cls.validate_relationship_ids(instance))
# check if data has the right attributes and content
attributes = cls.validate_lookdata_attributes(instance)
# check the looks for ID
looks = cls.validate_looks(instance)
invalid = instance_items + attributes + relationships
invalid = looks + attributes
return invalid
@ -68,36 +69,16 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
"`relationships`".format(instance.name))
invalid.add(instance.name)
return invalid
return list(invalid)
@classmethod
def validate_relationship_ids(cls, instance):
"""Validate and update lookData relationships"""
def validate_looks(cls, instance):
invalid = set()
relationships = instance.data["lookData"]["relationships"]
for objectset, members in relationships.items():
uuid = members["uuid"]
if not uuid:
look_name = objectset
cls.log.error("{} has invalid ID ".format(look_name))
invalid.add(look_name)
looks = instance.data["lookData"]["relationships"]
invalid = []
for name, data in looks.items():
if not data["uuid"]:
cls.log.error("Look '{}' has no UUID".format(name))
invalid.append(name)
return invalid
@classmethod
def validate_instance_items(cls, instance):
required_nodes = lib.get_id_required_nodes(referenced_nodes=False)
invalid = [node for node in instance if node in required_nodes
and not lib.get_id(node)]
if invalid:
nr_of_invalid = len(invalid)
cls.log.error("Found {} nodes without ID: {}".format(nr_of_invalid,
invalid))
return invalid

View file

@ -1,24 +1,19 @@
import pyblish.api
import colorbleed.api
import colorbleed.maya.lib as lib
class ValidateLookMembers(pyblish.api.InstancePlugin):
"""Validate look members have colorbleed id attributes
Looks up the contents of the look to see if all its members have
Colorbleed Id attributes so they can be connected correctly.
When invalid it's very likely related to the model not having the id
attributes that it should have. These should have been generated in the
work files for the model/rig/fur or alike.
Loops up all relationship members and check if all the members have the
cbId (colorbleed id) and return all the nodes who fail the test.
"""
order = colorbleed.api.ValidatePipelineOrder
families = ['colorbleed.lookdev']
hosts = ['maya']
label = 'Look Members'
label = 'Look Members (ID)'
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.GenerateUUIDsOnInvalidAction]
@ -33,12 +28,12 @@ class ValidateLookMembers(pyblish.api.InstancePlugin):
@classmethod
def get_invalid(cls, instance):
members = set()
relationships = instance.data["lookData"]["relationships"]
for relation in relationships.values():
members.update([member['name'] for member in relation['members']])
members = []
for relationship in relationships.values():
members.extend(relationship["members"])
invalid = [m for m in members if not lib.get_id(m)]
# get the name of the node when there is no UUID
invalid = [m["name"] for m in members if not m["uuid"]]
return invalid

View file

@ -1,17 +1,14 @@
from collections import defaultdict
from maya import cmds
import pyblish.api
import colorbleed.api
import colorbleed.maya.lib as lib
class ValidateNonDuplicateRelationshipMembers(pyblish.api.InstancePlugin):
class ValidateUniqueRelationshipMembers(pyblish.api.InstancePlugin):
"""Validate the relational nodes of the look data to ensure every node is
unique.
This ensures the same id is not present as more than one node in the look.
This ensures the all member ids are unique.
That means there's only ever one of a specific node inside the look to be
published. For example if you'd have a loaded 3x the same tree and by
@ -22,38 +19,13 @@ class ValidateNonDuplicateRelationshipMembers(pyblish.api.InstancePlugin):
"""
order = colorbleed.api.ValidatePipelineOrder
label = 'Non Duplicate Relationship Members (ID)'
label = 'Unique Relationship Members (ID)'
hosts = ['maya']
families = ['colorbleed.lookdev']
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.GenerateUUIDsOnInvalidAction]
@staticmethod
def get_invalid(instance):
# Get all members from the sets
members = []
relationships = instance.data["lookData"]["relationships"]
for relationship in relationships.values():
members.extend([i['name'] for i in relationship['members']])
# Ensure we don't have components but the objects
members = set(cmds.ls(members, objectsOnly=True, long=True))
members = list(members)
# Group members per id
id_nodes = defaultdict(set)
for node in members:
node_id = lib.get_id(node)
if not node_id:
continue
id_nodes[node_id].add(node)
invalid = [n for n in id_nodes.itervalues() if len(n) > 1]
return invalid
def process(self, instance):
"""Process all meshes"""
@ -61,3 +33,23 @@ class ValidateNonDuplicateRelationshipMembers(pyblish.api.InstancePlugin):
if invalid:
raise RuntimeError("Members found without asset IDs: "
"{0}".format(invalid))
@staticmethod
def get_invalid(instance):
# Get all members from the sets
id_nodes = defaultdict(list)
relationships = instance.data["lookData"]["relationships"]
for relationship in relationships.values():
for member in relationship['members']:
node_id = member["uuid"]
node = member["name"]
id_nodes[node_id].append(node)
# check if any id has more than 1 node
invalid = []
for nodes in id_nodes.values():
if len(nodes) > 1:
invalid.extend(nodes)
return invalid

View file

@ -1,70 +0,0 @@
import pprint
from collections import defaultdict
import pyblish.api
import colorbleed.api
import colorbleed.maya.lib as lib
class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
"""Validate look sets have unique colorbleed id attributes
"""
order = colorbleed.api.ValidatePipelineOrder
families = ['colorbleed.lookdev']
hosts = ['maya']
label = 'Look Id Unique Attributes'
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.RepairAction]
@classmethod
def get_invalid(cls, instance):
invalid = []
uuids_dict = defaultdict(list)
relationships = instance.data["lookData"]["relationships"]
pprint.pprint(relationships)
for objectset, relationship in relationships.items():
cls.log.info("Validating lookData for '%s'" % objectset)
# check if node has UUID and this matches with found node
for member in relationship["members"]:
node = member["name"]
member_uuid = member["uuid"]
uuid_query = lib.get_id(node)
if not member_uuid:
cls.log.error("No UUID found for '{}'".format(node))
invalid.append(node)
continue
if uuid_query != member_uuid:
cls.log.error("UUID in lookData does not match with "
"queried UUID of '{}'".format(node))
invalid.append(node)
continue
# check if the uuid has already passed through the check
# if so it means its a duplicate.
uuids_dict[objectset].append(uuid_query)
for objectset, member_uuids in uuids_dict.items():
stored = len(member_uuids)
unique = len(set(member_uuids))
if unique != stored:
rel_members = relationships[objectset]["members"]
invalid.extend([i["name"] for i in rel_members if
i["uuid"] not in unique])
return invalid
def process(self, instance):
"""Process all meshes"""
invalid = self.get_invalid(instance)
if invalid:
for item in invalid:
self.log.error("Invalid node : %s" % item)
raise RuntimeError("Nodes found without unique "
"IDs, see records")

View file

@ -7,6 +7,16 @@ import colorbleed.api
class ValidateLookSets(pyblish.api.InstancePlugin):
"""Validate if any sets are missing from the instance and look data
A node might have a relationship with a shader but has no Colorbleed ID.
Because it is missing the ID it has not been collected in the instance.
When the relationship needs to be maintained the artist might need to
create a different* relationship or ensure the node has the Colorbleed ID.
* The relationship might be too broad (assigned to top node if hierarchy).
This can be countered by creating the relationship on the shape or its
transform.
In essence, ensure item the shader is assigned to has the Colorbleed ID!
"""
order = colorbleed.api.ValidateContentsOrder
@ -18,10 +28,6 @@ class ValidateLookSets(pyblish.api.InstancePlugin):
def process(self, instance):
"""Process all the nodes in the instance"""
if not instance[:]:
raise RuntimeError("Instance is empty")
self.log.info("Validation '{}'".format(instance.name))
invalid = self.get_invalid(instance)
if invalid:
raise RuntimeError("'{}' has invalid look "
@ -34,15 +40,16 @@ class ValidateLookSets(pyblish.api.InstancePlugin):
cls.log.info("Validating look content for "
"'{}'".format(instance.name))
lookdata = instance.data["lookData"]
relationships = lookdata["relationships"]
relationships = instance.data["lookData"]["relationships"]
invalid = []
for node in instance:
# get the connected objectSets of the node
sets = lib.get_related_sets(node)
if not sets:
continue
# check if any objectSets are not present ion the relationships
missing_sets = [s for s in sets if s not in relationships]
if missing_sets:
# A set of this node is not coming along, this is wrong!

View file

@ -21,6 +21,16 @@ class ValidateNonDuplicateInstanceMembers(pyblish.api.InstancePlugin):
actions = [colorbleed.api.SelectInvalidAction,
colorbleed.api.GenerateUUIDsOnInvalidAction]
def process(self, instance):
"""Process all meshes"""
# Ensure all nodes have a cbId
invalid = self.get_invalid_dict(instance)
if invalid:
raise RuntimeError("Nodes found with non-unique "
"asset IDs: {0}".format(invalid))
@classmethod
def get_invalid_dict(cls, instance):
"""Return a dictionary mapping of id key to list of member nodes"""
@ -53,15 +63,4 @@ class ValidateNonDuplicateInstanceMembers(pyblish.api.InstancePlugin):
for members in invalid_dict.itervalues():
invalid.extend(members)
return invalid
def process(self, instance):
"""Process all meshes"""
# Ensure all nodes have a cbId
invalid = self.get_invalid_dict(instance)
if invalid:
raise RuntimeError("Nodes found with non-unique "
"asset IDs: {0}".format(invalid))
return invalid