diff --git a/colorbleed/plugins/maya/publish/collect_look_textures.py b/colorbleed/plugins/maya/publish/collect_look_textures.py index 772deaeba1..586e264307 100644 --- a/colorbleed/plugins/maya/publish/collect_look_textures.py +++ b/colorbleed/plugins/maya/publish/collect_look_textures.py @@ -31,26 +31,11 @@ class SelectTextureNodesAction(pyblish.api.Action): # Apply pyblish.logic to get the instances for the plug-in instances = pyblish.api.instances_by_plugin(instances, plugin) - def is_texture_resource(resource): - """Return whether the resource is a texture""" - - tags = resource.get("tags", []) - if not TAGS_LOOKUP.issubset(tags): - return False - - if resource.get("subfolder", None) != "textures": - return False - - if "node" not in resource: - return False - - return True - # Get the texture nodes from the instances nodes = [] for instance in instances: for resource in instance.data.get("resources", []): - if is_texture_resource(resource): + if self.is_texture_resource(resource): node = resource['node'] nodes.append(node) @@ -64,6 +49,21 @@ class SelectTextureNodesAction(pyblish.api.Action): self.log.info("No texture nodes found.") cmds.select(deselect=True) + def is_texture_resource(self, resource): + """Return whether the resource is a texture""" + + tags = resource.get("tags", []) + if not TAGS_LOOKUP.issubset(tags): + return False + + if resource.get("subfolder", None) != "textures": + return False + + if "node" not in resource: + return False + + return True + class CollectLookTextures(pyblish.api.InstancePlugin): """Collect look textures @@ -93,43 +93,61 @@ class CollectLookTextures(pyblish.api.InstancePlugin): resources = instance.data.get("resources", []) for node in files: - - attribute = "%s.fileTextureName" % node - source = cmds.getAttr(attribute) - - # Get the computed file path (e.g. the one with the pattern - # in it) So we can reassign it this computed file path whenever - # we need to. - computed_attribute = "%s.computedFileTextureNamePattern" % node - computed_source = cmds.getAttr(computed_attribute) - if source != computed_source: - if verbose: - self.log.debug("File node computed pattern differs from " - "original pattern: {0} " - "({1} -> {2})".format(node, - source, - computed_source)) - - # We replace backslashes with forward slashes because V-Ray - # can't handle the UDIM files with the backslashes in the - # paths as the computed patterns - source = computed_source.replace("\\", "/") - - files = shader.get_file_node_files(node) - if not files: - self.log.error("File node does not have a texture set: " - "{0}".format(node)) - - # Define the resource - resource = {"tags": TAGS[:], - "node": node, - "attribute": attribute, - "source": source, # required for resources - "files": files, # required for resources - "subfolder": "textures" # optional for resources - } - + resource = self.collect_resources(node, verbose) + if not resource: + continue resources.append(resource) # Store resources instance.data['resources'] = resources + + def collect_resources(self, node, verbose=False): + """Collect the link to the file(s) used (resource) + Args: + node (str): name of the node + verbose (bool): enable debug information + + Returns: + dict + """ + + attribute = "{}.fileTextureName".format(node) + source = cmds.getAttr(attribute) + + # Get the computed file path (e.g. the one with the pattern + # in it) So we can reassign it this computed file path whenever + # we need to. + + computed_attribute = "{}.computedFileTextureNamePattern".format(node) + computed_source = cmds.getAttr(computed_attribute) + if source != computed_source: + if verbose: + self.log.debug("File node computed pattern differs from " + "original pattern: {0} " + "({1} -> {2})".format(node, + source, + computed_source)) + + # We replace backslashes with forward slashes because V-Ray + # can't handle the UDIM files with the backslashes in the + # paths as the computed patterns + source = computed_source.replace("\\", "/") + + files = shader.get_file_node_files(node) + if not files: + self.log.error("File node does not have a texture set: " + "{0}".format(node)) + return + + # Define the resource + resource = {"tags": TAGS[:], + "node": node, + "attribute": attribute, + "source": source, # required for resources + "files": files, # required for resources + "subfolder": "textures" # optional for resources + } + + return resource + + diff --git a/colorbleed/plugins/maya/publish/validate_look_contents.py b/colorbleed/plugins/maya/publish/validate_look_contents.py index 6c91f83206..f117dad794 100644 --- a/colorbleed/plugins/maya/publish/validate_look_contents.py +++ b/colorbleed/plugins/maya/publish/validate_look_contents.py @@ -18,10 +18,20 @@ class ValidateLookContents(pyblish.api.InstancePlugin): def process(self, instance): """Process all the nodes in the instance""" + error = False + + attributes = ["lookSets", + "lookSetRelations", + "lookAttributes"] + if not instance[:]: raise RuntimeError("Instance is empty") # Required look data - assert "lookSets" in instance.data - assert "lookSetRelations" in instance.data - assert "lookAttributes" in instance.data + for attr in attributes: + if attr not in instance.data: + self.log.error("No %s found in data" % attr) + error = True + + if error: + raise RuntimeError("Invalid look content. See log for details.")