diff --git a/colorbleed/plugins/maya/publish/validate_look_contents.py b/colorbleed/plugins/maya/publish/validate_look_contents.py index 1d9d192521..4f62fdd2ac 100644 --- a/colorbleed/plugins/maya/publish/validate_look_contents.py +++ b/colorbleed/plugins/maya/publish/validate_look_contents.py @@ -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 - - - diff --git a/colorbleed/plugins/maya/publish/validate_look_members_node_ids.py b/colorbleed/plugins/maya/publish/validate_look_members_node_ids.py index 9ecc8cd5fa..c6a914b304 100644 --- a/colorbleed/plugins/maya/publish/validate_look_members_node_ids.py +++ b/colorbleed/plugins/maya/publish/validate_look_members_node_ids.py @@ -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 - diff --git a/colorbleed/plugins/maya/publish/validate_look_members_unique.py b/colorbleed/plugins/maya/publish/validate_look_members_unique.py index 1dfac3f3f1..9391b086dd 100644 --- a/colorbleed/plugins/maya/publish/validate_look_members_unique.py +++ b/colorbleed/plugins/maya/publish/validate_look_members_unique.py @@ -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 diff --git a/colorbleed/plugins/maya/publish/validate_look_node_unique_ids.py b/colorbleed/plugins/maya/publish/validate_look_node_unique_ids.py deleted file mode 100644 index fbfc007a9a..0000000000 --- a/colorbleed/plugins/maya/publish/validate_look_node_unique_ids.py +++ /dev/null @@ -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") diff --git a/colorbleed/plugins/maya/publish/validate_look_sets.py b/colorbleed/plugins/maya/publish/validate_look_sets.py index 56f104a18b..95dc266f97 100644 --- a/colorbleed/plugins/maya/publish/validate_look_sets.py +++ b/colorbleed/plugins/maya/publish/validate_look_sets.py @@ -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! diff --git a/colorbleed/plugins/maya/publish/validate_unique_node_ids.py b/colorbleed/plugins/maya/publish/validate_unique_node_ids.py index 3de16d5a15..d08775f5b0 100644 --- a/colorbleed/plugins/maya/publish/validate_unique_node_ids.py +++ b/colorbleed/plugins/maya/publish/validate_unique_node_ids.py @@ -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 \ No newline at end of file