mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
Merged in Aardschok/config/0004 (pull request #7)
0004 Approved-by: Wijnand Koreman <wikoreman@gmail.com>
This commit is contained in:
commit
f6539d4e33
18 changed files with 272 additions and 211 deletions
|
|
@ -8,6 +8,7 @@ from pyblish import api as pyblish
|
|||
from maya import cmds
|
||||
|
||||
from . import menu
|
||||
from . import lib
|
||||
|
||||
PARENT_DIR = os.path.dirname(__file__)
|
||||
PACKAGE_DIR = os.path.dirname(PARENT_DIR)
|
||||
|
|
@ -96,31 +97,19 @@ def on_save(_):
|
|||
|
||||
avalon.logger.info("Running callback on save..")
|
||||
|
||||
# establish set of nodes to ignore
|
||||
ignore = set(["initialShadingGroup", "initialParticleSE"])
|
||||
ignore |= set(cmds.ls(long=True, readOnly=True))
|
||||
ignore |= set(cmds.ls(long=True, lockedNodes=True))
|
||||
|
||||
types = ["shadingEngine", "file", "mesh", "nurbsCurve"]
|
||||
|
||||
# the items which need to pass the id to their parent
|
||||
nodes = set(cmds.ls(type=types, long=True))
|
||||
|
||||
# Add the collected transform to the nodes
|
||||
transforms = cmds.listRelatives(list(nodes),
|
||||
parent=True,
|
||||
fullPath=True) or []
|
||||
|
||||
nodes |= set(transforms)
|
||||
|
||||
# Remove the ignored nodes
|
||||
nodes -= ignore
|
||||
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)
|
||||
|
||||
# Lead with asset ID from the database
|
||||
asset = os.environ["AVALON_ASSET"]
|
||||
asset_id = io.find_one({"type": "asset", "name": asset})
|
||||
asset_id = io.find_one({"type": "asset", "name": asset},
|
||||
projection={"_id": True})
|
||||
|
||||
# generate the ids
|
||||
for node in nodes:
|
||||
_set_uuid(str(asset_id["_id"]), node)
|
||||
|
||||
for node in nodes:
|
||||
print node
|
||||
_set_uuid(str(asset_id["_id"]), node)
|
||||
|
|
|
|||
|
|
@ -613,7 +613,43 @@ def remap_resource_nodes(resources, folder=None):
|
|||
cmds.file(save=True, type="mayaAscii")
|
||||
|
||||
|
||||
def _get_id(node):
|
||||
def filter_out_nodes(nodes, defaults=False, 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
|
||||
Returns:
|
||||
nodes (list): 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
|
||||
|
||||
ignore = set()
|
||||
if referenced_nodes:
|
||||
ignore |= set(cmds.ls(long=True, referencedNodes=referenced_nodes))
|
||||
|
||||
if defaults:
|
||||
ignore |= set(cmds.ls(long=True, defaultNodes=defaults))
|
||||
|
||||
# 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
|
||||
transforms = cmds.listRelatives(dag,
|
||||
parent=True,
|
||||
fullPath=True) or []
|
||||
|
||||
nodes |= set(transforms)
|
||||
nodes -= ignore # Remove the ignored nodes
|
||||
|
||||
return nodes
|
||||
|
||||
|
||||
def get_id(node):
|
||||
"""
|
||||
Get the `cbId` attribute of the given node
|
||||
Args:
|
||||
|
|
@ -817,7 +853,7 @@ def assign_look(nodes, subset="lookDefault"):
|
|||
# Group all nodes per asset id
|
||||
grouped = defaultdict(list)
|
||||
for node in nodes:
|
||||
colorbleed_id = _get_id(node)
|
||||
colorbleed_id = get_id(node)
|
||||
if not colorbleed_id:
|
||||
continue
|
||||
|
||||
|
|
@ -877,17 +913,17 @@ def apply_shaders(relationships, shadernodes, nodes):
|
|||
shader_sets = relationships.get("sets", [])
|
||||
|
||||
shading_engines = cmds.ls(shadernodes, type="objectSet", long=True)
|
||||
assert len(shading_engines) > 0, ("Error in retrieving shading engines "
|
||||
assert len(shading_engines) > 0, ("Error in retrieving objectSets "
|
||||
"from reference")
|
||||
|
||||
# region compute lookup
|
||||
ns_nodes_by_id = defaultdict(list)
|
||||
for node in nodes:
|
||||
ns_nodes_by_id[_get_id(node)].append(node)
|
||||
ns_nodes_by_id[get_id(node)].append(node)
|
||||
|
||||
shading_engines_by_id = defaultdict(list)
|
||||
for shad in shading_engines:
|
||||
shading_engines_by_id[_get_id(shad)].append(shad)
|
||||
shading_engines_by_id[get_id(shad)].append(shad)
|
||||
# endregion
|
||||
|
||||
# region assign
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
|
||||
class ValidateNodeIds(pyblish.api.InstancePlugin):
|
||||
"""Validate nodes have colorbleed id attributes
|
||||
|
||||
All look sets should have id attributes.
|
||||
|
||||
"""
|
||||
|
||||
label = 'Node Id Attributes'
|
||||
families = ['colorbleed.look', 'colorbleed.model']
|
||||
hosts = ['maya']
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
@staticmethod
|
||||
def get_invalid(instance):
|
||||
import maya.cmds as cmds
|
||||
|
||||
nodes = instance.data["setMembers"]
|
||||
|
||||
# Ensure all nodes have a cbId
|
||||
data_id = {}
|
||||
invalid = []
|
||||
for node in nodes:
|
||||
try:
|
||||
uuid = cmds.getAttr("{}.cbId".format(node))
|
||||
data_id[uuid] = node
|
||||
if uuid in data_id:
|
||||
invalid.append(node)
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
return invalid
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all meshes"""
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
|
||||
if invalid:
|
||||
raise RuntimeError("Nodes found with invalid"
|
||||
"asset IDs: {0}".format(invalid))
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
from maya import cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.maya.lib as lib
|
||||
from cb.utils.maya import context, shaders
|
||||
import cbra.utils.maya.node_uuid as id_utils
|
||||
|
||||
SHAPE_ATTRS = ["castsShadows",
|
||||
"receiveShadows",
|
||||
|
|
@ -13,6 +13,7 @@ SHAPE_ATTRS = ["castsShadows",
|
|||
"visibleInRefractions",
|
||||
"doubleSided",
|
||||
"opposite"]
|
||||
|
||||
SHAPE_ATTRS = set(SHAPE_ATTRS)
|
||||
|
||||
|
||||
|
|
@ -167,10 +168,10 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
if objset in sets:
|
||||
continue
|
||||
|
||||
unique_id = cmds.getAttr("%s.cbId" % objset)
|
||||
sets[objset] = {"name": objset,
|
||||
"uuid": unique_id,
|
||||
"uuid": lib.get_id(objset),
|
||||
"members": list()}
|
||||
|
||||
return sets
|
||||
|
||||
def get_related_sets(self, node, view_sets):
|
||||
|
|
@ -185,8 +186,12 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
Args:
|
||||
node (str): name of the current not to check
|
||||
"""
|
||||
defaults = ["initialShadingGroup",
|
||||
"defaultLightSet",
|
||||
"defaultObjectSet"]
|
||||
|
||||
ignored = ["pyblish.avalon.instance", "pyblish.avalon.container"]
|
||||
ignored = ["pyblish.avalon.instance",
|
||||
"pyblish.avalon.container"]
|
||||
|
||||
related_sets = cmds.listSets(object=node, extendToShape=False)
|
||||
if not related_sets:
|
||||
|
|
@ -206,6 +211,7 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
deformer_sets = cmds.listSets(object=node,
|
||||
extendToShape=False,
|
||||
type=2) or []
|
||||
|
||||
deformer_sets = set(deformer_sets) # optimize lookup
|
||||
sets = [s for s in sets if s not in deformer_sets]
|
||||
|
||||
|
|
@ -215,8 +221,9 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
# Ignore viewport filter view sets (from isolate select and
|
||||
# viewports)
|
||||
sets = [s for s in sets if s not in view_sets]
|
||||
sets = [s for s in sets if s not in defaults]
|
||||
|
||||
self.log.info("Found sets %s for %s" % (related_sets, node))
|
||||
self.log.info("Found sets %s for %s" % (sets, node))
|
||||
|
||||
return sets
|
||||
|
||||
|
|
@ -263,21 +270,14 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
if member in [m["name"] for m in objset_members]:
|
||||
return
|
||||
|
||||
# check node type, if mesh get parent! makes assigning shaders easier
|
||||
# check node type, if mesh get parent!
|
||||
if cmds.nodeType(node) == "mesh":
|
||||
parent = cmds.listRelatives(node, parent=True, fullPath=True)
|
||||
# a mesh NEEDS to have a parent in Maya logic, no reason for
|
||||
# assertions or extra checking
|
||||
parent = parent[0]
|
||||
if cmds.attributeQuery("cbId", node=parent, exists=True):
|
||||
node = parent
|
||||
else:
|
||||
self.log.error("Transform group of mesh '{}' has no attribute "
|
||||
"'cbId', this is manditory")
|
||||
return
|
||||
# A mesh will always have a transform node in Maya logic
|
||||
node = cmds.listRelatives(node, parent=True, fullPath=True)[0]
|
||||
|
||||
if verbose:
|
||||
self.log.debug("Such as %s.." % member)
|
||||
if not cmds.attributeQuery("cbId", node=node, exists=True):
|
||||
self.log.error("Node '{}' has no attribute 'cbId'".format(node))
|
||||
return
|
||||
|
||||
member_data = {"name": node,
|
||||
"uuid": cmds.getAttr("{}.cbId".format(node))}
|
||||
|
|
@ -321,7 +321,7 @@ class CollectLook(pyblish.api.InstancePlugin):
|
|||
node_attributes[attr] = cmds.getAttr(attribute)
|
||||
|
||||
attributes.append({"name": node,
|
||||
"uuid": id_utils.get_id(node),
|
||||
"uuid": cmds.getAttr("{}.cbId".format(node)),
|
||||
"attributes": node_attributes})
|
||||
|
||||
return attributes
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ class ValidateFrameRange(pyblish.api.InstancePlugin):
|
|||
|
||||
"""
|
||||
|
||||
label = "Validate Frame Range"
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
|
||||
label = "Frame Range"
|
||||
families = ["colorbleed.animation",
|
||||
"colorbleed.render"]
|
||||
|
||||
def process(self, instance):
|
||||
|
||||
|
|
|
|||
|
|
@ -11,28 +11,72 @@ class ValidateLookContents(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Contents'
|
||||
actions = [colorbleed.api.SelectInvalidAction]
|
||||
|
||||
invalid = []
|
||||
errors = []
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all the nodes in the instance"""
|
||||
|
||||
error = False
|
||||
|
||||
attributes = ["sets",
|
||||
"relationships",
|
||||
"attributes"]
|
||||
|
||||
if not instance[:]:
|
||||
raise RuntimeError("Instance is empty")
|
||||
|
||||
# Required look data
|
||||
self.get_invalid(instance)
|
||||
|
||||
if self.errors:
|
||||
error_string = "\n".join(self.errors)
|
||||
raise RuntimeError("Invalid look content. "
|
||||
"Errors : {}".format(error_string))
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
invalid_attr = list(cls.validate_lookdata_attributes(instance))
|
||||
invalid_rels = list(cls.validate_relationships(instance))
|
||||
|
||||
invalid = invalid_attr + invalid_rels
|
||||
|
||||
return invalid
|
||||
|
||||
@classmethod
|
||||
def validate_lookdata_attributes(cls, instance):
|
||||
"""Check if the lookData has the required attributes
|
||||
|
||||
Args:
|
||||
instance
|
||||
|
||||
"""
|
||||
|
||||
invalid = set()
|
||||
|
||||
attributes = ["sets", "relationships", "attributes"]
|
||||
lookdata = instance.data["lookData"]
|
||||
for attr in attributes:
|
||||
if attr not in lookdata:
|
||||
self.log.error("No %s found in data" % attr)
|
||||
error = True
|
||||
cls.errors.append("Look Data has no attribute "
|
||||
"'{}'".format(attr))
|
||||
invalid.add(instance.name)
|
||||
|
||||
if error:
|
||||
raise RuntimeError("Invalid look content. See log for details.")
|
||||
return invalid
|
||||
|
||||
@classmethod
|
||||
def validate_relationships(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)
|
||||
|
||||
return invalid
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class ValidateLookDefaultShadersConnections(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Default Shader Connections'
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class ValidateLookDeformedShapes(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look deformed shapes'
|
||||
actions = [colorbleed.api.SelectInvalidAction, CopyUUIDsFromHistory]
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class ValidateLookIgnoreColorSpace(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look RAW Ignore color space'
|
||||
actions = [colorbleed.api.SelectInvalidAction]
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateLookMembersNodeIds(pyblish.api.InstancePlugin):
|
||||
class ValidateLookMembersHaveId(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.
|
||||
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
|
||||
|
|
@ -17,35 +16,12 @@ class ValidateLookMembersNodeIds(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Members Id Attributes'
|
||||
label = 'Look Members Have ID Attribute'
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
@staticmethod
|
||||
def get_invalid(instance):
|
||||
|
||||
# Get all members from the sets
|
||||
members = []
|
||||
relations = instance.data["lookData"]["relationships"]
|
||||
for sg in relations:
|
||||
sg_members = sg['members']
|
||||
sg_members = [member['name'] for member in sg_members]
|
||||
members.extend(sg_members)
|
||||
|
||||
# Get all sets
|
||||
|
||||
members = list(set(members))
|
||||
|
||||
# Ensure all nodes have a cbId
|
||||
invalid = list()
|
||||
for node in members:
|
||||
if not cmds.getAttr("{}.cbId".format(node)):
|
||||
invalid.append(node)
|
||||
|
||||
return invalid
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all meshes"""
|
||||
|
||||
|
|
@ -53,3 +29,24 @@ class ValidateLookMembersNodeIds(pyblish.api.InstancePlugin):
|
|||
if invalid:
|
||||
raise RuntimeError("Members found without "
|
||||
"asset IDs: {0}".format(invalid))
|
||||
|
||||
@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)
|
||||
|
||||
# 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)
|
||||
|
||||
return invalid
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ def get_unique_id(node):
|
|||
return unique_id
|
||||
|
||||
|
||||
class ValidateLookMembersUnique(pyblish.api.InstancePlugin):
|
||||
"""Validate members of look are unique.
|
||||
class ValidateNonDuplicateRelationshipMembers(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.
|
||||
|
||||
|
|
@ -29,9 +30,10 @@ class ValidateLookMembersUnique(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
families = ['colorbleed.look']
|
||||
label = 'Non Duplicate Relationship Members (ID)'
|
||||
hosts = ['maya']
|
||||
label = 'Look Members Unique'
|
||||
families = ['colorbleed.lookdev']
|
||||
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
|
|
@ -42,8 +44,7 @@ class ValidateLookMembersUnique(pyblish.api.InstancePlugin):
|
|||
members = []
|
||||
relationships = instance.data["lookData"]["relationships"]
|
||||
for sg in relationships:
|
||||
sg_members = sg['members']
|
||||
sg_members = [member['name'] for member in sg_members]
|
||||
sg_members = [member['name'] for member in sg['members']]
|
||||
members.extend(sg_members)
|
||||
|
||||
# Ensure we don't have components but the objects
|
||||
|
|
@ -68,9 +69,7 @@ class ValidateLookMembersUnique(pyblish.api.InstancePlugin):
|
|||
def process(self, instance):
|
||||
"""Process all meshes"""
|
||||
|
||||
print self.actions
|
||||
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Members found without "
|
||||
"asset IDs: {0}".format(invalid))
|
||||
raise RuntimeError("Members found without asset IDs: "
|
||||
"{0}".format(invalid))
|
||||
|
|
|
|||
|
|
@ -22,65 +22,51 @@ class ValidateLookNoDefaultShaders(pyblish.api.InstancePlugin):
|
|||
|
||||
"""
|
||||
|
||||
order = colorbleed.api.ValidateContentsOrder
|
||||
families = ['colorbleed.look']
|
||||
order = colorbleed.api.ValidateContentsOrder + 0.01
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look No Default Shaders'
|
||||
actions = [colorbleed.api.SelectInvalidAction]
|
||||
|
||||
@classmethod
|
||||
def get_invalid_sets(cls, instance):
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
invalid = []
|
||||
disallowed = ["lambert1",
|
||||
"initialShadingGroup",
|
||||
"initialParticleSE",
|
||||
"particleCloud1"]
|
||||
disallowed = set(disallowed)
|
||||
|
||||
# Check among the sets
|
||||
lookdata = instance.data["lookData"]
|
||||
sets = lookdata['sets']
|
||||
lookup = set(sets)
|
||||
intersect = lookup.intersection(disallowed)
|
||||
if intersect:
|
||||
cls.log.error("Default shaders found in the "
|
||||
"look: {0}".format(list(intersect)))
|
||||
return list(intersect)
|
||||
setmembers = instance.data["setMembers"]
|
||||
members = cmds.listRelatives(setmembers,
|
||||
allDescendents=True,
|
||||
type="shape")
|
||||
|
||||
# Check among history/inputs of the sets
|
||||
history = cmds.listHistory(sets) or []
|
||||
lookup = set(history)
|
||||
for member in members:
|
||||
|
||||
intersect = lookup.intersection(disallowed)
|
||||
if intersect:
|
||||
cls.log.error("Default shaders found in the history of the "
|
||||
"look: {0}".format(list(intersect)))
|
||||
return list(intersect)
|
||||
# get connection
|
||||
# listConnections returns a list or None
|
||||
shading_engine = cmds.listConnections(member, type="shadingEngine")
|
||||
if not shading_engine:
|
||||
cls.log.error("Detected shape without shading engine : "
|
||||
"'{}'".format(member))
|
||||
invalid.append(member)
|
||||
continue
|
||||
|
||||
return list()
|
||||
|
||||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
shaders = cls.get_invalid_sets(instance)
|
||||
nodes = instance[:]
|
||||
|
||||
# Get members of the shaders
|
||||
all = set()
|
||||
for shader in shaders:
|
||||
members = cmds.sets(shader, query=True) or []
|
||||
members = cmds.ls(members, long=True)
|
||||
all.update(members)
|
||||
|
||||
# Get the instance nodes among the shader members
|
||||
invalid = all.intersection(nodes)
|
||||
invalid = list(invalid)
|
||||
# retrieve the shading engine out of the list
|
||||
shading_engine = shading_engine[0]
|
||||
if shading_engine in disallowed:
|
||||
cls.log.error("Member connected to a disallows objectSet: "
|
||||
"'{}'".format(member))
|
||||
else:
|
||||
continue
|
||||
|
||||
return invalid
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all the nodes in the instance"""
|
||||
|
||||
sets = self.get_invalid_sets(instance)
|
||||
# sets = self.get_invalid_sets(instance)
|
||||
sets = self.get_invalid(instance)
|
||||
if sets:
|
||||
raise RuntimeError("Invalid shaders found: {0}".format(sets))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
|
|||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
families = ['colorbleed.look']
|
||||
families = ['colorbleed.lookdev']
|
||||
hosts = ['maya']
|
||||
label = 'Look Id Unique Attributes'
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
|
|
@ -28,8 +28,8 @@ class ValidateLookNodeUniqueIds(pyblish.api.InstancePlugin):
|
|||
invalid = list()
|
||||
for node in nodes:
|
||||
unique_id = None
|
||||
if cmds.attributeQuery("mbId", node=node, exists=True):
|
||||
unique_id = cmds.getAttr("{}.mbId".format(node))
|
||||
if cmds.attributeQuery("cbId", node=node, exists=True):
|
||||
unique_id = cmds.getAttr("{}.cbId".format(node))
|
||||
if not unique_id:
|
||||
continue
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ class ValidateModelContent(pyblish.api.InstancePlugin):
|
|||
@classmethod
|
||||
def get_invalid(cls, instance):
|
||||
|
||||
pprint.pprint(instance.data)
|
||||
|
||||
content_instance = instance.data.get("setMembers", None)
|
||||
if not content_instance:
|
||||
cls.log.error("Instance has no nodes!")
|
||||
|
|
|
|||
51
colorbleed/plugins/maya/publish/validate_node_ids.py
Normal file
51
colorbleed/plugins/maya/publish/validate_node_ids.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
|
||||
from colorbleed.maya import lib
|
||||
|
||||
|
||||
class ValidateNodeIDs(pyblish.api.InstancePlugin):
|
||||
"""Validate nodes have a Colorbleed Id
|
||||
|
||||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
label = 'Node Ids (ID)'
|
||||
hosts = ['maya']
|
||||
families = ["colorbleed.model",
|
||||
"colorbleed.lookdev",
|
||||
"colorbleed.rig"]
|
||||
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
||||
def process(self, instance):
|
||||
"""Process all meshes"""
|
||||
|
||||
# Ensure all nodes have a cbId
|
||||
invalid = self.get_invalid(instance)
|
||||
if invalid:
|
||||
raise RuntimeError("Nodes found without "
|
||||
"IDs: {0}".format(invalid))
|
||||
|
||||
@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
|
||||
# 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)
|
||||
|
||||
return invalid
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,20 +1,22 @@
|
|||
from collections import defaultdict
|
||||
|
||||
import maya.cmds as cmds
|
||||
|
||||
import pyblish.api
|
||||
import colorbleed.api
|
||||
import colorbleed.maya.lib as lib
|
||||
|
||||
|
||||
class ValidateUniqueNodeIds(pyblish.api.InstancePlugin):
|
||||
"""Validate nodes have colorbleed id attributes"""
|
||||
class ValidateNonDuplicateInstanceMembers(pyblish.api.InstancePlugin):
|
||||
"""Validate the nodes in the instance have a unique Colorbleed Id
|
||||
|
||||
Here we ensure that what has been added to the instance is unique
|
||||
"""
|
||||
|
||||
order = colorbleed.api.ValidatePipelineOrder
|
||||
label = 'Unique Id Attributes'
|
||||
label = 'Non Duplicate Instance Members (ID)'
|
||||
hosts = ['maya']
|
||||
families = ['colorbleed.model',
|
||||
'colorbleed.lookdev',
|
||||
'colorbleed.rig']
|
||||
families = ["colorbleed.model",
|
||||
"colorbleed.lookdev",
|
||||
"colorbleed.rig"]
|
||||
|
||||
actions = [colorbleed.api.SelectInvalidAction,
|
||||
colorbleed.api.GenerateUUIDsOnInvalidAction]
|
||||
|
|
@ -23,15 +25,12 @@ class ValidateUniqueNodeIds(pyblish.api.InstancePlugin):
|
|||
def get_invalid_dict(cls, instance):
|
||||
"""Return a dictionary mapping of id key to list of member nodes"""
|
||||
|
||||
uuid_attr = "cbId"
|
||||
|
||||
# Collect each id with their members
|
||||
ids = defaultdict(list)
|
||||
for member in instance:
|
||||
if not cmds.attributeQuery(uuid_attr, node=member, exists=True):
|
||||
object_id = lib.get_id(member)
|
||||
if not object_id:
|
||||
continue
|
||||
|
||||
object_id = cmds.getAttr("{}.{}".format(member, uuid_attr))
|
||||
ids[object_id].append(member)
|
||||
|
||||
# Skip those without IDs (if everything should have an ID that should
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ import os
|
|||
import avalon.io as io
|
||||
|
||||
|
||||
class CollectResourceDestination(pyblish.api.InstancePlugin):
|
||||
class CollectAssumedDestination(pyblish.api.InstancePlugin):
|
||||
"""This plug-ins displays the comment dialog box per default"""
|
||||
|
||||
label = "Collect Resource Destination"
|
||||
label = "Collect Assumed Destination"
|
||||
order = pyblish.api.CollectorOrder + 0.499
|
||||
|
||||
def process(self, instance):
|
||||
|
|
@ -63,15 +63,22 @@ class CollectResourceDestination(pyblish.api.InstancePlugin):
|
|||
|
||||
# get all the stuff from the database
|
||||
subset_name = instance.data["subset"]
|
||||
asset_name = instance.data["asset"]
|
||||
project_name = os.environ["AVALON_PROJECT"]
|
||||
|
||||
project = io.find_one({"type": "project",
|
||||
"name": project_name},
|
||||
projection={"config": True})
|
||||
|
||||
template = project["config"]["template"]["publish"]
|
||||
|
||||
asset = io.find_one({"type": "asset",
|
||||
"name": asset_name,
|
||||
"parent": project["_id"]})
|
||||
|
||||
subset = io.find_one({"type": "subset",
|
||||
"name": subset_name})
|
||||
"name": subset_name,
|
||||
"parent": asset["_id"]})
|
||||
|
||||
# assume there is no version yet, we start at `1`
|
||||
version_number = 1
|
||||
|
|
@ -85,7 +92,7 @@ class CollectResourceDestination(pyblish.api.InstancePlugin):
|
|||
template_data = {"root": os.environ["AVALON_ROOT"],
|
||||
"project": project_name,
|
||||
"silo": os.environ["AVALON_SILO"],
|
||||
"asset": instance.data["asset"],
|
||||
"asset": asset_name,
|
||||
"subset": subset_name,
|
||||
"version": version_number,
|
||||
"representation": "TEMP"}
|
||||
|
|
@ -4,7 +4,7 @@ import pyblish.api
|
|||
class CollectMindbenderComment(pyblish.api.ContextPlugin):
|
||||
"""This plug-ins displays the comment dialog box per default"""
|
||||
|
||||
label = "Collect Mindbender Time"
|
||||
label = "Collect Comment"
|
||||
order = pyblish.api.CollectorOrder
|
||||
|
||||
def process(self, context):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue