def repair(cls, instance): renderlayer = instance.data.get("setMembers") with lib.renderlayer(renderlayer): cls.log.info("Enabling Distributed Rendering " "ignore in batch mode..") cmds.setAttr(cls.ignored_attr, True)
def get_invalid(cls, instance): """Get all invalid nodes""" cls.log.info("Validating look content for " "'{}'".format(instance.name)) relationships = instance.data["lookData"]["relationships"] invalid = [] renderlayer = instance.data.get("renderlayer", "defaultRenderLayer") with lib.renderlayer(renderlayer): 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! cls.log.error("Missing sets '{}' for node " "'{}'".format(missing_sets, node)) invalid.append(node) continue # Ensure the node is in the sets that are collected for shaderset, data in relationships.items(): if shaderset not in sets: # no need to check for a set if the node # isn't in it anyway continue member_nodes = [ member['name'] for member in data['members'] ] if node not in member_nodes: # The node is not found in the collected set # relationships cls.log.error("Missing '{}' in collected set node " "'{}'".format(node, shaderset)) invalid.append(node) continue return invalid
def process(self, instance): # Check if Extend Frames is toggled if not instance.data("extendFrames", False): return # Get renderer renderer = cmds.getAttr("defaultRenderGlobals.currentRenderer") self.log.info("Renderer found: {}".format(renderer)) rp_node_types = {"vray": "VRayRenderElement", "arnold": "aiAOV", "redshift": "RedshiftAOV"} if renderer not in rp_node_types.keys(): self.log.error("Unsupported renderer found: '{}'".format(renderer)) return result = [] # Collect all AOVs / Render Elements with lib.renderlayer(instance.name): node_type = rp_node_types[renderer] render_elements = cmds.ls(type=node_type) # Check if AOVs / Render Elements are enabled for element in render_elements: enabled = cmds.getAttr("{}.enabled".format(element)) if not enabled: continue pass_name = self.get_pass_name(renderer, element) render_pass = "******" % (instance.name, pass_name) result.append(render_pass) self.log.info("Found {} render elements / AOVs for " "'{}'".format(len(result), instance.name)) instance.data["renderPasses"] = result
def get_invalid(cls, instance): invalid = False renderer = instance.data['renderer'] layer_node = instance.data['setMembers'] # Collect the filename prefix in the render layer with lib.renderlayer(layer_node): render_attrs = lib.RENDER_ATTRS.get(renderer, lib.RENDER_ATTRS['default']) node = render_attrs["node"] padding_attr = render_attrs["padding"] prefix_attr = render_attrs["prefix"] prefix = cmds.getAttr("{}.{}".format(node, prefix_attr)) padding = cmds.getAttr("{}.{}".format(node, padding_attr)) anim_override = cmds.getAttr("defaultRenderGlobals.animation") if not anim_override: invalid = True cls.log.error("Animation needs to be enabled. Use the same " "frame for start and end to render single frame") fname_prefix = cls.RENDERER_PREFIX.get(renderer, cls.DEFAULT_PREFIX) if prefix != fname_prefix: invalid = True cls.log.error("Wrong file name prefix, expecting %s" % fname_prefix) if padding != cls.DEFAULT_PADDING: invalid = True cls.log.error("Expecting padding of {} ( {} )".format( cls.DEFAULT_PADDING, "0" * cls.DEFAULT_PADDING)) return invalid
def repair(cls, instance): renderer = instance.data['renderer'] layer_node = instance.data['setMembers'] with lib.renderlayer(layer_node): default = lib.RENDER_ATTRS['default'] render_attrs = lib.RENDER_ATTRS.get(renderer, default) # Repair prefix node = render_attrs["node"] prefix_attr = render_attrs["prefix"] fname_prefix = cls.RENDERER_PREFIX.get(renderer, cls.DEFAULT_PREFIX) cmds.setAttr("{}.{}".format(node, prefix_attr), fname_prefix, type="string") # Repair padding padding_attr = render_attrs["padding"] cmds.setAttr("{}.{}".format(node, padding_attr), cls.DEFAULT_PADDING)
def process(self, instance): """Collect the Look in the instance with the correct layer settings""" with lib.renderlayer(instance.data["renderlayer"]): self.collect(instance)
def process(self, context): asset = api.Session["AVALON_ASSET"] filepath = context.data["currentFile"].replace("\\", "/") # Get render globals node try: render_globals = cmds.ls("renderglobalsDefault")[0] except IndexError: self.log.error("Cannot collect renderlayers without " "renderGlobals node") return # Get start and end frame start_frame = self.get_render_attribute("startFrame") end_frame = self.get_render_attribute("endFrame") context.data["startFrame"] = start_frame context.data["endFrame"] = end_frame # Get render layers renderlayers = [i for i in cmds.ls(type="renderLayer") if cmds.getAttr("{}.renderable".format(i)) and not cmds.referenceQuery(i, isNodeReferenced=True)] # Include/exclude default render layer default_layer = "{}.includeDefaultRenderLayer".format(render_globals) use_defaultlayer = cmds.getAttr(default_layer) if not use_defaultlayer: renderlayers = [i for i in renderlayers if not i.endswith("defaultRenderLayer")] # Sort by displayOrder def sort_by_display_order(layer): return cmds.getAttr("%s.displayOrder" % layer) renderlayers = sorted(renderlayers, key=sort_by_display_order) for layer in renderlayers: if layer.endswith("defaultRenderLayer"): layername = "masterLayer" else: layername = layer.split("rs_", 1)[-1] # Get layer specific settings, might be overrides with lib.renderlayer(layer): data = { "subset": layername, "setMembers": layer, "publish": True, "startFrame": self.get_render_attribute("startFrame"), "endFrame": self.get_render_attribute("endFrame"), "byFrameStep": self.get_render_attribute("byFrameStep"), "renderer": self.get_render_attribute("currentRenderer"), # instance subset "family": "Render Layers", "families": ["colorbleed.renderlayer"], "asset": asset, "time": api.time(), "author": context.data["user"], # Add source to allow tracing back to the scene from # which was submitted originally "source": filepath } # Apply each user defined attribute as data for attr in cmds.listAttr(layer, userDefined=True) or list(): try: value = cmds.getAttr("{}.{}".format(layer, attr)) except Exception: # Some attributes cannot be read directly, # such as mesh and color attributes. These # are considered non-essential to this # particular publishing pipeline. value = None data[attr] = value # Include (optional) global settings # TODO(marcus): Take into account layer overrides # Get global overrides and translate to Deadline values overrides = self.parse_options(render_globals) data.update(**overrides) instance = context.create_instance(layername) instance.data.update(data)
def process(self, instance): # Define extract output file path dir_path = self.staging_dir(instance) maya_fname = "{0}.ma".format(instance.name) json_fname = "{0}.json".format(instance.name) # Make texture dump folder maya_path = os.path.join(dir_path, maya_fname) json_path = os.path.join(dir_path, json_fname) self.log.info("Performing extraction..") # Remove all members of the sets so they are not included in the # exported file by accident self.log.info("Extract sets (Maya ASCII) ...") lookdata = instance.data["lookData"] relationships = lookdata["relationships"] sets = relationships.keys() resources = instance.data["resources"] remap = OrderedDict() # needs to be ordered, see color space values for resource in resources: attr = resource['attribute'] remap[attr] = resource['destination'] # Preserve color space values (force value after filepath change) # This will also trigger in the same order at end of context to # ensure after context it's still the original value. color_space_attr = resource['node'] + ".colorSpace" remap[color_space_attr] = cmds.getAttr(color_space_attr) self.log.info("Finished remapping destinations ...") # Extract in correct render layer layer = instance.data.get("renderlayer", "defaultRenderLayer") with lib.renderlayer(layer): # TODO: Ensure membership edits don't become renderlayer overrides with lib.empty_sets(sets, force=True): # To avoid Maya trying to automatically remap the file # textures relative to the `workspace -directory` we force # it to a fake temporary workspace. This fixes textures # getting incorrectly remapped. (LKD-17, PLN-101) with no_workspace_dir(): with lib.attribute_values(remap): with avalon.maya.maintained_selection(): cmds.select(sets, noExpand=True) cmds.file(maya_path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=False, channels=True, constraints=True, expressions=True, constructionHistory=True) # Write the JSON data self.log.info("Extract json..") data = { "attributes": lookdata["attributes"], "relationships": relationships } with open(json_path, "w") as f: json.dump(data, f) if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(maya_fname) instance.data["files"].append(json_fname) self.log.info("Extracted instance '%s' to: %s" % (instance.name, maya_path))