def load(self, context, name=None, namespace=None, data=None): import maya.cmds as cmds from avalon import maya from avalon.maya import lib choice = self.display_warning() if choice is False: return asset = context['asset'] namespace = namespace or lib.unique_namespace( asset["name"] + "_", prefix="_" if asset["name"][0].isdigit() else "", suffix="_", ) with maya.maintained_selection(): cmds.file(self.fname, i=True, namespace=namespace, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) # We do not containerize imported content, it remains unmanaged return
def _post_process(self, name, namespace, context, data): # TODO(marcus): We are hardcoding the name "out_SET" here. # Better register this keyword, so that it can be used # elsewhere, such as in the Integrator plug-in, # without duplication. output = next((node for node in self if node.endswith("out_SET")), None) controls = next( (node for node in self if node.endswith("controls_SET")), None) assert output, "No out_SET in rig, this is a bug." assert controls, "No controls_SET in rig, this is a bug." # Find the roots amongst the loaded nodes roots = cmds.ls(self[:], assemblies=True, long=True) assert roots, "No root nodes in rig, this is a bug." asset = api.Session["AVALON_ASSET"] dependency = str(context["representation"]["_id"]) # Create the animation instance with maya.maintained_selection(): cmds.select([output, controls] + roots, noExpand=True) api.create(name=namespace, asset=asset, family="animation", options={"useSelection": True}, data={"dependencies": dependency})
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya import pymel.core as pm with maya.maintained_selection(): groupName = "{}:{}".format(namespace, name) path = self.fname proxyPath = os.path.splitext(path)[0] + ".ma" nodes = cmds.file(proxyPath, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName=groupName) cmds.makeIdentity(groupName, apply=False, rotate=True, translate=True, scale=True) # Set attributes proxyShape = pm.ls(nodes, type="mesh")[0] proxyShape.aiTranslator.set('procedural') proxyShape.dso.set(path) proxyShape.aiOverrideShaders.set(0) self[:] = nodes return nodes
def process(self, instance): import os from maya import cmds from avalon import maya dirname = tempfile.mkdtemp() filename = "{name}.ma".format(**instance.data) path = os.path.join(dirname, filename) # Perform extraction self.log.info("Performing extraction..") with maya.maintained_selection(), maya.without_extension(): self.log.info("Extracting %s" % str(list(instance))) cmds.select(instance, noExpand=True) cmds.file(path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=False) # Store reference for integration if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(filename) instance.data["stagingDir"] = dirname self.log.info("Extracted {instance} to {path}".format(**locals()))
def process(self, instance): from maya import cmds from avalon import maya from reveries import utils staging_dir = utils.stage_dir() filename = "%s.ma" % instance.data["subset"] outpath = "%s/%s" % (staging_dir, filename) instance.data["repr.mayaAscii._stage"] = staging_dir instance.data["repr.mayaAscii._files"] = [filename] instance.data["repr.mayaAscii.entryFileName"] = filename # Perform extraction self.log.info("Performing extraction..") with maya.maintained_selection(): # Set flag `noExpand` to True for sharing containers, # which will be ignored if the selection expanded since # they are objectSets. cmds.select(instance, noExpand=True) cmds.file(outpath, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=True, channels=True, constraints=True, expressions=True, shader=True, constructionHistory=True)
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya try: family = context["representation"]["context"]["family"] except ValueError: family = "fbx" # Ensure FBX plug-in is loaded cmds.loadPlugin("fbxmaya", quiet=True) with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) groupName = "{}:{}".format(namespace, name) presets = config.get_presets(project=os.environ['AVALON_PROJECT']) colors = presets['plugins']['maya']['load']['colors'] c = colors.get(family) if c is not None: cmds.setAttr(groupName + ".useOutlinerColor", 1) cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2]) self[:] = nodes return nodes
def polyConstraint(components, *args, **kwargs): """Return the list of *components* with the constraints applied. A wrapper around Maya's `polySelectConstraint` to retrieve its results as a list without altering selections. For a list of possible constraints see `maya.cmds.polySelectConstraint` documentation. Arguments: components (list): List of components of polygon meshes Returns: list: The list of components filtered by the given constraints. """ kwargs.pop('mode', None) with no_undo(flush=False): with maya.maintained_selection(): # Apply constraint using mode=2 (current and next) so # it applies to the selection made before it; because just # a `maya.cmds.select()` call will not trigger the constraint. with reset_polySelectConstraint(): cmds.select(components, r=1, noExpand=True) cmds.polySelectConstraint(*args, mode=2, **kwargs) result = cmds.ls(selection=True) cmds.select(clear=True) return result
def _post_process_rig(self, name, namespace, context, options): output = next((node for node in self if node.endswith("out_SET")), None) controls = next( (node for node in self if node.endswith("controls_SET")), None) assert output, "No out_SET in rig, this is a bug." assert controls, "No controls_SET in rig, this is a bug." # Find the roots amongst the loaded nodes roots = cmds.ls(self[:], assemblies=True, long=True) assert roots, "No root nodes in rig, this is a bug." asset = api.Session["AVALON_ASSET"] dependency = str(context["representation"]["_id"]) self.log.info("Creating subset: {}".format(namespace)) # Create the animation instance creator_plugin = get_creator_by_name(self.animation_creator_name) with maya.maintained_selection(): cmds.select([output, controls] + roots, noExpand=True) api.create(creator_plugin, name=namespace, asset=asset, options={"useSelection": True}, data={"dependencies": dependency})
def extract_mayaAscii(self, packager): # Define extract output file path entry_file = packager.file_name("ma") package_path = packager.create_package() entry_path = os.path.join(package_path, entry_file) # Perform extraction self.log.info("Performing extraction..") with maya.maintained_selection(): # Set flag `noExpand` to True for sharing containers, # which will be ignored if the selection expanded since # they are objectSets. cmds.select(self.member, noExpand=True) cmds.file(entry_path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=True, channels=True, constraints=True, expressions=True, shader=True, constructionHistory=True) packager.add_data({ "entryFileName": entry_file, }) self.log.info("Extracted {name} to {path}".format( name=self.data["subset"], path=entry_path) )
def load(self, context, name=None, namespace=None, data=None): import maya.cmds as cmds from avalon import maya from avalon.maya import lib from avalon.maya.pipeline import containerise asset = context['asset'] namespace = namespace or lib.unique_namespace( asset["name"] + "_", prefix="_" if asset["name"][0].isdigit() else "", suffix="_", ) with maya.maintained_selection(): nodes = cmds.file(self.fname, i=True, namespace=namespace, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) # Only containerize if any nodes were loaded by the Loader if not nodes: return self[:] = nodes return containerise(name=name, namespace=namespace, nodes=nodes, context=context, loader=self.__class__.__name__)
def assign_look_by_version(nodes, version_id): """Assign nodes a specific published look version by id. This assumes the nodes correspond with the asset. Args: nodes(list): nodes to assign look to version_id (bson.ObjectId): database id of the version Returns: None """ # Get representations of shader file and relationships look_representation = io.find_one({ "type": "representation", "parent": version_id, "name": "ma" }) json_representation = io.find_one({ "type": "representation", "parent": version_id, "name": "json" }) # See if representation is already loaded, if so reuse it. host = api.registered_host() representation_id = str(look_representation['_id']) for container in host.ls(): if (container['loader'] == "LookLoader" and container['representation'] == representation_id): log.info("Reusing loaded look ..") container_node = container['objectName'] break else: log.info("Using look for the first time ..") # Load file loaders = api.loaders_from_representation(api.discover(api.Loader), representation_id) Loader = next((i for i in loaders if i.__name__ == "LookLoader"), None) if Loader is None: raise RuntimeError("Could not find LookLoader, this is a bug") # Reference the look file with maya.maintained_selection(): container_node = pipeline.load(Loader, look_representation) # Get container members shader_nodes = cmds.sets(container_node, query=True) # Load relationships shader_relation = api.get_representation_path(json_representation) with open(shader_relation, "r") as f: relationships = json.load(f) # Assign relationships apply_shaders(relationships, shader_nodes, nodes)
def process(self, instance): import os import ava from maya import cmds from avalon import maya self.log.debug("Loading plug-in..") cmds.loadPlugin("atomImportExport.mll", quiet=True) self.log.info("Extracting curves..") dirname = ava.format_staging_dir( root=instance.context.data["workspaceDir"], time=instance.context.data["time"], name=instance.data["name"]) try: os.makedirs(dirname) except OSError: pass filename = "{name}.curves".format(**instance.data) options = ";".join([ "precision=8", "statics=1", "baked=1", "sdk=0", "constraint=0", "animLayers=0", "selected=selectedOnly", "whichRange=1", "range=1:10", "hierarchy=none", "controlPoints=0", "useChannelBox=1", "options=keys", ("copyKeyCmd=" "-animation objects " "-option keys " "-hierarchy none " "-controlPoints 0 ") ]) controls = next( (node for node in instance if node.endswith("controls_SET")), None) if controls is None: # Backwards compatibility self.log.warning("%s is missing a controls_SET" % instance.name) return with maya.maintained_selection(), maya.without_extension(): cmds.select(controls, noExpand=False) cmds.file(os.path.join(dirname, filename).replace("\\", "/"), force=True, options=options, typ="atomExport", exportSelected=True) # Store reference for integration if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(filename) instance.data["stagingDir"] = dirname self.log.info("Extracted {instance} to {dirname}".format(**locals()))
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True) self[:] = nodes
def process(self, instance): import os import ava from maya import cmds from avalon import maya self.log.info("Extracting history..") dirname = ava.format_staging_dir( root=instance.context.data["workspaceDir"], time=instance.context.data["time"], name=instance.data["name"]) try: os.makedirs(dirname) except OSError: pass filename = "{name}.history".format(**instance.data) options = ";".join([ "precision=8", "statics=1", "baked=1", "sdk=0", "constraint=0", "animLayers=0", "selected=selectedOnly", "whichRange=1", "range=1:10", "hierarchy=none", "controlPoints=0", "useChannelBox=1", "options=keys", ("copyKeyCmd=" "-animation objects " "-option keys " "-hierarchy none " "-controlPoints 0 ") ]) with maya.maintained_selection(), maya.without_extension(): cmds.select(instance, noExpand=True) cmds.exportEdits( os.path.join(dirname, filename).replace("\\", "/"), force=True, type="editMA", selected=True, includeNetwork=True, includeAnimation=True, includeSetAttrs=True, ) # Store reference for integration if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(filename) instance.data["stagingDir"] = dirname self.log.info("Extracted {instance} to {dirname}".format(**locals()))
def repair(cls, instance): with maya.maintained_selection(): with pc.UndoChunk(): temp_transform = pc.polyCube()[0] attributes = cls.get_invalid_attributes(instance, compute=False) for attr in attributes: source = pc.PyNode("{}.{}".format( temp_transform.getShape(), attr.attrName())) attr.set(source.get()) pc.delete(temp_transform)
def process(self, instance): import os import polly from maya import cmds from avalon import maya dirname = polly.format_staging_dir( root=instance.context.data["workspaceDir"], time=instance.context.data["time"], name=instance.data["name"]) try: os.makedirs(dirname) except OSError: pass filename = "{name}.ma".format(**instance.data) path = os.path.join(dirname, filename) # Perform extraction self.log.info("Performing extraction..") with maya.maintained_selection(), maya.without_extension(): self.log.info("Extracting %s" % str(list(instance))) cmds.select(instance, noExpand=True) cmds.file( path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=False, # Shader assignment is the responsibility of # riggers, for animators, and lookdev, for rendering. shader=False, # Construction history inherited from collection # This enables a selective export of nodes relevant # to this particular plug-in. constructionHistory=False) # Store reference for integration if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(filename) instance.data["stagingDir"] = dirname self.log.info("Extracted {instance} to {path}".format(**locals()))
def extract_LightSet(self, packager): from maya import cmds from avalon import maya from reveries.maya import capsule entry_file = packager.file_name("ma") package_path = packager.create_package() # Extract lights # entry_path = os.path.join(package_path, entry_file) self.log.info("Extracting lights..") # From texture extractor try: texture = next(chd for chd in self.data.get("childInstances", []) if chd.data["family"] == "reveries.texture") except StopIteration: file_node_attrs = dict() else: file_node_attrs = texture.data.get("fileNodeAttrs", dict()) with contextlib.nested( maya.maintained_selection(), capsule.attribute_values(file_node_attrs), capsule.no_refresh(), ): cmds.select(self.member, replace=True, noExpand=True) cmds.file(entry_path, options="v=0;", type="mayaAscii", force=True, exportSelected=True, preserveReferences=False, constructionHistory=False, channels=True, # allow animation constraints=False, shader=False, expressions=True) packager.add_data({ "entryFileName": entry_file, })
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya import pymel.core as pm try: family = context["representation"]["context"]["family"] except ValueError: family = "ass" with maya.maintained_selection(): groupName = "{}:{}".format(namespace, name) path = self.fname proxyPath = os.path.splitext(path)[0] + ".ma" nodes = cmds.file(proxyPath, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName=groupName) cmds.makeIdentity(groupName, apply=False, rotate=True, translate=True, scale=True) # Set attributes proxyShape = pm.ls(nodes, type="mesh")[0] proxyShape.aiTranslator.set('procedural') proxyShape.dso.set(path) proxyShape.aiOverrideShaders.set(0) presets = config.get_presets(project=os.environ['AVALON_PROJECT']) colors = presets['plugins']['maya']['load']['colors'] c = colors.get(family) if c is not None: cmds.setAttr(groupName + ".useOutlinerColor", 1) cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2]) self[:] = nodes return nodes
def process(self, instance): from maya import cmds from avalon import maya from reveries import utils from reveries.maya import capsule staging_dir = utils.stage_dir() filename = "%s.ma" % instance.data["subset"] outpath = "%s/%s" % (staging_dir, filename) instance.data["repr.LightSet._stage"] = staging_dir instance.data["repr.LightSet._files"] = [filename] instance.data["repr.LightSet.entryFileName"] = filename # Extract lights # self.log.info("Extracting lights..") # From texture extractor child_instances = instance.data.get("childInstances", []) try: texture = next(chd for chd in child_instances if chd.data["family"] == "reveries.texture") except StopIteration: file_node_attrs = dict() else: file_node_attrs = texture.data.get("fileNodeAttrs", dict()) with contextlib.nested( maya.maintained_selection(), capsule.attribute_values(file_node_attrs), capsule.no_refresh(), ): cmds.select(instance, replace=True, noExpand=True) cmds.file( outpath, options="v=0;", type="mayaAscii", force=True, exportSelected=True, preserveReferences=False, constructionHistory=False, channels=True, # allow animation constraints=False, shader=False, expressions=True)
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya try: family = context["representation"]["context"]["family"] except ValueError: family = "model" with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) self[:] = nodes groupName = "{}:{}".format(namespace, name) presets = config.get_presets(project=os.environ['AVALON_PROJECT']) colors = presets['plugins']['maya']['load']['colors'] c = colors.get(family) if c is not None: cmds.setAttr(groupName + ".useOutlinerColor", 1) cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2]) cmds.setAttr(groupName + ".displayHandle", 1) # get bounding box bbox = cmds.exactWorldBoundingBox(groupName) # get pivot position on world space pivot = cmds.xform(groupName, q=True, sp=True, ws=True) # center of bounding box cx = (bbox[0] + bbox[3]) / 2 cy = (bbox[1] + bbox[4]) / 2 cz = (bbox[2] + bbox[5]) / 2 # add pivot position to calculate offset cx = cx + pivot[0] cy = cy + pivot[1] cz = cz + pivot[2] # set selection handle offset to center of bounding box cmds.setAttr(groupName + ".selectHandleX", cx) cmds.setAttr(groupName + ".selectHandleY", cy) cmds.setAttr(groupName + ".selectHandleZ", cz) return nodes
def process_reference(self, context, name, namespace, group, options): import maya.cmds as cmds from avalon import maya representation = context["representation"] entry_path = self.file_path(representation) with maya.maintained_selection(): nodes = cmds.file(entry_path, namespace=namespace, ignoreVersion=True, reference=True, returnNewNodes=True, groupReference=True, groupName=group) self[:] = nodes
def process_reference(self, context, name=None, namespace=None, data=None): import maya.cmds as cmds from avalon import maya with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) self[:] = nodes self.log.info("Yeti Rig Connection Manager will be available soon") return nodes
def process_reference(self, context, name, namespace, data): import maya.cmds as cmds from avalon import maya # Ensure FBX plug-in is loaded cmds.loadPlugin("fbxmaya", quiet=True) with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) self[:] = nodes return nodes
def _post_process(self, name, namespace, context, data): import os from maya import cmds from avalon import maya, io # Task-dependent post-process if os.getenv("AVALON_TASK") != "animate": return self.log.info( "No animation instance created due to task != animate") # Find associated rig to these curves try: dependency = context["representation"]["dependencies"][0] except (KeyError, IndexError): return self.log.warning("No dependencies found for %s" % name) dependency = io.find_one({"_id": io.ObjectId(dependency)}) _, _, dependency, _ = io.parenthood(dependency) # TODO(marcus): We are hardcoding the name "out_SET" here. # Better register this keyword, so that it can be used # elsewhere, such as in the Integrator plug-in, # without duplication. output = next((node for node in self if node.endswith("out_SET")), None) controls = next( (node for node in self if node.endswith("controls_SET")), None) assert output, "No out_SET in rig, this is a bug." assert controls, "No controls_SET in rig, this is a bug." with maya.maintained_selection(): cmds.select([output, controls], noExpand=True) dependencies = [context["representation"]["_id"]] name = "anim" + dependency["name"].title() + "_" # TODO(marcus): Hardcoding the family here, better separate this. maya.create( name=maya.unique_name(name, suffix="_SET"), family="ava.animation", options={"useSelection": True}, data={"dependencies": " ".join(str(d) for d in dependencies)})
def process(self, instance): from maya import cmds from avalon import maya with maya.maintained_selection(): cmds.select(instance, replace=True) nodes = cmds.file( constructionHistory=True, exportSelected=True, preview=True, force=True, ) self.assemblies[:] = cmds.ls(nodes, assemblies=True) if not self.assemblies: raise Exception("No assembly found.") if len(self.assemblies) != 1: self.assemblies = '"%s"' % '", "'.join(self.assemblies) raise Exception("Multiple assemblies found: %s" % self.assemblies)
def process(self, instance): import os import polly from maya import cmds from avalon import maya dirname = polly.format_staging_dir( root=instance.context.data["workspaceDir"], time=instance.context.data["time"], name=instance.data["name"]) try: os.makedirs(dirname) except OSError: pass filename = "{name}.ma".format(**instance.data) path = os.path.join(dirname, filename) # Perform extraction self.log.info("Performing extraction..") with maya.maintained_selection(), maya.without_extension(): cmds.select(instance, noExpand=True) cmds.file(path, force=True, typ="mayaAscii", exportSelected=True, preserveReferences=False, constructionHistory=True) # Store reference for integration if "files" not in instance.data: instance.data["files"] = list() instance.data["files"].append(filename) instance.data["stagingDir"] = dirname self.log.info("Extracted {instance} to {path}".format(**locals()))
def process_reference(self, context, name, namespace, options): """ Load and try to assign Lookdev to nodes based on relationship data. Args: name: namespace: context: options: Returns: """ import maya.cmds as cmds from avalon import maya with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True) self[:] = nodes
def extract_mayaBinary(self, packager): # Define extract output file path entry_file = packager.file_name("mb") package_path = packager.create_package() entry_path = os.path.join(package_path, entry_file) # Perform extraction self.log.info("Performing extraction..") with contextlib.nested( capsule.no_undo(), capsule.no_display_layers(self.member), maya.maintained_selection(), ): with capsule.undo_chunk_when_no_undo(): """(DEPRECATED, keeping namespaces) # - Remove referenced subset's namespace before exporting # (Not keeping model namespace) referenced_namespace = self.context.data["referencedNamespace"] for namespace in reversed(sorted(list(referenced_namespace))): if not cmds.namespace(exists=namespace): continue try: cmds.namespace(removeNamespace=namespace, mergeNamespaceWithRoot=True) except Exception: # Reload reference and try again. # The namespace of the reference will be able to # removed after reload. # (TODO) This publish workflow might not be a good # approach... ref_node = lib.reference_node_by_namespace(namespace) # There must be a reference node, since that's the # main reason why namespace can not be removed. cmds.file(loadReference=ref_node) cmds.namespace(removeNamespace=namespace, mergeNamespaceWithRoot=True) """ # - Remove loaded container member # If the mesh of the loaded model has been copied and edited # (mesh face detach and separation), the model container # might end up with a lots of facet member, which means there # are dag connections that would make the model container be # exported as well, and we don't want that happens. # So we just remove them all for good. for container in self.context.data["RootContainers"]: cmds.delete(container) mesh_nodes = cmds.ls(self.member, type="mesh", noIntermediate=True, long=True) geo_id_and_hash = self.hash(set(mesh_nodes)) packager.add_data({"modelProfile": geo_id_and_hash}) cmds.select(cmds.ls(self.member), noExpand=True) cmds.file(entry_path, force=True, typ="mayaBinary", exportSelected=True, preserveReferences=False, channels=True, constraints=True, expressions=True, constructionHistory=True, shader=True) packager.add_data({ "entryFileName": entry_file, }) self.log.info("Extracted {name} to {path}".format( name=self.data["subset"], path=entry_path))
def process_reference(self, context, name, namespace, options): import maya.cmds as cmds from avalon import maya import pymel.core as pm try: family = context["representation"]["context"]["family"] except ValueError: family = "model" with maya.maintained_selection(): groupName = "{}:{}".format(namespace, name) cmds.loadPlugin("AbcImport.mll", quiet=True) nodes = cmds.file(self.fname, namespace=namespace, sharedReferenceFile=False, groupReference=True, groupName="{}:{}".format(namespace, name), reference=True, returnNewNodes=True) # namespace = cmds.referenceQuery(nodes[0], namespace=True) shapes = cmds.ls(nodes, shapes=True, long=True) newNodes = (list(set(nodes) - set(shapes))) current_namespace = pm.namespaceInfo(currentNamespace=True) if current_namespace != ":": groupName = current_namespace + ":" + groupName groupNode = pm.PyNode(groupName) roots = set() for node in newNodes: try: roots.add(pm.PyNode(node).getAllParents()[-2]) except: # noqa: E722 pass if family not in ["layout", "setdress", "mayaAscii"]: for root in roots: root.setParent(world=True) groupNode.zeroTransformPivots() for root in roots: root.setParent(groupNode) cmds.setAttr(groupName + ".displayHandle", 1) settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get(family) if c is not None: groupNode.useOutlinerColor.set(1) groupNode.outlinerColor.set(c[0], c[1], c[2]) self[:] = newNodes cmds.setAttr(groupName + ".displayHandle", 1) # get bounding box bbox = cmds.exactWorldBoundingBox(groupName) # get pivot position on world space pivot = cmds.xform(groupName, q=True, sp=True, ws=True) # center of bounding box cx = (bbox[0] + bbox[3]) / 2 cy = (bbox[1] + bbox[4]) / 2 cz = (bbox[2] + bbox[5]) / 2 # add pivot position to calculate offset cx = cx + pivot[0] cy = cy + pivot[1] cz = cz + pivot[2] # set selection handle offset to center of bounding box cmds.setAttr(groupName + ".selectHandleX", cx) cmds.setAttr(groupName + ".selectHandleY", cy) cmds.setAttr(groupName + ".selectHandleZ", cz) if family == "rig": self._post_process_rig(name, namespace, context, options) else: if "translate" in options: cmds.setAttr(groupName + ".t", *options["translate"]) return newNodes
def process_reference(self, context, name=None, namespace=None, options=None): import maya.cmds as cmds from avalon import maya # get roots of selected hierarchies selected_roots = [] for sel in cmds.ls(sl=True, long=True): selected_roots.append(sel.split("|")[1]) # get all objects under those roots selected_hierarchy = [] for root in selected_roots: selected_hierarchy.append( cmds.listRelatives(root, allDescendents=True) or []) # flatten the list and filter only shapes shapes_flat = [] for root in selected_hierarchy: shapes = cmds.ls(root, long=True, type="mesh") or [] for shape in shapes: shapes_flat.append(shape) # create dictionary of cbId and shape nodes scene_lookup = defaultdict(list) for node in shapes_flat: cb_id = lib.get_id(node) scene_lookup[cb_id] = node # load rig with maya.maintained_selection(): nodes = cmds.file(self.fname, namespace=namespace, reference=True, returnNewNodes=True, groupReference=True, groupName="{}:{}".format(namespace, name)) # for every shape node we've just loaded find matching shape by its # cbId in selection. If found outMesh of scene shape will connect to # inMesh of loaded shape. for destination_node in nodes: source_node = scene_lookup[lib.get_id(destination_node)] if source_node: self.log.info("found: {}".format(source_node)) self.log.info( "creating connection to {}".format(destination_node)) cmds.connectAttr("{}.outMesh".format(source_node), "{}.inMesh".format(destination_node), force=True) groupName = "{}:{}".format(namespace, name) settings = get_project_settings(os.environ['AVALON_PROJECT']) colors = settings['maya']['load']['colors'] c = colors.get('yetiRig') if c is not None: cmds.setAttr(groupName + ".useOutlinerColor", 1) cmds.setAttr(groupName + ".outlinerColor", c[0], c[1], c[2]) self[:] = nodes return nodes