From e3c58662b9cf05211d35c5282e5d25a2fb5b46f0 Mon Sep 17 00:00:00 2001 From: Toke Stuart Jepsen Date: Tue, 7 Feb 2023 18:13:25 +0000 Subject: [PATCH] Working loading proxy --- .../maya/plugins/load/load_arnold_standin.py | 117 ++++++++++++++---- 1 file changed, 91 insertions(+), 26 deletions(-) diff --git a/openpype/hosts/maya/plugins/load/load_arnold_standin.py b/openpype/hosts/maya/plugins/load/load_arnold_standin.py index 50b72d87e8..57e1d8a6e0 100644 --- a/openpype/hosts/maya/plugins/load/load_arnold_standin.py +++ b/openpype/hosts/maya/plugins/load/load_arnold_standin.py @@ -9,7 +9,9 @@ from openpype.pipeline import ( load, get_representation_path ) -from openpype.hosts.maya.api.lib import unique_namespace +from openpype.hosts.maya.api.lib import ( + unique_namespace, get_attribute_input, maintained_selection +) from openpype.hosts.maya.api.pipeline import containerise @@ -22,18 +24,6 @@ def is_sequence(files): return sequence -def set_color(node, context): - project_name = context["project"]["name"] - settings = get_project_settings(project_name) - colors = settings['maya']['load']['colors'] - color = colors.get('ass') - if color is not None: - cmds.setAttr(node + ".useOutlinerColor", True) - cmds.setAttr( - node + ".outlinerColor", color[0], color[1], color[2] - ) - - class ArnoldStandinLoader(load.LoaderPlugin): """Load file as Arnold standin""" @@ -62,24 +52,35 @@ class ArnoldStandinLoader(load.LoaderPlugin): label = "{}:{}".format(namespace, name) root = cmds.group(name=label, empty=True) - set_color(root, context) + # Set color. + project_name = context["project"]["name"] + settings = get_project_settings(project_name) + colors = settings['maya']['load']['colors'] + color = colors.get('ass') + if color is not None: + cmds.setAttr(root + ".useOutlinerColor", True) + cmds.setAttr( + root + ".outlinerColor", color[0], color[1], color[2] + ) - # Create transform with shape - transform_name = label + "_standin" + with maintained_selection(): + # Create transform with shape + transform_name = label + "_standin" - standinShape = mtoa.ui.arnoldmenu.createStandIn() - standin = cmds.listRelatives(standinShape, parent=True)[0] - standin = cmds.rename(standin, transform_name) - standinShape = cmds.listRelatives(standin, shapes=True)[0] + standinShape = mtoa.ui.arnoldmenu.createStandIn() + standin = cmds.listRelatives(standinShape, parent=True)[0] + standin = cmds.rename(standin, transform_name) + standinShape = cmds.listRelatives(standin, shapes=True)[0] - cmds.parent(standin, root) + cmds.parent(standin, root) - # Set the standin filepath - cmds.setAttr(standinShape + ".dso", self.fname, type="string") - sequence = is_sequence(os.listdir(os.path.dirname(self.fname))) - cmds.setAttr(standinShape + ".useFrameExtension", sequence) + # Set the standin filepath + dso_path, operator = self._setup_proxy(standinShape, self.fname) + cmds.setAttr(standinShape + ".dso", dso_path, type="string") + sequence = is_sequence(os.listdir(os.path.dirname(self.fname))) + cmds.setAttr(standinShape + ".useFrameExtension", sequence) - nodes = [root, standin] + nodes = [root, standin, operator] self[:] = nodes return containerise( @@ -89,6 +90,70 @@ class ArnoldStandinLoader(load.LoaderPlugin): context=context, loader=self.__class__.__name__) + def get_next_free_multi_index(self, attr_name): + """Find the next unconnected multi index at the input attribute.""" + + start_index = 0 + # Assume a max of 10 million connections + while start_index < 10000000: + connection_info = cmds.connectionInfo( + "{}[{}]".format(attr_name, start_index), + sourceFromDestination=True + ) + if len(connection_info or []) == 0: + return start_index + start_index += 1 + + def _setup_proxy(self, shape, path): + basename_split = os.path.basename(path).split(".") + proxy_basename = ( + basename_split[0] + "_proxy." + ".".join(basename_split[1:]) + ) + proxy_path = "/".join( + [os.path.dirname(path), "resources", proxy_basename] + ) + + if not os.path.exists(proxy_path): + self.log.error("Proxy files do not exist. Skipping proxy setup.") + return path + + options_node = "defaultArnoldRenderOptions" + merge_operator = get_attribute_input(options_node + ".operator") + if merge_operator is None: + merge_operator = cmds.createNode("aiMerge") + cmds.connectAttr( + merge_operator + ".message", options_node + ".operator" + ) + + merge_operator = merge_operator.split(".")[0] + + string_replace_operator = cmds.createNode("aiStringReplace") + cmds.setAttr( + string_replace_operator + ".selection", + "*.(@node=='procedural')", + type="string" + ) + cmds.setAttr( + string_replace_operator + ".match", + "resources/" + proxy_basename, + type="string" + ) + cmds.setAttr( + string_replace_operator + ".replace", + os.path.basename(path), + type="string" + ) + + cmds.connectAttr( + string_replace_operator + ".out", + "{}.inputs[{}]".format( + merge_operator, + self.get_next_free_multi_index(merge_operator + ".inputs") + ) + ) + + return proxy_path, string_replace_operator + def update(self, container, representation): # Update the standin standins = list()