def contain(type): selection = pymel.ls(selection=True) if type == 'dag': type = 'dagContainer' positions = {} for each in selection: positions[each] = pymel.hyperGraph(HYPER_GRAPH, query=True, getNodePosition=selection[0]) container = pymel.container(type=type, includeHierarchyBelow=True, ) pymel.container(addNode=selection, edit=True, includeHierarchyBelow=True, force=True) print container pymel.select( cl=True ) #pymel.evalDeferred('pymel.select("'+container+'", replace=True,)') #pymel.evalDeferred('pymel.hyperGraph("'+hyperGraph+'", edit=True, expandContainer=True)') def deferredCauseMayaIsStupid(): pymel.select(container, replace=True,) pymel.hyperGraph(HYPER_GRAPH, edit=True, expandContainer=True) for each in positions: pymel.hyperGraph(HYPER_GRAPH, edit=True, setNodePosition=[each, positions[each][0], positions[each][1]]) posX, posY = pymel.hyperGraph(HYPER_GRAPH, query=True, getNodePosition=container) pymel.hyperGraph(HYPER_GRAPH, edit=True, setNodePosition=[each, posX, posY+3]) pymel.evalDeferred( deferredCauseMayaIsStupid)
def addIntermediateNode(node, data): """The function to be passed into the callback.""" node = pmc.PyNode(node) if isinstance(node, pmc.nt.DagNode): # ignore DAG objects return pmc.container(container, e=True, addNode=node)
def createSkeletonGroup(self): self.rig_skeleton_group = pm.group(empty = True, name = "SKELETON") pm.container(self.rig_container, e = True, addNode = self.rig_skeleton_group, ihb = True) return self.rig_skeleton_group
def createRigGroup(self): self.rig_rig_group = pm.group(empty = True, name = "RIG") pm.container(self.rig_container, e = True, addNode = self.rig_skeleton_group, ihb = True) return self.rig_rig_group
def createMeshGroup(self): self.rig_mesh_group = pm.group(empty = True, name = "MESH") pm.container(self.rig_container, e = True, addNode = self.rig_mesh_group, ihb = True) return self.rig_mesh_group
def loadTranslationControl(root_joint, module_name, container, module_control_grp, control_type = "translation", color = [1, 0, 0]): """ loads translation control onto the root_joint """ path = os.path.join(environ.ControlObjectsPath, "translation_control.ma") pm.importFile(path, renameAll = True, loadReferenceDepth = "all", namespace =":") # renamePrefix == namespace # rename default module translation_control = pm.rename("translation_control", module_name + ":" + root_joint.stripNamespace() + "_translation_control", ignoreShape = False) translation_control_grp = pm.group(translation_control, name = module_name + ":" + root_joint.stripNamespace() + "_translation_controlGrp") # move control to root root_joint pm.delete(pm.pointConstraint(root_joint, translation_control_grp, maintainOffset=False)) translation_control_grp.setParent(module_control_grp) pm.addAttr(translation_control, longName="ControlType", dataType="string", keyable=False) pm.addAttr(translation_control, longName="ParentObject", at="message", multi = True) translation_control.ControlType.set(control_type, type = "string", lock = True) utils.addNodeToContainer(container, [translation_control, translation_control_grp], ihb = True, includeNetwork = True) pm.container(container, edit=True, publishAndBind=[translation_control + ".rotate", translation_control.stripNamespace() + "_rotate"]) pm.container(container, edit=True, publishAndBind=[translation_control + ".translate", translation_control.stripNamespace() + "_translate"]) return translation_control, translation_control_grp
def AddNodeToContainer(_containerName, _nodesIn, _includeHierarchyBelow = False, _includeShapes = False, _force = False): import types nodes = [] # create a new list of current list object if type(_nodesIn) is types.ListType: nodes = list(_nodesIn) # store current object as a list else: nodes = [_nodesIn] # Put maya unit conversion nodes in a list conversionNodes = [] for node in nodes: node_conversionNodes = pm.listConnections(node, source = True, destination = True) node_conversionNodes = pm.ls(node_conversionNodes, typ = 'unitConversion') conversionNodes.extend(node_conversionNodes) # Store everything in a single list nodes.extend(conversionNodes) pm.container(_containerName, edit = True, addNode = nodes, includeHierarchyBelow = _includeHierarchyBelow, includeShapes = _includeShapes, force = _force)
def checkLeveL(self,node): if not pm.objExists(node.name()):return False ar = pm.container(query=True, findContainer=node) if not ar: return False ar = pm.container(query=True, findContainer=ar) if not ar: return False return True
def __init__(self): selectedObjects = pm.ls(selection = True, transforms = True) filteredGroups = [] for obj in selectedObjects: if obj.find("Group__") == 0: filteredGroups.append(obj) if len(filteredGroups) == 0: return # Recursively find and store grouped module namespaces in a list groupContainer = "Group_container" modules = [] for group in filteredGroups: modules.extend(self.FindChildModules(group)) # Store all the grouped container nodes in a list moduleContainers = [groupContainer] for module in modules: moduleContainer = "%s:module_container" %module moduleContainers.append(moduleContainer) # Unlock containers for container in moduleContainers: pm.lockNode(container, lock = False, lockUnpublished = False) # Ungroup for group in filteredGroups: childCount = len(pm.listRelatives(group, children = True)) if childCount > 1: pm.ungroup(group, absolute = True) for attr in ["t", "r", "globalScale"]: pm.container(groupContainer, edit = True, unbindAndUnpublish = "%s.%s" %(group, attr)) parentGroup = pm.listRelatives(group, parent = True) pm.delete(group) # Recursively delete empty parent groups if len(parentGroup) != 0: parentGroup = parentGroup[0] children = pm.listRelatives(parentGroup, children = True) children = pm.ls(children, transforms = True) if len(children) == 0: pm.select(parentGroup, replace = True) UngroupSelected() # Lock module containers after ungrouping is finished for container in moduleContainers: if pm.objExists(container): pm.lockNode(container, lock = True, lockUnpublished = True)
def publish_joints(asset=None): """From the given container, publish the xform attributes for all joints.""" if not asset or not isinstance(asset, pmc.nt.Container): asset = pmc.selected(type="container")[0] all_nodes = pmc.container(asset, q=True, nodeList=True) for j in (o for o in all_nodes if isinstance(o, pmc.nt.Joint)): for attr in (j.translate, j.rotate, j.scale): pubName = "_".join(("inputs", j.nodeName(), attr.longName())) pmc.container(asset, e=True, publishAndBind=(attr, pubName))
def setModuleMetaInfo(node, attribute, attrInfo): """ Sets the attribute of the modules meta node. If attribute type is message, attribute has to be the same for both meta and node. """ node = pm.PyNode(node) # what if node is meta meta_node = None # find meta node if node.hasAttr("MetaNode"): meta_node = pm.PyNode(node.MetaNode.get()) elif node.hasAttr("ModuleNodes"): meta_node = pm.PyNode(node) if meta_node != None: if pm.objectType(node) == "container": module_container = node else: module_container = pm.container(q = True, findContainer = node) lock_state = pm.lockNode(module_container, q = True, lock = True)[0] pm.lockNode(module_container, lock = False, lockUnpublished = False) # --------------------------------------------------------------- # if attribute is a string if meta_node.attr(attribute).type() == "string": meta_node.attr(attribute).set(lock = False) meta_node.attr(attribute).set(attrInfo, lock = True) # if attribute is a message if meta_node.attr(attribute).type() == "message": # meta node and node need to have same attribute connected_node = pm.PyNode(attrInfo) # find the nodes container connectedNode_container = pm.container(q = True, findContainer = connected_node) if connectedNode_container != getModuleMetaInfo(node, "ModuleContainer"): # need to make sure the input node's container is unlocked connectedNode_lockState = pm.lockNode(connectedNode_container, q = True, lock = True)[0] pm.lockNode(connectedNode_container, lock = False, lockUnpublished = False) # if the input node does not have the same attribute if not connected_node.hasAttr(attribute): _logger.warning("{} does not have attribute: {}".format(connected_node, attribute)) pm.addAttr(connected_node, longName = attribute, at="message", multi = True) try: meta_node.attr(attribute).connect(connected_node.attr(attribute)) except: _logger.warning("CANNOT CONNECT {} TO {}".format(meta_node.attr(attribute), connected_node.attr(attribute))) pm.lockNode(connectedNode_container, lock = connectedNode_lockState, lockUnpublished = lock_state) pm.lockNode(module_container, lock = lock_state, lockUnpublished = lock_state)
def Install_custom(self, _joints): self.SetupInterpolation() moduleGrp = "%s:module_grp" %self.moduleNamespace pm.select(moduleGrp, replace = True) pm.addAttr(attributeType = "enum", enumName = "y:z", longName = "sao_local") pm.addAttr(attributeType = "enum", enumName = "+x:-x:+y:-y:+z:-z", longName = "sao_world") for attr in ["sao_local", "sao_world"]: pm.container(self.containerName, edit = True, publishAndBind = ["%s.%s" %(moduleGrp, attr), attr] )
def organizeNodes(): """Make containers for each surface in the scene and add all DG (NOT DAG) nodes to it for scene organization""" surfs = [s for s in pmc.ls(type="transform") if hasattr(s, "layeredTexture")] for s in surfs: nodes = set(s.future(allFuture=True)) # also need some nodes connected to ctrls and joints ctrls = s.controls.get() for c in ctrls: j = c.rangeU.outputs()[0] nodes.update(c.history(), j.future(), j.history()) nodes = [n for n in nodes if not isinstance(n, pmc.nt.DagNode)] pmc.container(name=s.name()+"_assets", addNode=nodes)
def assetize(self, publishCtrls=1): ''' Adds all nodes associated with the component to a Maya asset container. :param: publishCtrls. If true. publishes the components controls so they are visible when asset is blackboxed :return: The newly created asset node ''' nodes = pmc.ls('%s*' % self.name) self.asset = pmc.container(name='%s_asset' % self.name, addNode=nodes) pmc.container(self.asset, e=1, publishName='%s_%s' % (self.name, self.side)) if publishCtrls: for ctrl in self.ctrls: pmc.containerPublish(self.asset, publishNode=[ctrl.name(), 'transform'], bindNode=[ctrl.name(), ctrl.name()])
def assetize_cmpnt(cmpnt=None, autoPublish=True): """Reads all DG nodes involved in the component given by either argument or only selected DAG object.""" if not cmpnt: cmpnt = pmc.selected()[0] cmpNodes = {cmpnt} # prune set is objects which will later be removed from the component set prune = set() allDag = cmpnt.getChildren(allDescendents=True) for dag in allDag: cmpNodes.update(dag.history()) cmpNodes.update(dag.future(af=True)) # now prune input's history and output's future # perhaps not the most efficient but it's reliable # in an uncertain situation name = dag.longName() if "input" in name: prune.update(dag.history()) elif "output" in name: prune.update(dag.future(af=True)) cmpNodes -= prune contName = cmpnt.split("_") contName[-1] = "asset" contName = "_".join(contName) # ugly, but Maya seems to have no special way of considering layer nodes. cmpNodes = [n for n in cmpNodes if "layer" not in n.type().lower()] asset = pmc.container(addNode=cmpNodes, includeHierarchyBelow=True, name=contName) if autoPublish: publish_controls(asset) publish_inputs_outputs(asset)
def getPoyCountGroupByContainerUsingPymel2(*args, **kwargs): scenePolyCount = {'Verts':0, 'Edges':0, 'Faces':0, 'UVs':0, 'Tris':0, 'surface area':0, 'hierarchy':{}} Verts = Edges = Faces = UVs = Tris = 0 if pm.system.sceneName(): for shape in pm.ls(type='mesh', noIntermediate=True): instanceCount = len(shape.getAllPaths()) Verts = shape.numVertices() * instanceCount Edges = shape.numEdges() * instanceCount Faces = shape.numFaces() * instanceCount UVs = shape.numUVs() * instanceCount Tris = int(pm.mel.eval('polyEvaluate -triangle {0}'.format(shape.name()))[0]) * instanceCount surfaceArea = pm.polyEvaluate(shape, wa=True) scenePolyCount['Verts'] += Verts scenePolyCount['Edges'] += Edges scenePolyCount['Faces'] += Faces scenePolyCount['UVs'] += UVs scenePolyCount['Tris'] += Tris scenePolyCount['surface area'] += int(surfaceArea) container = pm.container(shape, query=True, findContainer=shape.name()) if container is not None: containerStack = getContainerStackUsingPymel(container) _buildHierarchy(scenePolyCount, containerStack, **{'container':container.name(), 'Verts':Verts, 'Edges':Edges, 'Faces':Faces, 'UVs':UVs, 'Tris':Tris, 'surface area': int(surfaceArea)}) return scenePolyCount
def publish_controls(asset=None): """From a given asset, publish the control objects. Assumes any transform with a nurbsCurve shape is a control.""" if not asset or not isinstance(asset, pmc.nt.Container): asset = pmc.selected(type="container")[0] all_nodes = pmc.container(asset, q=True, nodeList=True) is_ctrl = lambda obj: hasattr(obj, "getShape") and isinstance( obj.getShape(), pmc.nt.NurbsCurve) controls = [n for n in all_nodes if is_ctrl(n)] # need to find the names of the controls and cross-check them with each other for c in controls: name = c.shortName() if "|" in name: # "|" means shortName returned longName. # it happens, and it's just nice when it's caught and notifies pmc.warning( "{0} is not uniquely named! This could be bad!".format(name)) try: name = name.split("_")[2] except IndexError: # if it's gonna throw a fit then just use the whole name pass if hasattr(asset, name): print("Re-naming {0}.{1}".format(asset, name)) # this tests for duplicate name and re-aliases if necessary attr = getattr(asset, name) existing = attr.publishedNode.get() # try all tokens except first and last (assert: side + identifier) existing_new_name = "_".join(existing.shortName().split("_")[1:-1]) attr.setAlias(existing_new_name) name = "_".join(c.shortName().split("_")[1:-1]) pmc.containerPublish(asset, publishNode=(name, "")) pmc.containerPublish(asset, bindNode=(name, c))
def get_published_attrs(c): """Return attributes published to arg asset in {name: pymel attr} form.""" try: return dict( ((n, a) for a, n in pmc.container(c, q=True, bindAttr=True))) except TypeError: return {}
def findAllAssets(self, top='|assets', ns_level='*:master'): masters = [] if not pm.objExists(top): return masters masters_raw = [ m for m in pm.ls(ns_level, rn=True) if m.isReferenced() and m.isChildOf(top) ] if masters_raw: masters = [ m for m in masters_raw if pm.objExists(m.name().replace(':master', ':poly')) ] masters.extend(self.findAllAssets(top, '*:' + ns_level)) # find assembly reference nodes l_ar = pm.listRelatives(top, ad=True, type='assemblyReference') l_asset_ar = [] l_asb_ar = [] for ar in l_ar: asset_ar = True l_nodes = pm.container(ar, q=True, nodeList=True) for n in l_nodes: if n.nodeType() == 'assemblyReference': asset_ar = False if asset_ar: masters.append(ar) return masters
def selectInputOutput(mode='all', depthLimit=4): selection = pymel.ls(selection=True) hyperGraph = 'graph1HyperShadeEd' addList = [] addList.extend(selection) if mode == 'inputs' or mode == 'all': inputDepth = [] inputDepth.append(selection) while len(inputDepth) < depthLimit: newDepth = [] for each in inputDepth[-1]: inputs = pymel.listConnections( each, destination=False, source=True, skipConversionNodes=False) if inputs: newDepth.extend(inputs) inputDepth.append(newDepth) for listVar in inputDepth: for each in listVar: if not each in addList and pymel.nodeType(each) != 'hyperLayout': addList.append(each) if mode == 'outputs' or mode == 'all': outputDepth = [] outputDepth.append(selection) while len(outputDepth) < depthLimit: newDepth = [] for each in outputDepth[-1]: outputs = pymel.listConnections( each, destination=True, source=False, skipConversionNodes=False) if outputs: newDepth.extend(outputs) outputDepth.append(newDepth) for listVar in outputDepth: for each in listVar: if not each in addList and pymel.nodeType(each) != 'hyperLayout': addList.append(each) unblackBoxList = [] for each in addList: container = pymel.container(query=True, findContainer=each) if container: if not container in unblackBoxList: if pymel.getAttr(container+'.blackBox'): unblackBoxList.append(container) pymel.select(addList, replace=True)
def initializeParentModuleSetup(self, rootTranslationControl): """ Every module's root translation control will have a set of two joints. The parent object will equal to the unhookTarget_locator if it is not parented to another module. If it is parented to another module, the parent_object will be that modules translation control """ # setup root locator at rootTranslationControl as unHookTarget unhookTarget_locator = pm.spaceLocator(name = self.userSpecifiedName + ":unhookTarget_loc") pm.addAttr(unhookTarget_locator, longName="ParentObject", at="message") unhookTarget_locator.visibility.set(0) # set offset slightly off so we don't divide by a zero pm.pointConstraint(rootTranslationControl, unhookTarget_locator, offset = [0.001, 0.01, 0.001], name = self.userSpecifiedName + ":unhookTarget_locator_pointConstraint") if self.parent_object == None: self.parent_object = unhookTarget_locator pm.select(cl = True) # get the position of base target and the parent target # setup setup root joint at rootTranslationControl # setup endJoint to be at the location of the new hook object target_joint_position = pm.xform(self.parent_object, q = True, ws = True, translation = True) root_joint = pm.joint(name = self.userSpecifiedName + ":targetParent_root_joint", position = rootTranslationControl.translate.get()) target_joint = pm.joint(name = self.userSpecifiedName + ":target_end_joint", position = target_joint_position ) pm.joint(root_joint, edit=True, orientJoint="xyz", sao="yup") ik_nodes = self.stretchy_ik(root_joint, target_joint, container = self.module_container) target_locator = ik_nodes["end_locator"] doNotTouch_grp =ik_nodes["doNotTouch_grp"] # constrain the end parentJoint to the parent module pm.pointConstraint(rootTranslationControl, target_locator, maintainOffset=False, name = self.userSpecifiedName + ":targetObject_pointConstraint") # constrain the root parentJoint to the child module pm.pointConstraint(self.parent_object, root_joint, maintainOffset=False, name = self.userSpecifiedName + ":targetParent_pointConstraint") parent_group = pm.group([root_joint, unhookTarget_locator, doNotTouch_grp], name = self.userSpecifiedName + ":parent_group") utils.addNodeToContainer(self.module_container, [parent_group], ihb = True) for joint in [root_joint, target_joint]: joint.template.set(1) pm.container(self.module_container, edit=True, publishAndBind=[joint + ".rotate", joint.stripNamespace() + "_r"]) if self.parent_object != unhookTarget_locator: utils.setModuleMetaInfo(self.module_container, "ParentObject", self.findParentModule())
def publish_inputs_outputs(asset=None): """From the given container, publish the DAG nodes under "input" and "output" transforms. Assumes this structure.""" if not asset or not isinstance(asset, pmc.nt.Container): asset = pmc.selected(type="container")[0] all_nodes = pmc.container(asset, q=True, nodeList=True) attrs_to_publish = [] is_edge = lambda obj, side: isinstance(obj, pmc.nt.DagNode ) and obj.nodeName() == side for edge in ("inputs", "outputs"): for par in (t for t in all_nodes if is_edge(t, edge)): for i in par.getChildren(): for attr in i.listAttr(k=True): pubName = "_".join((edge, i.nodeName(), attr.longName())) pmc.container(asset, e=True, publishAndBind=(attr, pubName))
def SetupIconScale(self, _animationModuleNamespace): clusterNodes = pm.cluster(self.controlObject, name = "%s_icon_scale_cluster" %self.controlObject, relative = True) pm.container("%s:module_container" %_animationModuleNamespace, edit = True, addNode = clusterNodes, includeHierarchyBelow = True, includeShapes = True) clusterHandle = clusterNodes[1] pm.setAttr("%s.scalePivotX" %clusterHandle, 0) pm.setAttr("%s.scalePivotY" %clusterHandle, 0) pm.setAttr("%s.scalePivotZ" %clusterHandle, 0) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleX" %clusterHandle) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleY" %clusterHandle) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleZ" %clusterHandle) pm.parent(clusterHandle, self.controlObject, absolute = True) pm.setAttr("%s.visibility" %clusterHandle, 0)
def rigCurveShapeControl( ctrl=None, attr=None, sampleParams=[0,1,2,3,4,5,6,7,8,9,10], container=False ): ''' 스쿼시 스트레치시 그래프 에디터 커브로 쉐입을 조정하려고 만들어짐. powAttr = rigCurveShapeControl( ctrl='spinCtrl', attr='sideAxisScaleShape', sampleParams=range( len(joints) ) ) @param ctrl: @param attr: @param sampleParams: @param container: @return: ctrl.results 어트리뷰트를 리턴함. @rtype: pm.Attribute ''' if not ctrl: sel = pm.selected() if sel: ctrl = sel[0] else: return if not attr: attr = 'curveCtrl' ctrl.addAttr( attr, keyable=True ) ctrl = pm.PyNode(ctrl) ctrlAttr = pm.Attribute( ctrl.attr(attr) ) # 애니메이션 커브 생성 pm.setKeyframe( ctrlAttr, t=sampleParams[ 0], v=0) pm.setKeyframe( ctrlAttr, t=sampleParams[-1], v=0) pm. keyTangent( ctrlAttr, weightedTangents=True ) pm. keyTangent( ctrlAttr, weightLock=False ) pm. keyTangent( ctrlAttr, e=True, absolute=True, time=[sampleParams[ 0]], outAngle=77, outWeight=1 ) pm. keyTangent( ctrlAttr, e=True, absolute=True, time=[sampleParams[-1]], inAngle=-77, inWeight=1 ) # frameCache노드로 애니메이션 커브의 각 포인트에서 값을 가져옴 ctrl.addAttr( 'samples', multi=True, readable=True, indexMatters=False ) ctrl.addAttr( 'results', multi=True, readable=True, indexMatters=False ) frameCaches = [] for i,param in enumerate(sampleParams): ctrl.samples[i].set( param ) frameCache = pm.createNode( 'frameCache' ) pm.connectAttr( ctrlAttr, frameCache.stream) pm.connectAttr( ctrl.samples[i], frameCache.varyTime ) pm.connectAttr( frameCache.varying, ctrl.results, na=True) frameCaches.append(frameCache) # container Setting : wip if container: cont = pm.container( type='dagContainer', addNode=frameCaches ) cont.blackBox.set(True) return ctrl.results
def findContainerNode(node = None): """ finds the container module for any selected node""" node = pm.ls(sl = True)[0] or node module_container = node if pm.objectType(node) != "container": module_container = pm.container(q = True, findContainer = node) return module_container
def find_cb_attrs(attr_names): attrs = [] obj = pmc.selected()[-1] # attr could be on selected node or could be published to its asset c = pmc.container(q=True, fc=obj) if c: # bindAttr returns in wrong order, just reverse before making into dict pub_attrs = dict( ((n, a) for a, n in pmc.container(c, q=True, bindAttr=True))) else: pub_attrs = {} for a in attr_names: try: attrs.append(obj.attr(a)) except: # see if it's in published attributes if a in pub_attrs: attrs.append(pub_attrs[a]) return attrs
def migrate_to_parent_asset(containers=None): """Move all nodes from selected containers into their parent container and re-publish to parent any nodes which were published before.""" if not containers: containers == pmc.selected(containers=True) for c in containers: all_nodes = pmc.container(c, q=True, nodeList=True) c_name = c.namespace().strip(":") pub_info = pmc.containerPublish(c, q=True, bindNode=True) par_c = pmc.container(c, q=True, parentContainer=True) if not par_c: pmc.warning("{} has no parent container! Skipped.".format(c)) continue pmc.container(c, e=True, removeContainer=True) pmc.container(par_c, e=True, addNode=all_nodes) # publish to new parent container pub_iter = iter(pub_info) for pub_name in pub_iter: pub_name = "{}_{}".format(c_name, pub_name) pub_ctrl = pub_iter.next() pmc.containerPublish(par_c, publishNode=(pub_name, "")) pmc.containerPublish(par_c, bindNode=(pub_name, pub_ctrl)) # fix node names, AFTER re-publishing for node in all_nodes: prefix, n = node.name().split(":") node.rename(prefix + n.title(), ignoreShape=True)
def makeAssets(): surfs = [s for s in pmc.ls(type="transform") if hasattr(s, "layeredTexture")] for s in surfs: nodes = set(s.future(allFuture=True) + s.future(leaf=False)) # also need some nodes connected to ctrls and joints ctrls = s.controls.get() for c in ctrls: j = c.rangeU.outputs()[0] nodes.update(c.history(), j.future(), j.history()) nodes = [n for n in nodes if not isinstance(n, pmc.nt.DagNode)] cont = pmc.container(name=s.name()+"_assets", addNode=nodes) s.addAttr("container", at="message") cont.addAttr("surface", at="message") s.container >> cont.surface
def AddGroupToContainer(self, _group): groupContainer = "Group_container" utils.AddNodeToContainer(groupContainer, _group, _includeShapes = True) groupName = _group.partition("Group__")[2] pm.container(groupContainer, edit = True, publishAndBind = ["%s.translate" %_group, "%s_t" %groupName]) pm.container(groupContainer, edit = True, publishAndBind = ["%s.rotate" %_group, "%s_r" %groupName]) pm.container(groupContainer, edit = True, publishAndBind = ["%s.globalScale" %_group, "%s_globalScale" %groupName])
def getTranslationControls(self, containerName): allTransControls = [] transControl = pm.container(containerName, query=True, nodeList=True, ish=False, isd=False, inc=True ) for control in transControl: suffix = "joint_translation_control_container" result = control.endswith(suffix) if result == True: control = control.replace("_container", "") allTransControls.append(control) return allTransControls
def addNodeToContainer(container, nodesIn, ihb = False, includeShapes = False, includeNetwork = False, force = True): import types nodes = [] ''' container = pm.PyNode(container) meta_node = None if container.hasAttr("MetaNode") == True: meta_node = getModuleMetaInfo(container, "ModuleNodes") ''' # if nodesIn is not a list, turns it into a list if type(nodesIn) is types.ListType: nodes = list(nodesIn) else: nodes = [nodesIn] # make sure to add all conversion nodes conversion_nodes = [] for node in nodes: node = pm.PyNode(node) node_conversionNodes = pm.listConnections(node, source = True, destination = True) node_conversionNodes = pm.ls(node_conversionNodes, type = 'unitConversion') conversion_nodes.extend(node_conversionNodes) ''' if container.hasAttr("MetaNode") == True: if node.hasAttr("MetaNode") == False: pm.addAttr(node, longName="MetaNode", at="message") if meta_node != None: meta_node.ModuleNodes.connect(node.MetaNode) ''' nodes.extend(conversion_nodes) pm.container(container, e = True, addNode = nodes, ihb = ihb, includeShapes = includeShapes, includeNetwork = includeNetwork, force = force)
def getContainerStackUsingPymel(container=None): ''' Container path ''' container_stack = deque() while isinstance(container, pm.nt.Container) \ or isinstance(container, pm.nt.DagContainer): container_stack.appendleft(container.name()) parent = pm.container(container, query=True, parentContainer=True) container = parent[0] if parent else None if container is not None: pm.mel.eval('select -r {0}'.format(container)) container = pm.ls(selection=True)[0] pm.select(cl=True) return container_stack
def SetupInterpolation(self, _unlockContainer = False, *args): previousSelection = pm.ls(selection = True) if _unlockContainer: pm.lockNode(self.containerName, lock = False, lockUnpublished = False) joints = self.GetJoints() numberOfJoints = len(joints) startControl = self.GetTranslationControl(joints[0]) endControl = self.GetTranslationControl(joints[numberOfJoints - 1]) pointConstraints = [] for i in range(1, numberOfJoints - 1): material = "%s_m_translation_control" %joints[i] pm.setAttr("%s.colorR" %material, 0.815) pm.setAttr("%s.colorG" %material, 0.629) pm.setAttr("%s.colorB" %material, 0.498) translationControl = self.GetTranslationControl(joints[i]) # Calculate constraint influence depending of distance from start/end endWeight = 0.0 + (float(i) / (numberOfJoints - 1)) startWeight = 1.0 - endWeight # point constraint between start/end pointConstraints.append(pm.pointConstraint(startControl, translationControl, maintainOffset = False, weight = startWeight)) pointConstraints.append(pm.pointConstraint(endControl, translationControl, maintainOffset = False, weight = endWeight)) # Lock translation attribute of control for attr in [".translateX", ".translateY", ".translateZ"]: pm.setAttr("%s%s" %(translationControl, attr), lock = True) interpolationContainer = pm.container(name = "%s:interpolation_container" %self.moduleNamespace) utils.AddNodeToContainer(interpolationContainer, pointConstraints) utils.AddNodeToContainer(self.containerName, interpolationContainer) if _unlockContainer: pm.lockNode(self.containerName, lock = True, lockUnpublished = True) # Reselect initial selection if len(previousSelection) > 0: pm.select(previousSelection, replace = True) else: pm.select(clear = True)
def publish_to_asset(nodes=None, name=None): """ Publish the given node to the given container. :param node: Node to publish :param asset: duh :param name: optional. if not given, just strip off ":" and "_ctrl" :return: None """ if not nodes: nodes = pmc.selected(transforms=True) asset = pmc.container(q=True, fc=nodes[0]) for node in nodes: name = node.replace(":", "").replace("_ctrl", "") if name == "global": name = "master" pmc.containerPublish(asset, publishNode=(name, "")) pmc.containerPublish(asset, bindNode=(name, node))
def distributeCrv( transformNodes, curve=None, uniform=True ): nodes = [pm.PyNode(node) for node in transformNodes] crv = pm.PyNode(curve) crvShape = crv.getShape() nodeNums = len(nodes) contMembers = [] if uniform: rebCrv, reb = pm.rebuildCurve( crvShape, ch=True, rpo=False, rt=4, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=3, tol=0.001 ) crvShape = rebCrv.getShapes( type='nurbsCurve' )[0] rebCrv.rename( crv+'_rebCrv' ) reb.rename( crv+'_rebuildCrv' ) contMembers.append( pm.parentConstraint( crv, rebCrv ) ) contMembers.append( pm.scaleConstraint( crv, rebCrv ) ) contMembers.append( rebCrv ) contMembers.append( reb ) unit = None if crv.form() == 'periodic': unit = (1.0/nodeNums) else: unit = (1.0/(nodeNums-1)) for i, node in enumerate( nodes ): pointOnCurve = pm.PyNode( pm.pointOnCurve( crvShape, ch=True ) ) pointOnCurve.rename( node+'_POC' ) pointOnCurve.turnOnPercentage.set(True) pointOnCurve.parameter.set( unit*i ) pointOnCurve.p >> node.t pointOnCurve.setAttr('parameter', keyable=True) contMembers.append( pointOnCurve ) cont = pm.container( type='dagContainer', addNode=contMembers, n=crv+'_distributeCrv#' ) cont.v.set(False) return cont
def getTranslationControls(self, containerName): allTransControls = [] transControl = pm.container(containerName, query=True, nodeList=True, ish=False, isd=False, inc=True) for control in transControl: suffix = "joint_translation_control_container" result = control.endswith(suffix) if result == True: control = control.replace("_container", "") allTransControls.append(control) return allTransControls
def alignNodes(alignment): selection = pymel.ls(selection=True) hyperGraph = 'graph1HyperShadeEd' if len(selection) >= 2: posX, posY = pymel.hyperGraph(HYPER_GRAPH, query=True, getNodePosition=selection[0]) for each in selection[1:]: container = pymel.container(query=True, findContainer=[each]) if container: pymel.setAttr(container+'.blackBox', 0) if alignment == 'horizontal': posX += 200 elif alignment == 'vertical': posY -= 200 else: print 'ERROR, no alignment set' pymel.hyperGraph(HYPER_GRAPH, edit=True, addDependNode=each) pymel.hyperGraph(HYPER_GRAPH, edit=True, setNodePosition=[each, posX, posY]) print pymel.hyperGraph(HYPER_GRAPH, query=True, look=True)
def install_joints(self): """ gathers information from the module and creates the joints """ # create list of joints joints = [] translation_controls = [] # clear selection pm.select(cl = True) # set current namespace to root. that way all namespaces will be child of the root only pm.namespace(setNamespace = ":") pm.namespace(add = self.userSpecifiedName) self.joints_grp = pm.group(empty = True, name = self.userSpecifiedName + ":joints_grp") self.misc_grp = pm.group(empty = True, name = self.userSpecifiedName + ":misc_grp") self.module_container = pm.container(name = self.userSpecifiedName + ":module_container" ) self.networkNode() # creating joints this way because when you select a joint and create a joint it will correct orientation index = 0 for joint in self.joint_info: joint_name = joint[0] joint_positions = joint[1] # if not the root joint, selecting the parent joint if index > 0: pm.select(joints[index-1], replace = True) # create joint and append to joints list new_joint = pm.PyNode(pm.joint(name = self.userSpecifiedName + ":" + joint_name, position = joint_positions) ) joints.append(new_joint) # if not the root joint, change the orient of the parent joint to defaults if index > 0: pm.joint(new_joint.getParent(), edit = True, orientJoint = "xyz", secondaryAxisOrient = "yup") pm.makeIdentity(new_joint, apply=True, translate=False, rotate=True, scale=False ) utils.addNodeToContainer(self.module_container, new_joint, ihb = True, includeNetwork = True) # Publish and bind rotation values for current joint to cointainer before locking; # this is important for later use with IK system setup to be able to rotate the joints attributes. pm.container(self.module_container, edit=True, publishAndBind=[new_joint + ".rotate", joint_name + "_r"]) pm.container(self.module_container, edit=True, publishAndBind=[new_joint + ".rotateOrder", joint_name + "_rotateOrder"]) pm.addAttr(new_joint, longName = "Meta", at="message") self.meta_node.ModuleJoints[index].connect(new_joint.Meta) index += 1 ''' mirrorBehavior = True mirrorXY = False mirrorYZ = False mirrorXZ = False pm.mirrorJoint(joints[0], mirrorBehavior = mirrorBehavior, mirrorXY = mirrorXY, mirrorYZ = mirrorYZ, mirrorXZ = mirrorXZ) ''' joints[0].setParent(self.joints_grp) joints[0].visibility.set(True) # TEMP- TURNING ON LOCAL AXIS for joint in joints: joint.displayLocalAxis.set(1) joint.template.set(1) # ------------------------------------------------------------------------- # # set up controls for the module module_control = controls.loadModuleControl(joints[0], self.userSpecifiedName, self.module_container) # install translation controls to each joint and parent it under the module control for joint in joints: #translation_controls[joint] = controls.loadTranslationControl(joint, self.userSpecifiedName, module_control) translation_controls.append(controls.loadTranslationControl(joint, self.userSpecifiedName,self.module_container, module_control) ) # point constraint root control to root joint pm.pointConstraint(translation_controls[0][0], joints[0], maintainOffset = False, name = self.userSpecifiedName + ":" + joints[0].stripNamespace() + "_rootTransContConstraint") self.initializeParentModuleSetup(translation_controls[0][0]) # ------------------------------------------------------------------------- # # set up stretch joint segments for index in range(len(joints) -1 ): # load joint rep onto joins # setup stretchy joint segments setupStretchyJointSegment = self.setupStretchyJointSegment(joints[index], joints[index + 1]) setupStretchyJointSegment[0].setParent(self.misc_grp) setupStretchyJointSegment[1].setParent(self.joints_grp) # ------------------------------------------------------------------------- # # parent items #module_control_grp.setParent(self.module_container) utils.addNodeToContainer(self.module_container, [self.misc_grp, self.joints_grp, module_control], ihb = True, includeNetwork = True) # don't know why, but cannot full delete the transform node pm.container(self.module_container, edit=True, publishAndBind=[module_control + ".translate", module_control.stripNamespace() + "_translate"]) pm.container(self.module_container, edit=True, publishAndBind=[module_control + ".rotate", module_control.stripNamespace() + "_rotate"]) pm.container(self.module_container, edit=True, publishAndBind=[module_control + ".scale", module_control.stripNamespace() + "_globalScale"]) # add meta information if self.module_container.hasAttr("MetaNode") == True: for node in pm.container(self.module_container, q = True, nodeList = True): if node.nodeType() != "network" or "joint": if not node.hasAttr("MetaNode"): pm.addAttr(node, longName="MetaNode", at="message") self.meta_node.ModuleNodes.connect(node.MetaNode) self.install_customAttributes() # ------------------------------------------------------------------------- # # lock nodes pm.lockNode(self.module_container, lock = True, lockUnpublished = True) pm.select(cl = True)
import pymel.core as pmc from functools import partial from bkTools.mayaSceneUtil import mergeShapes, addShapeToTrans, nextAvailableIndex,\ get_selected_cb_attrs, readJson, writeJson __author__ = "Brendan Kelly" __email__ = "*****@*****.**" """ A collection of utilities for building better rig controls. """ child_cmpnts = lambda c: (o for o in pmc.container(c, q=True, nl=True) if isinstance(o, pmc.nt.Container)) def publish_to_asset(nodes=None, name=None): """ Publish the given node to the given container. :param node: Node to publish :param asset: duh :param name: optional. if not given, just strip off ":" and "_ctrl" :return: None """ if not nodes: nodes = pmc.selected(transforms=True) asset = pmc.container(q=True, fc=nodes[0]) for node in nodes: name = node.replace(":", "").replace("_ctrl", "") if name == "global": name = "master"
def __init__(self): self.rig_container = pm.container(name = "PUPPET")
def getMetaNodeInfo(meta_node, attribute): meta_info = "" if meta_node.hasAttr(attribute) == True: meta_info = meta_node.attr(attribute).get() else: print ("{} does not have \"{}\" attribute".format(meta_node, attribute)) return meta_info #print getMetaNodeInfo(getMetaNode(), "Module") containerNodes = pm.container("ArmSegment1:moduleContainer", q = True, nodeList = True) for node in containerNodes: print node if node.nodeType() == "transform": if "ArmSegment:module_controlGRP" == node: print "FOUND NODE: {}".format(node) ''' def networkNode(self): self.meta_node = pm.createNode('network', n= self.userSpecifiedName + '_metaNode')
def Create(self, _name, _controlFile, _animationModuleInstance, _lod = 1, _translation = True, _rotation = True, _globalScale = True, _spaceSwitching = False): if _translation == True or _translation == False: translation = [_translation, _translation, _translation] if _rotation == True or _rotation == False: rotation = [_rotation, _rotation, _rotation] self.translation = translation self.rotation = rotation self.globalScale = _globalScale animationModuleName = _animationModuleInstance.moduleNamespace blueprintModuleNameSpace = _animationModuleInstance.blueprintNamespace blueprintModuleUserSpecifiedName = utils.StripAllNamespaces(blueprintModuleNameSpace)[1].partition("__")[2] animationModuleNamespace = "%s:%s" %(blueprintModuleNameSpace, animationModuleName) # import control object #controlObjectFile = "%s/ControlObjects/Animation/%s" %(self.directory, _controlFile) controlObjectFile = "%s/ControlObjects/Animation/%s" %(os.environ["RIGGING_TOOL_ROOT"], _controlFile) pm.importFile(controlObjectFile) self.controlObject = pm.rename("control", "%s:%s" %(animationModuleNamespace, _name)) self.rootParent = self.controlObject self.SetupIconScale(animationModuleNamespace) pm.setAttr("%s.overrideEnabled" %self.controlObject, 1) pm.setAttr("%s.overrideShading" %self.controlObject, 0) pm.connectAttr("%s:module_grp.overrideColor" %animationModuleNamespace, "%s.overrideColor" %self.controlObject) pm.container("%s:module_container" %animationModuleNamespace, edit = True, addNode = self.controlObject, includeHierarchyBelow = True, includeNetwork = True) if _globalScale: pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleX" %self.controlObject) pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleZ" %self.controlObject) pm.aliasAttr("globalScale", "%s.scaleY" %self.controlObject) attributes = [] if self.translation == [True, True, True]: attributes.append([True, ".translate", "T"]) else: attributes.extend([[translation[0], ".translateX", "TX"], [translation[1], ".translateY", "TY"], [translation[2], ".translateZ", "TZ"]]) if self.rotation == [True, True, True]: attributes.append([True, ".rotate", "R"]) else: attributes.extend([[rotation[0], ".rotateX", "RX"], [rotation[1], ".rotateY", "RY"], [rotation[2], ".rotateZ", "RZ"]]) attributes.append([_globalScale, ".globalScale", "scale"]) for attrInfo in attributes: if attrInfo[0]: attributeNiceName = "%s_%s" %(_name, attrInfo[2]) _animationModuleInstance.PublishNameToModuleContainer("%s%s" %(self.controlObject, attrInfo[1]), attributeNiceName, True) pm.select(self.controlObject, replace = True) pm.addAttr(attributeType = "bool", defaultValue = 1, keyable = True, longName = "display") _animationModuleInstance.PublishNameToModuleContainer("%s.display" %self.controlObject, "display", False) moduleGrp = "%s:module_grp" %animationModuleNamespace visibilityExpression = '%s.visibility = %s.display * (%s.levelOfDetail >= %d);' %(self.controlObject, self.controlObject, moduleGrp, _lod) expression = pm.expression(name = "%s_visibility_expression" %self.controlObject, string = visibilityExpression) utils.AddNodeToContainer("%s:module_container" %animationModuleNamespace, expression) return (self.controlObject, self.rootParent)
def CreateGroup(self, _groupName): fullGroupName = "Group__%s" %_groupName # Check for valid names if pm.objExists(fullGroupName): pm.confirmDialog(title = "Name Conflict", message = 'Group "%s" already exits.' %_groupName, button= "Accept", defaultButton = "Accept") return None groupTransform = pm.rename(self.tempGroupTransform, fullGroupName) # Create container for grouped objects groupContainer = "Group_container" if not pm.objExists(groupContainer): pm.container(name = groupContainer) # Store containers to be grouped in a list containers = [groupContainer] for obj in self.objectsToGroup: if obj.find("Group__") == 0: continue objNamespace = utils.StripLeadingNamespace(obj)[0] containers.append("%s:module_container" %objNamespace) # Unlock all grouped containers for c in containers: pm.lockNode(c, lock = False, lockUnpublished = False) if len(self.objectsToGroup) != 0: # Group objects temprorarily to simulate final heirarchy tempGroup = pm.group(self.objectsToGroup, absolute = True) groupParent = pm.listRelatives(tempGroup, parent = True) if groupParent != []: pm.parent(groupTransform, groupParent[0], absolute = True) pm.parent(self.objectsToGroup, groupTransform, absolute = True) pm.delete(tempGroup) self.AddGroupToContainer(groupTransform) # Lock all group containers for c in containers: pm.lockNode(c, lock = True, lockUnpublished = True) # Make sure the created group is selected pm.setToolTo("moveSuperContext") pm.select(groupTransform, replace = True) return groupTransform
def rigSymmetryTransform( *args, **kwargs): ''' 조인트를 미러링 하기 위해서 만들어진 스크립트 직접 유틸리티 노드로 미러링을 해서 구현을 했으나. 연결된 노드가 없어지면 조인트가 쪼그라드는 현상이 생김 이를 방지하기 위해 아래 컨테이너를 하나 거쳐서 연결 미러를 삭제하려면 아래 컨테니어를 삭제하면 미러링이 깨짐. 개선의 여지 있음. 제한된 상황에서만 올바르게 작동함. ''' if args: pm.select(args) sel = pm.selected() if not sel: print u'뭐라도 하나 선택하고 실행하세요.' return obj = sel[0] target=None if len(sel)>1: target = sel[1] axis = kwargs.get('axis', kwargs.get('ax','x') ) translate = kwargs.get('translate',kwargs.get('t',True) ) rotate = kwargs.get('rotate', kwargs.get('r',True) ) scale = kwargs.get('scale', kwargs.get('s',True) ) if not target: target=pm.spaceLocator( n= obj.name()+'__'+ axis.lower() +'axis_symmetryTrans_LOC') else: target = pm.PyNode(target) # 계산노드 md = pm.createNode('multiplyDivide') md.input2.set(-1,-1,-1) # 컨테이너에 연결함.. 직접연결할경우 cont = pm.container( type='dagContainer', addNode=[md], n=obj.name()+'__'+ axis.lower() +'axis_symmetryTrans_UTIL' ) if axis == 'x': if translate: # 해당 축이 꺼짐 #obj.tx >> target.tx if not target.ty.isLocked(): obj.ty >> cont.ty cont.ty >> target.ty if not target.tz.isLocked(): obj.tz >> cont.tz cont.tz >> target.tz # 해당 축이 켜짐 if not target.tx.isLocked(): obj.tx >> md.input1X md.outputX >> target.tx #obj.ty >> md.input1Y #md.outputY >> target.ty #obj.tz >> md.input1Z #md.outputZ >> target.tz if rotate: # 해당 축이 켜짐 if not target.rx.isLocked(): obj.rx >> cont.rx cont.rx >> target.rx #obj.ry >> target.ry if not target.rz.isLocked(): obj.rz >> cont.rz cont.rz >> target.rz # 해당 축이 꺼짐 #obj.rx >> md.input1X #md.outputX >> target.rx if not target.ry.isLocked(): obj.ry >> md.input1Y md.outputY >> target.ry if not target.rz.isLocked(): obj.rz >> md.input1Z md.outputZ >> target.rz elif axis == 'y': if translate: # 해당 축이 꺼짐 if not target.tx.isLocked(): obj.tx >> cont.tx cont.tx >> target.tx #obj.ty >> target.ty if not target.tz.isLocked(): obj.tz >> cont.tz cont.tz >> target.tz # 해당 축이 켜짐 #obj.tx >> md.input1X #md.outputX >> target.tx if not target.ty.isLocked(): obj.ty >> md.input1Y md.outputY >> target.ty #obj.tz >> md.input1Z #md.outputZ >> target.tz if rotate: # 해당 축이 켜짐 #obj.rx >> target.rx if not target.ry.isLocked(): obj.ry >> cont.ry cont.ry >> target.ry #obj.rz >> target.rz # 해당 축이 꺼짐 if not target.rx.isLocked(): obj.rx >> md.input1X md.outputX >> target.rx #obj.ry >> md.input1Y #md.outputY >> target.ry if not target.rz.isLocked(): obj.rz >> md.input1Z md.outputZ >> target.rz elif axis == 'z': if translate: # 해당 축이 꺼짐 if not target.tx.isLocked(): obj.tx >> cont.tx cont.tx >> target.tx if not target.ty.isLocked(): obj.ty >> cont.ty cont.ty >> target.ty #obj.tz >> target.tz # 해당 축이 켜짐 #obj.tx >> md.input1X #md.outputX >> target.tx #obj.ty >> md.input1Y #md.outputY >> target.ty if not target.tz.isLocked(): obj.tz >> md.input1Z md.outputZ >> target.tz if rotate: # 해당 축이 꺼짐 if not target.rx.isLocked(): obj.rx >> md.input1X md.outputX >> target.rx if not target.ry.isLocked(): obj.ry >> md.input1Y md.outputY >> target.ry #obj.rz >> md.input1Z #md.outputZ >> target.rz # 해당 축이 켜짐 #obj.rx >> target.rx #obj.ry >> target.ry if not target.rz.isLocked(): obj.rz >> cont.rz cont.rz >> target.rz if scale: if not target.sx.isLocked(): obj.sx >> cont.sx cont.sx >> target.sx if not target.sy.isLocked(): obj.sy >> cont.sy cont.sy >> target.sy if not target.sz.isLocked(): obj.sz >> cont.sz cont.sz >> target.sz pm.select( obj ) return cont, target