mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merged in Aardschok/config (pull request #8)
Improvements and additions
This commit is contained in:
commit
6254b02df4
16 changed files with 292 additions and 187 deletions
|
|
@ -97,11 +97,7 @@ def on_save(_):
|
|||
|
||||
avalon.logger.info("Running callback on save..")
|
||||
|
||||
types = ["objectSet", "file", "mesh", "nurbsCurve", "nurbsSurface"]
|
||||
type_nodes = set(cmds.ls(type=types, long=True))
|
||||
nodes = lib.filter_out_nodes(type_nodes,
|
||||
defaults=True,
|
||||
referenced_nodes=True)
|
||||
nodes = lib.get_id_required_nodes(referenced_nodes=False)
|
||||
|
||||
# Lead with asset ID from the database
|
||||
asset = os.environ["AVALON_ASSET"]
|
||||
|
|
@ -111,5 +107,4 @@ def on_save(_):
|
|||
# generate the ids
|
||||
|
||||
for node in nodes:
|
||||
print node
|
||||
_set_uuid(str(asset_id["_id"]), node)
|
||||
|
|
|
|||
|
|
@ -595,55 +595,45 @@ def maya_temp_folder():
|
|||
return tmp_dir
|
||||
|
||||
|
||||
def remap_resource_nodes(resources, folder=None):
|
||||
|
||||
log.info("Updating resource nodes ...")
|
||||
for resource in resources:
|
||||
source = resource["source"]
|
||||
if folder:
|
||||
fname = os.path.basename(source)
|
||||
fpath = os.path.join(folder, fname)
|
||||
else:
|
||||
fpath = source
|
||||
|
||||
node_attr = resource["attribute"]
|
||||
cmds.setAttr(node_attr, fpath, type="string")
|
||||
|
||||
log.info("Saving file ...")
|
||||
cmds.file(save=True, type="mayaAscii")
|
||||
|
||||
|
||||
def filter_out_nodes(nodes, defaults=False, referenced_nodes=False):
|
||||
def get_id_required_nodes(referenced_nodes=False):
|
||||
"""Filter out any node which are locked (reference) or readOnly
|
||||
|
||||
Args:
|
||||
nodes (set): nodes to filter
|
||||
locked (bool): set True to filter out lockedNodes
|
||||
readonly (bool): set True to filter out readOnly
|
||||
referenced_nodes (bool): set True to filter out reference nodes
|
||||
Returns:
|
||||
nodes (list): list of filtered nodes
|
||||
nodes (set): list of filtered nodes
|
||||
"""
|
||||
# establish set of nodes to ignore
|
||||
|
||||
# `readOnly` flag is obsolete as of Maya 2016 therefor we explicitly remove
|
||||
# default nodes and reference nodes
|
||||
camera_shapes = ["frontShape", "sideShape", "topShape", "perspShape"]
|
||||
|
||||
ignore = set()
|
||||
if referenced_nodes:
|
||||
ignore |= set(cmds.ls(long=True, referencedNodes=referenced_nodes))
|
||||
if not referenced_nodes:
|
||||
ignore |= set(cmds.ls(long=True, referencedNodes=True))
|
||||
|
||||
if defaults:
|
||||
ignore |= set(cmds.ls(long=True, defaultNodes=defaults))
|
||||
# list all defaultNodes to filter out from the rest
|
||||
ignore |= set(cmds.ls(long=True, defaultNodes=True))
|
||||
ignore |= set(cmds.ls(camera_shapes, long=True))
|
||||
|
||||
# establish set of nodes to ignore
|
||||
types = ["objectSet", "file", "mesh", "nurbsCurve", "nurbsSurface"]
|
||||
|
||||
# We *always* ignore intermediate shapes, so we filter them out
|
||||
# directly
|
||||
nodes = cmds.ls(type=types, long=True, noIntermediate=True)
|
||||
|
||||
# The items which need to pass the id to their parent
|
||||
# Add the collected transform to the nodes
|
||||
dag = cmds.ls(list(nodes),
|
||||
type="dagNode",
|
||||
long=True) # query only dag nodes
|
||||
dag = cmds.ls(nodes, type="dagNode", long=True) # query only dag nodes
|
||||
|
||||
transforms = cmds.listRelatives(dag,
|
||||
parent=True,
|
||||
fullPath=True) or []
|
||||
|
||||
nodes = set(nodes)
|
||||
nodes |= set(transforms)
|
||||
|
||||
nodes -= ignore # Remove the ignored nodes
|
||||
|
||||
return nodes
|
||||
|
|
@ -663,14 +653,10 @@ def get_id(node):
|
|||
if node is None:
|
||||
return
|
||||
|
||||
try:
|
||||
attr = "{}.cbId".format(node)
|
||||
attribute_value = cmds.getAttr(attr)
|
||||
except Exception as e:
|
||||
log.debug(e)
|
||||
if not cmds.attributeQuery("cbId", node=node, exists=True):
|
||||
return
|
||||
|
||||
return attribute_value
|
||||
return cmds.getAttr("{}.cbId".format(node))
|
||||
|
||||
|
||||
def get_representation_file(representation, template=TEMPLATE):
|
||||
|
|
@ -910,7 +896,7 @@ def apply_shaders(relationships, shadernodes, nodes):
|
|||
"""
|
||||
|
||||
attributes = relationships.get("attributes", [])
|
||||
shader_sets = relationships.get("sets", [])
|
||||
shader_data = relationships.get("relationships", {})
|
||||
|
||||
shading_engines = cmds.ls(shadernodes, type="objectSet", long=True)
|
||||
assert len(shading_engines) > 0, ("Error in retrieving objectSets "
|
||||
|
|
@ -927,10 +913,10 @@ def apply_shaders(relationships, shadernodes, nodes):
|
|||
# endregion
|
||||
|
||||
# region assign
|
||||
for shader_set in shader_sets:
|
||||
for data in shader_data.values():
|
||||
# collect all unique IDs of the set members
|
||||
shader_uuid = shader_set["uuid"]
|
||||
member_uuids = [member["uuid"] for member in shader_set["members"]]
|
||||
shader_uuid = data["uuid"]
|
||||
member_uuids = [member["uuid"] for member in data["members"]]
|
||||
|
||||
filtered_nodes = list()
|
||||
for uuid in member_uuids:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import tempfile
|
||||
import pyblish.api
|
||||
import avalon.maya
|
||||
|
||||
|
||||
ValidatePipelineOrder = pyblish.api.ValidatorOrder + 0.05
|
||||
ValidateContentsOrder = pyblish.api.ValidatorOrder + 0.1
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
hosts = ["maya"]
|
||||
|
||||
# Ignore specifically named sets (check with endswith)
|
||||
IGNORE = ["out_SET", "controls_SET", "_INST"]
|
||||
IGNORE = ["out_SET", "controls_SET", "_INST", "_CON"]
|
||||
|
||||
def process(self, instance):
|
||||
"""Collect the Look in the instance with the correct layer settings"""
|
||||
|
|
@ -120,19 +120,20 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
|
||||
# Store data on the instance
|
||||
instance.data["lookData"] = {"attributes": attributes,
|
||||
"relationships": sets.values(),
|
||||
"sets": looksets}
|
||||
"relationships": sets}
|
||||
|
||||
# Collect file nodes used by shading engines
|
||||
history = cmds.listHistory(looksets)
|
||||
files = cmds.ls(history, type="file", long=True)
|
||||
# Collect file nodes used by shading engines (if we have any)
|
||||
files = list()
|
||||
if looksets:
|
||||
history = cmds.listHistory(looksets)
|
||||
files = cmds.ls(history, type="file", long=True)
|
||||
|
||||
# Collect textures
|
||||
resources = [self.collect_resource(n) for n in files]
|
||||
instance.data["resources"] = resources
|
||||
|
||||
# Log a warning when no relevant sets were retrieved for the look.
|
||||
if not instance.data["lookData"]["sets"]:
|
||||
if not instance.data["lookData"]["relationships"]:
|
||||
self.log.warning("No sets found for the nodes in the instance: "
|
||||
"%s" % instance[:])
|
||||
|
||||
|
|
@ -168,8 +169,7 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
if objset in sets:
|
||||
continue
|
||||
|
||||
sets[objset] = {"name": objset,
|
||||
"uuid": lib.get_id(objset),
|
||||
sets[objset] = {"uuid": lib.get_id(objset),
|
||||
"members": list()}
|
||||
|
||||
return sets
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class ExtractLook(colorbleed.api.Extractor):
|
|||
# exported file by accident
|
||||
self.log.info("Extract sets (Maya ASCII) ...")
|
||||
lookdata = instance.data["lookData"]
|
||||
sets = lookdata["sets"]
|
||||
sets = lookdata["relationships"].keys()
|
||||
|
||||
resources = instance.data["resources"]
|
||||
remap = {}
|
||||
|
|
@ -72,7 +72,7 @@ class ExtractLook(colorbleed.api.Extractor):
|
|||
# Write the JSON data
|
||||
self.log.info("Extract json..")
|
||||
data = {"attributes": lookdata["attributes"],
|
||||
"sets": lookdata["relationships"]}
|
||||
"relationships": lookdata["relationships"]}
|
||||
|
||||
with open(json_path, "w") as f:
|
||||
json.dump(data, f)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateLookContents(pyblish.api.InstancePlugin):
|
||||
|
|
@ -13,32 +16,32 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
|
|||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Contents'
|
||||
label = 'Look Data Contents'
|
||||
actions = [colorbleed.api.SelectInvalidAction]
|
||||
|
||||
invalid = []
|
||||
errors = []
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all the nodes in the instance"""
|
||||
|
||||
if not instance[:]:
|
||||
raise RuntimeError("Instance is empty")
|
||||
|
||||
self.get_invalid(instance)
|
||||
|
||||
if self.errors:
|
||||
error_string = "\n".join(self.errors)
|
||||
raise RuntimeError("Invalid look content. "
|
||||
"Errors : {}".format(error_string))
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("'{}' has invalid look "
|
||||
"content".format(instance.name))
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
"""Get all invalid nodes"""
|
||||
|
||||
invalid_attr = list(cls.validate_lookdata_attributes(instance))
|
||||
invalid_rels = list(cls.validate_relationships(instance))
|
||||
cls.log.info("Validating look content for "
|
||||
"'{}'".format(instance.name))
|
||||
|
||||
invalid = invalid_attr + invalid_rels
|
||||
instance_items = cls.validate_instance_items(instance)
|
||||
attributes = list(cls.validate_lookdata_attributes(instance))
|
||||
relationships = list(cls.validate_relationship_ids(instance))
|
||||
|
||||
invalid = instance_items + attributes + relationships
|
||||
|
||||
return invalid
|
||||
|
||||
|
|
@ -53,30 +56,50 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
|
|||
|
||||
invalid = set()
|
||||
|
||||
attributes = ["sets", "relationships", "attributes"]
|
||||
attributes = ["relationships", "attributes"]
|
||||
lookdata = instance.data["lookData"]
|
||||
for attr in attributes:
|
||||
if attr not in lookdata:
|
||||
cls.errors.append("Look Data has no attribute "
|
||||
"'{}'".format(attr))
|
||||
cls.log.error("Look Data has no attribute "
|
||||
"'{}'".format(attr))
|
||||
invalid.add(instance.name)
|
||||
|
||||
# Validate at least one single relationship is collected
|
||||
if not lookdata["relationships"]:
|
||||
cls.log.error("Look '{}' has no "
|
||||
"`relationship`".format(instance.name))
|
||||
invalid.add(instance.name)
|
||||
|
||||
return invalid
|
||||
|
||||
@classmethod
|
||||
def validate_relationships(cls, instance):
|
||||
def validate_relationship_ids(cls, instance):
|
||||
"""Validate and update lookData relationships"""
|
||||
|
||||
invalid = set()
|
||||
|
||||
relationships = instance.data["lookData"]["relationships"]
|
||||
for relationship in relationships:
|
||||
look_name = relationship["name"]
|
||||
for key, value in relationship.items():
|
||||
if value is None:
|
||||
cls.errors.append("{} has invalid attribite "
|
||||
"'{}'".format(look_name, key))
|
||||
|
||||
invalid.add(look_name)
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
|
|
@ -20,11 +22,10 @@ class ValidateLookDefaultShadersConnections(pyblish.api.InstancePlugin):
|
|||
label = 'Look Default Shader Connections'
|
||||
|
||||
# The default connections to check
|
||||
DEFAULTS = [
|
||||
("initialShadingGroup.surfaceShader", "lambert1"),
|
||||
("initialParticleSE.surfaceShader", "lambert1"),
|
||||
("initialParticleSE.volumeShader", "particleCloud1")
|
||||
]
|
||||
DEFAULTS = [("initialShadingGroup.surfaceShader", "lambert1"),
|
||||
("initialParticleSE.surfaceShader", "lambert1"),
|
||||
("initialParticleSE.volumeShader", "particleCloud1")
|
||||
]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
@ -33,19 +34,15 @@ class ValidateLookDefaultShadersConnections(pyblish.api.InstancePlugin):
|
|||
# the family is not present in an instance.
|
||||
key = "__validate_look_default_shaders_connections_checked"
|
||||
context = instance.context
|
||||
is_run = context.data.get(key,
|
||||
False)
|
||||
is_run = context.data.get(key, False)
|
||||
if is_run:
|
||||
return
|
||||
else:
|
||||
context.data[key] = True
|
||||
|
||||
# Process as usual
|
||||
from maya import cmds
|
||||
|
||||
invalid = list()
|
||||
for plug, input_node in self.DEFAULTS:
|
||||
|
||||
inputs = cmds.listConnections(plug,
|
||||
source=True,
|
||||
destination=False) or None
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import colorbleed.api
|
|||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateLookMembersHaveId(pyblish.api.InstancePlugin):
|
||||
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
|
||||
|
|
@ -18,35 +18,27 @@ class ValidateLookMembersHaveId(pyblish.api.InstancePlugin):
|
|||
order = colorbleed.api.ValidatePipelineOrder
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Members Have ID Attribute'
|
||||
label = 'Look Members'
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all meshes"""
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Members found without "
|
||||
"asset IDs: {0}".format(invalid))
|
||||
invalid_ids = self.get_invalid(instance)
|
||||
if invalid_ids:
|
||||
raise RuntimeError("Found invalid nodes.\nNo ID : "
|
||||
"{}".format(invalid_ids))
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
# Get all members from the sets
|
||||
members = []
|
||||
relations = instance.data["lookData"]["relationships"]
|
||||
for relation in relations:
|
||||
members = [member['name'] for member in relation['members']]
|
||||
members.extend(members)
|
||||
members = set()
|
||||
relationships = instance.data["lookData"]["relationships"]
|
||||
for relation in relationships.values():
|
||||
members.update([member['name'] for member in relation['members']])
|
||||
|
||||
# Get all sets
|
||||
members = list(set(members))
|
||||
|
||||
# Ensure all nodes have a cbId
|
||||
invalid = list()
|
||||
for node in members:
|
||||
if not lib.get_id(node):
|
||||
invalid.append(node)
|
||||
invalid = [m for m in members if not lib.get_id(m)]
|
||||
|
||||
return invalid
|
||||
|
||||
|
|
|
|||
|
|
@ -4,15 +4,7 @@ from maya import cmds
|
|||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
|
||||
def get_unique_id(node):
|
||||
attr = 'cbId'
|
||||
unique_id = None
|
||||
has_attribute = cmds.attributeQuery(attr, node=node, exists=True)
|
||||
if has_attribute:
|
||||
unique_id = cmds.getAttr("{}.{}".format(node, attr))
|
||||
return unique_id
|
||||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateNonDuplicateRelationshipMembers(pyblish.api.InstancePlugin):
|
||||
|
|
@ -43,26 +35,22 @@ class ValidateNonDuplicateRelationshipMembers(pyblish.api.InstancePlugin):
|
|||
# Get all members from the sets
|
||||
members = []
|
||||
relationships = instance.data["lookData"]["relationships"]
|
||||
for sg in relationships:
|
||||
sg_members = [member['name'] for member in sg['members']]
|
||||
members.extend(sg_members)
|
||||
for relationship in relationships.values():
|
||||
members.extend([i['name'] for i in relationship['members']])
|
||||
|
||||
# Ensure we don't have components but the objects
|
||||
members = cmds.ls(members, objectsOnly=True, long=True)
|
||||
members = list(set(members))
|
||||
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 = get_unique_id(node)
|
||||
node_id = lib.get_id(node)
|
||||
if not node_id:
|
||||
continue
|
||||
id_nodes[node_id].add(node)
|
||||
|
||||
invalid = list()
|
||||
for nodes in id_nodes.itervalues():
|
||||
if len(nodes) > 1:
|
||||
invalid.extend(nodes)
|
||||
invalid = [n for n in id_nodes.itervalues() if len(n) > 1]
|
||||
|
||||
return invalid
|
||||
|
||||
|
|
|
|||
|
|
@ -37,16 +37,15 @@ class ValidateLookNoDefaultShaders(pyblish.api.InstancePlugin):
|
|||
"initialParticleSE",
|
||||
"particleCloud1"]
|
||||
|
||||
setmembers = instance.data["setMembers"]
|
||||
members = cmds.listRelatives(setmembers,
|
||||
members = cmds.listRelatives(instance,
|
||||
allDescendents=True,
|
||||
type="shape")
|
||||
|
||||
shapes=True,
|
||||
noIntermediate=True) or []
|
||||
for member in members:
|
||||
|
||||
# get connection
|
||||
# listConnections returns a list or None
|
||||
shading_engine = cmds.listConnections(member, type="shadingEngine")
|
||||
shading_engine = cmds.listConnections(member, type="objectSet")
|
||||
if not shading_engine:
|
||||
cls.log.error("Detected shape without shading engine : "
|
||||
"'{}'".format(member))
|
||||
|
|
@ -58,6 +57,7 @@ class ValidateLookNoDefaultShaders(pyblish.api.InstancePlugin):
|
|||
if shading_engine in disallowed:
|
||||
cls.log.error("Member connected to a disallows objectSet: "
|
||||
"'{}'".format(member))
|
||||
invalid.append(member)
|
||||
else:
|
||||
continue
|
||||
|
||||
|
|
@ -66,7 +66,6 @@ class ValidateLookNoDefaultShaders(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
"""Process all the nodes in the instance"""
|
||||
|
||||
# sets = self.get_invalid_sets(instance)
|
||||
sets = self.get_invalid(instance)
|
||||
if sets:
|
||||
raise RuntimeError("Invalid shaders found: {0}".format(sets))
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Invalid shaders found: {0}".format(invalid))
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import pprint
|
||||
from collections import defaultdict
|
||||
|
||||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
|
||||
|
|
@ -18,26 +18,44 @@ class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
|
|||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.RepairAction]
|
||||
|
||||
@staticmethod
|
||||
def get_invalid(instance):
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
nodes = instance.data["lookData"]["sets"]
|
||||
invalid = []
|
||||
uuids_dict = defaultdict(list)
|
||||
|
||||
# Ensure all nodes have a cbId
|
||||
id_sets = defaultdict(list)
|
||||
invalid = list()
|
||||
for node in nodes:
|
||||
unique_id = None
|
||||
if cmds.attributeQuery("cbId", node=node, exists=True):
|
||||
unique_id = cmds.getAttr("{}.cbId".format(node))
|
||||
if not unique_id:
|
||||
continue
|
||||
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)
|
||||
|
||||
id_sets[unique_id].append(node)
|
||||
if not member_uuid:
|
||||
cls.log.error("No UUID found for '{}'".format(node))
|
||||
invalid.append(node)
|
||||
continue
|
||||
|
||||
for unique_id, nodes in id_sets.iteritems():
|
||||
if len(nodes) > 1:
|
||||
invalid.extend(nodes)
|
||||
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
|
||||
|
||||
|
|
@ -46,5 +64,7 @@ class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
|
|||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Nodes found without "
|
||||
"asset IDs: {0}".format(invalid))
|
||||
for item in invalid:
|
||||
self.log.error("Invalid node : %s" % item)
|
||||
raise RuntimeError("Nodes found without unique "
|
||||
"IDs, see records")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
|
||||
class ValidateSingleShader(pyblish.api.InstancePlugin):
|
||||
"""Validate default shaders in the scene have their default connections.
|
||||
|
||||
For example the lambert1 could potentially be disconnected from the
|
||||
initialShadingGroup. As such it's not lambert1 that will be identified
|
||||
as the default shader which can have unpredictable results.
|
||||
|
||||
To fix the default connections need to be made again. See the logs for
|
||||
more details on which connections are missing.
|
||||
|
||||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Single Shader Per Shape'
|
||||
|
||||
# The default connections to check
|
||||
def process(self, instance):
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Found shapes which have multiple "
|
||||
"shadingEngines connected."
|
||||
"\n{}".format(invalid))
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
invalid = []
|
||||
shape_types = ["numrbsCurve", "nurbsSurface", "mesh"]
|
||||
|
||||
# Get all shapes from the instance
|
||||
shapes = set()
|
||||
for node in instance[:]:
|
||||
|
||||
nodetype = cmds.nodeType(node)
|
||||
if nodetype in shape_types:
|
||||
shapes.add(node)
|
||||
|
||||
elif nodetype == "transform":
|
||||
shape = cmds.listRelatives(node, children=True,
|
||||
type="shape", fullPath=True)
|
||||
if not shape:
|
||||
continue
|
||||
shapes.add(shape[0])
|
||||
|
||||
# Check the number of connected shadingEngines per shape
|
||||
for shape in shapes:
|
||||
shading_engines = cmds.listConnections(shape,
|
||||
destination=True,
|
||||
type="shadingEngine") or []
|
||||
if len(shading_engines) > 1:
|
||||
invalid.append(shape)
|
||||
|
||||
return invalid
|
||||
|
|
@ -20,11 +20,16 @@ class ValidateNoAnimation(pyblish.api.Validator):
|
|||
optional = True
|
||||
actions = [colorbleed.api.SelectInvalidAction]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Keyframes found: {0}".format(invalid))
|
||||
|
||||
@staticmethod
|
||||
def get_invalid(instance):
|
||||
|
||||
nodes = instance[:]
|
||||
|
||||
if not nodes:
|
||||
return []
|
||||
|
||||
|
|
@ -33,10 +38,3 @@ class ValidateNoAnimation(pyblish.api.Validator):
|
|||
return list(set(cmds.listConnections(curves)))
|
||||
|
||||
return []
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
|
||||
if invalid:
|
||||
raise RuntimeError("Keyframes found: {0}".format(invalid))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
|
|
@ -12,7 +10,7 @@ class ValidateNodeIDs(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
label = 'Node Ids (ID)'
|
||||
label = 'Instance Nodes Have ID'
|
||||
hosts = ['maya']
|
||||
families = ["colorbleed.model",
|
||||
"colorbleed.lookdev",
|
||||
|
|
@ -33,19 +31,11 @@ class ValidateNodeIDs(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
"""Return the member nodes that are invalid"""
|
||||
invalid = list()
|
||||
|
||||
# TODO: Implement check on only nodes like on_save callback.
|
||||
instance_shape = cmds.ls(instance, type="shape")
|
||||
|
||||
# We do want to check the referenced nodes as we it might be
|
||||
# We do want to check the referenced nodes as it might be
|
||||
# part of the end product
|
||||
nodes = lib.filter_out_nodes(set(instance_shape), defaults=True)
|
||||
for node in nodes:
|
||||
if not lib.get_id(node):
|
||||
invalid.append(node)
|
||||
id_nodes = lib.get_id_required_nodes(referenced_nodes=True)
|
||||
invalid = [n for n in instance[:] if n in id_nodes
|
||||
and not lib.get_id(n)]
|
||||
|
||||
return invalid
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
59
colorbleed/plugins/maya/publish/validate_node_ids_related.py
Normal file
59
colorbleed/plugins/maya/publish/validate_node_ids_related.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
import avalon.io as io
|
||||
|
||||
from colorbleed.maya import lib
|
||||
|
||||
|
||||
class ValidateNodeIDsRelated(pyblish.api.InstancePlugin):
|
||||
"""Validate nodes have a related Colorbleed Id to the instance asset
|
||||
|
||||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
label = 'Node Ids Related (ID)'
|
||||
hosts = ['maya']
|
||||
families = ["colorbleed.model",
|
||||
"colorbleed.lookdev",
|
||||
"colorbleed.rig"]
|
||||
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all nodes in instance (including hierarchy)"""
|
||||
# Ensure all nodes have a cbId
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Nodes IDs found that are not related to asset "
|
||||
"'{}' : {}".format(instance.data['asset'],
|
||||
invalid))
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
"""Return the member nodes that are invalid"""
|
||||
invalid = list()
|
||||
|
||||
asset = instance.data['asset']
|
||||
asset_data = io.find_one({"name": asset,
|
||||
"type": "asset"},
|
||||
projection={"_id": True})
|
||||
asset_id = str(asset_data['_id'])
|
||||
|
||||
# We do want to check the referenced nodes as we it might be
|
||||
# part of the end product
|
||||
for node in instance:
|
||||
|
||||
_id = lib.get_id(node)
|
||||
if not _id:
|
||||
continue
|
||||
|
||||
node_asset_id = _id.split(":", 1)[0]
|
||||
if node_asset_id != asset_id:
|
||||
invalid.append(node)
|
||||
|
||||
return invalid
|
||||
|
||||
|
||||
|
||||
|
|
@ -100,7 +100,6 @@ class ValidateRigContents(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
errors = []
|
||||
for node in nodes:
|
||||
print node
|
||||
if node not in hierarchy:
|
||||
errors.append(node)
|
||||
return errors
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue