def buildNode( cls, nodeName ): ''' Builds a curve control. @param nodeName: String. Name of the node. ''' # Create the curve. curveNode = CurveControlComponent( nodeName ).createCurveControl( cls( nodeName ).controlName, cls( nodeName ).curveType ) controlName = OpenMaya.MDagPath.getAPathTo( curveNode ).fullPathName() # Set the control to the transform matrix. applyStoredTransforms( nodeName, controlName ) # Get the saved properties and apply them to the curve. cvList = NurbsCurveUtility.readCurveValues( nodeName ) cvPointArray = NurbsCurveUtility.buildCVPointArray( cvList ) NurbsCurveUtility.setCurveCvs( controlName, cvPointArray ) # Color. GeneralUtility.setUserColor( controlName, userColor=cls( nodeName ).controlColor ) # Create the control spacer. transReference = NodeUtility.getNodeAttrSource( nodeName, 'parentName' ) controlSpacer = GeneralUtility.createSpacer( None, inGroupName=cls( nodeName ).controlName, inTargetObject=transReference[0], inDoParent=False, inPrefix='sp' ) cmds.parent( controlName, controlSpacer, relative=True ) return curveNode
def buildNode( cls, nodeName ): ''' Builds a GL Box control. @param nodeName: String. Name of the node. ''' jointName = cmds.getAttr( '{0}.jointName'.format( nodeName ) ) transReference = NodeUtility.getNodeAttrSource( nodeName, 'parentName' )
def mirrorModule(): # Mirrors a module. selList = cmds.ls( selection=True, long=True ) if len( selList ) == 1: # Prompt for axis. mirrorAxis = int( cmds.layoutDialog( ui=mirrorObjectPrompt ) ) inBitObj = selList[0] # Check if selected bit is the root. if NodeUtility.attributeCheck( inBitObj, 'frameRoot' ): # This is the root bit of the module. From here we know we can get the # meta node by accessing the frameRoot attribute. metaNode = NodeUtility.getNodeAttrDestination( inBitObj, 'frameRoot' )[0] else: # The selected bit is not the root. Run through each custom attribute # to find one connected to the meta node. attrList = cmds.listAttr( inBitObj, userDefined=True ) for attr in attrList: connection = NodeUtility.getNodeAttrDestination( inBitObj, attr ) if NodeUtility.attributeCheck( connection[0], 'metaType' ): metaNode = connection[0] break # Now that we have the meta node, we need the XML file name and it's location. metaClassPlug = NodeUtility.getPlug( metaNode, 'metaClass' ) metaClassValue = NodeUtility.getPlugValue( metaClassPlug ) metaBuildFolderPlug = NodeUtility.getPlug( metaNode, 'buildFolder' ) metaBuildFolderValue = NodeUtility.getPlugValue( metaBuildFolderPlug ) # Create the target module. ''' NEED TO FIX THIS! targetRootBit = buildFrameModule( metaBuildFolderValue, metaClassValue ) ''' # Loop through each object in the source module. metaRootBit = NodeUtility.getNodeAttrSource( metaNode, 'rootBit' )[0] sourceChildBits = NodeUtility.getFrameRootAllChildren( metaRootBit ) targetChildBits = NodeUtility.getFrameRootAllChildren( targetRootBit ) sourceBits = [] targetBits = [] for i,bit in enumerate( sourceChildBits ): sourceBits.append( bit ) sourceBits.insert( 0, metaRootBit ) for i, bit in enumerate( targetChildBits ): targetBits.append( bit ) targetBits.insert( 0, targetRootBit ) for bit in xrange( len(sourceBits) ): # Mirror the source onto the target. mirrorObject( inSourceObj=sourceBits[bit], inTargetObj=targetBits[bit], inMirrorAxis=mirrorAxis )
def deleteComponentFromObject( cls, inCompNode ): ''' Deletes the selected component from the object. Used in right-click menu for components GUI. ''' obj = NodeUtility.getNodeAttrSource( inCompNode, 'parentName' ) cmds.deleteAttr( '{0}.{1}'.format( obj[0], obj[1] ) ) cmds.delete( inCompNode ) cmds.select( obj[0] )
def buildNode( cls, nodeName ): ''' Builds a joint. @param nodeName: String. Name of the node. ''' jointName = cmds.getAttr( '{0}.jointName'.format( nodeName ) ) transReference = NodeUtility.getNodeAttrSource( nodeName, 'parentName' ) return marigoldJoints.createJoint( jointName, transReference[0] )
def getFramesInSceneWIP(): # Get all the meta nodes in the scene. metaNodes = NodeUtility.getMetaNodesInScene() print metaNodes if not metaNodes: return None else: for node in metaNodes: # Get the root bit of the frame module. rootBit = NodeUtility.getNodeAttrSource( node, 'rootBit' ) # Get the parent's full path. We need to remove the group name from the beginning as well. parent = cleanParentFullName( rootBit[0] ) print parent
def buildLists( self ): ''' Builds a list of all modules in a character. ''' modList = getCharacterChildrenModules( self.charNode ) self.conMods = {} self.disMods = {} for mod in modList: charRoot = NodeUtility.getNodeAttrSource( mod, 'characterRoot' ) moduleName = cmds.getAttr( '{0}.moduleName'.format( mod ) ) if charRoot is not None: self.conMods[moduleName] = mod else: self.disMods[moduleName] = mod
def createFrameModuleXML(): # Browse for file to replace or new file to make. moduleFilter = "*.xml" dialogResults = cmds.fileDialog2( fileFilter=moduleFilter, dialogStyle=2, startingDirectory=XMLUtility.getPresetPath( XMLUtility.FRAME_PRESETS_PATH ) ) tempPath = dialogResults[0].split( '/' ) fullFileName = tempPath[ len( tempPath )-1 ] filePath = dialogResults[0].rstrip( fullFileName ) fileName = fullFileName.split( '.' )[0] # Get the name of the selected node and it's plugs. selList = cmds.ls( selection=True ) node = selList[0] nodeAttrs = getFrameBitSettings( node ) # Build a list with each entry representing a line in the XML file. xmlList = [] xmlList.append( '<data>' ) # Set the first line # Meta node. xmlList.append( '\t<metanode name=\"{0}\" metaType=\"{1}\" metaClass=\"{2}\">'.format( node, nodeAttrs['metaType'], nodeAttrs['metaClass'] ) ) # Loop through the attributes. for attr in nodeAttrs: plug = NodeUtility.getPlug( node, attr ) if plug.isConnected(): connection = NodeUtility.getNodeAttrSource( node, attr ) types = getAttrTypes( node, attr ) xmlList.append( '\t\t<plug name=\"{0}\" connected=\"{1}\" attrType=\"{2}\" attrDataType=\"{3}\">{4}</plug>'.format( attr, True, types[0], types[1], connection[0]+'.'+connection[1] ) ) else: types = getAttrTypes( node, attr ) xmlList.append( '\t\t<plug name=\"{0}\" connected=\"{1}\" attrType=\"{2}\" attrDataType=\"{3}\">{4}</plug>'.format( attr, False, types[0], types[1], NodeUtility.getPlugValue( plug ) ) ) xmlList.append( '\t</metanode>' ) # Get the root bit of the frame module. rootBit = NodeUtility.getNodeAttrSource( node, 'rootBit' ) if not rootBit: raise ValueError( 'The meta node\'s ({0}) ROOT BIT attribute is not connected.'.format(node) ) # Get the parent's full path. We need to remove the group name from the beginning as well. parent = cleanParentFullName( rootBit[0] ) xmlList.append( '\t<bit name=\"{0}\" parent=\"{1}\">'.format( rootBit[0], parent ) ) rootAttrs = getFrameBitSettings( rootBit[0] ) for attr in rootAttrs: types = getAttrTypes( rootBit[0], attr ) plug = NodeUtility.getPlug( rootBit[0], attr ) xmlList.append( '\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], NodeUtility.getPlugValue( plug ) ) ) wmRootBit = TransformUtility.getMatrix( rootBit[0], 'matrix' ) pos = TransformUtility.getMatrixTranslation( wmRootBit, OpenMaya.MFn.kWorld ) rot = TransformUtility.getMatrixRotation( wmRootBit, 'eulerVector' ) xmlList.append( '\t\t<plug name=\"translateX\">{0}</plug>'.format( pos.x ) ) xmlList.append( '\t\t<plug name=\"translateY\">{0}</plug>'.format( pos.y ) ) xmlList.append( '\t\t<plug name=\"translateZ\">{0}</plug>'.format( pos.z ) ) xmlList.append( '\t\t<plug name=\"rotateX\">{0}</plug>'.format( math.degrees(rot.x) ) ) xmlList.append( '\t\t<plug name=\"rotateY\">{0}</plug>'.format( math.degrees(rot.y) ) ) xmlList.append( '\t\t<plug name=\"rotateZ\">{0}</plug>'.format( math.degrees(rot.z) ) ) # Shape nodes attributes. rootShape = NodeUtility.getDagPath( rootBit[0] ).child( 0 ) depFn = OpenMaya.MFnDependencyNode( rootShape ) shapeName = cmds.listRelatives( rootBit[0], shapes=True, fullPath=True )[0] shapeType = depFn.typeName() xmlList.append( '\t\t<shape name=\"{0}\">'.format( shapeType ) ) # Get the shape's local position and scale. for attr in cmds.listAttr( shapeName, channelBox=True ): types = getAttrTypes( shapeName, attr ) aPlug = NodeUtility.getPlug( shapeName, attr ) xmlList.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], NodeUtility.getPlugValue(aPlug) ) ) # Get the shape's custom attributes. for attr in cmds.listAttr( shapeName, multi=True, keyable=True ): if attr.find( '[' ) is not -1: # Special case handle array attributes. The [] needs to be removed so we can get # the base name for the attribute. From there we can then loop through it's children. # First we get the connection since these plugs won't return a value, but rather a # connected node. connection = NodeUtility.getNodeAttrSource( shapeName, attr ) bitChildren = cmds.listRelatives( rootBit[0], type='transform', children=True, fullPath=True ) for child in bitChildren: if child.find( connection[0] ): plugValue = child # Now we get the compound attribute's name by removing the index brackets. attrSplit = attr.split('[') attr = attrSplit[0] else: aPlug = NodeUtility.getPlug( shapeName, attr ) plugValue = NodeUtility.getPlugValue( aPlug ) types = getAttrTypes( shapeName, attr ) if types[0] is not False: xmlList.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], plugValue ) ) xmlList.append( '\t\t</shape>' ) xmlList.append( '\t</bit>') # Get all of the root's children. children = getFrameRootAllChildren( rootBit[0] ) for child in children: # Bit name. bitName = child parent = cleanParentFullName( child ) childFrameAttrs = getFrameBitSettings( child ) xmlList.append( '\t<bit name=\"{0}\" parent=\"{1}\">'.format( bitName, parent ) ) # Transform nodes attributes. if childFrameAttrs is not None: for attr in childFrameAttrs: types = getAttrTypes( child, attr ) plug = NodeUtility.getPlug( child, attr ) xmlList.append( '\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], NodeUtility.getPlugValue( plug ) ) ) # Get the position and rotation. wmBit = TransformUtility.getMatrix( child, 'matrix' ) pos = TransformUtility.getMatrixTranslation( wmBit, OpenMaya.MFn.kWorld ) rot = TransformUtility.getMatrixRotation( wmBit, 'eulerVector' ) xmlList.append( '\t\t<plug name=\"translateX\">{0}</plug>'.format( pos.x ) ) xmlList.append( '\t\t<plug name=\"translateY\">{0}</plug>'.format( pos.y ) ) xmlList.append( '\t\t<plug name=\"translateZ\">{0}</plug>'.format( pos.z ) ) xmlList.append( '\t\t<plug name=\"rotateX\">{0}</plug>'.format( math.degrees(rot.x) ) ) xmlList.append( '\t\t<plug name=\"rotateY\">{0}</plug>'.format( math.degrees(rot.y) ) ) xmlList.append( '\t\t<plug name=\"rotateZ\">{0}</plug>'.format( math.degrees(rot.z) ) ) # Shape nodes attributes. childShape = NodeUtility.getDagPath( child ).child( 0 ) depFn = OpenMaya.MFnDependencyNode( childShape ) shapeName = cmds.listRelatives( child, shapes=True, fullPath=True )[0] shapeType = depFn.typeName() xmlList.append( '\t\t<shape name=\"{0}\">'.format( shapeType ) ) # Get the shape's local position and scale. for attr in cmds.listAttr( shapeName, channelBox=True ): types = getAttrTypes( shapeName, attr ) aPlug = NodeUtility.getPlug( shapeName, attr ) xmlList.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], NodeUtility.getPlugValue(aPlug) ) ) # Get the shape's custom attributes. for attr in cmds.listAttr( shapeName, multi=True, keyable=True ): if attr.find( '[' ) is not -1: # Special case handle array attributes. The [] needs to be removed so we can get # the base name for the attribute. From there we can then loop through it's children. # First we get the connection since these plugs won't return a value, but rather a # connected node. connection = NodeUtility.getNodeAttrSource( shapeName, attr ) bitChildren = cmds.listRelatives( child, type='transform', children=True, fullPath=True ) for c in bitChildren: if c.find( connection[0] ): plugValue = c # Now we get the compound attribute's name by removing the index brackets. attrSplit = attr.split('[') attr = attrSplit[0] else: aPlug = NodeUtility.getPlug( shapeName, attr ) plugValue = NodeUtility.getPlugValue( aPlug ) types = getAttrTypes( shapeName, attr ) if types[0] is not False: xmlList.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], plugValue ) ) xmlList.append( '\t\t</shape>' ) # Close the bit. xmlList.append( '\t</bit>' ) # Close the data tag. xmlList.append( '</data>' ) # Create the new file. newfile = file( os.path.join( filePath, fullFileName ), 'w') for i in xmlList: newfile.write( i+'\n' ) newfile.close()
def writeModuleXML( inRootObjectName, inModuleType, inModuleName ): ''' Function for writing module xml. @param inRootObjectName: String. Name of module root object. @param inModuleType: String. Type of module. This determines which sub-folder the XML is saved. @param inModuleName: String. Name of the module XML file. ''' # Get list of the module hierarchy. Root is always first hierarchyList = NodeUtility.getFrameRootAllChildren( inRootObjectName ) hierarchyList.insert( 0, inRootObjectName ) # START: Writing XML xmlLines = [] xmlLines.append( '<data>' ) for item in hierarchyList: # BIT INFO itemName = getObjectShortName( item ) itemParent = NodeUtility.cleanParentFullName( item ) itemMatrix = TransformUtility.getMatrix( item, 'matrix' ) itemPosition = TransformUtility.getMatrixTranslation( itemMatrix, OpenMaya.MSpace.kTransform ) itemRotation = TransformUtility.getMatrixRotation( itemMatrix, 'eulerVector' ) # START: Bit xmlLines.append( '\t<bit name=\"{0}\" parent=\"{1}\">'.format( itemName, itemParent ) ) xmlLines.append( '\t\t<plug name=\"translateX\">{0}</plug>'.format( itemPosition.x ) ) xmlLines.append( '\t\t<plug name=\"translateY\">{0}</plug>'.format( itemPosition.y ) ) xmlLines.append( '\t\t<plug name=\"translateZ\">{0}</plug>'.format( itemPosition.z ) ) xmlLines.append( '\t\t<plug name=\"rotateX\">{0}</plug>'.format( math.degrees(itemRotation.x) ) ) xmlLines.append( '\t\t<plug name=\"rotateY\">{0}</plug>'.format( math.degrees(itemRotation.y) ) ) xmlLines.append( '\t\t<plug name=\"rotateZ\">{0}</plug>'.format( math.degrees(itemRotation.z) ) ) # SHAPE itemShape = NodeUtility.getDagPath( itemName ).child( 0 ) depFn = OpenMaya.MFnDependencyNode( itemShape ) shapeType = depFn.typeName() if shapeType.find( 'gl' ) != -1: itemShapeName = cmds.listRelatives( itemName, shapes=True, fullPath=True )[0] # Start shape xmlLines.append( '\t\t<shape name=\"{0}\">'.format( shapeType ) ) # Get the shape's local position and scale. for attr in cmds.listAttr( itemShapeName, channelBox=True ): types = NodeUtility.getAttrTypes( itemShapeName, attr ) aPlug = NodeUtility.getPlug( itemShapeName, attr ) xmlLines.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], NodeUtility.getPlugValue(aPlug) ) ) # Get the shape's custom attributes. for attr in cmds.listAttr( itemShapeName, multi=True, keyable=True ): types = NodeUtility.getAttrTypes( itemShapeName, attr ) if attr.find( '[' ) is not -1: # Special case handle array attributes. The [] needs to be removed so we can get # the base name for the attribute. From there we can then loop through it's children. # First we get the connection since these plugs won't return a value, but rather a # connected node. connection = NodeUtility.getNodeAttrSource( itemShapeName, attr ) bitChildren = cmds.listRelatives( itemName, type='transform', children=True, fullPath=True ) for child in bitChildren: childSplit = child.split('|') if childSplit[-1] == connection[0]: plugValue = child # Now we get the compound attribute's name by removing the index brackets. attrSplit = attr.split('[') attr = attrSplit[0] else: aPlug = NodeUtility.getPlug( itemShapeName, attr ) plugValue = NodeUtility.getPlugValue( aPlug ) if types[0] is not False: xmlLines.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], plugValue ) ) # End shape xmlLines.append( '\t\t</shape>' ) # BIT COMPONENTS print 'item: {0}'.format( item ) bitComponents = components.getComponents( item ) for comp in bitComponents: # Component info compName = ''.join(i for i in comp if not i.isdigit()) # Start component. xmlLines.append( '\t\t<component name=\"{0}\">'.format( compName ) ) compSettings = NodeUtility.getModuleComponentSettings( comp ) for attr in compSettings: types = NodeUtility.getAttrTypes( comp, attr ) # Special case message plugs. if types[1] == 'message': messageValues = NodeUtility.getAttrMessageValue( comp, attr ) if isinstance( messageValues, unicode ): plugValue = messageValues elif isinstance( messageValues, list ): plugValue = None else: aPlug = NodeUtility.getPlug( comp, attr ) plugValue = NodeUtility.getPlugValue( aPlug ) xmlLines.append( '\t\t\t<plug name=\"{0}\" attrType=\"{1}\" attrDataType=\"{2}\">{3}</plug>'.format( attr, types[0], types[1], plugValue ) ) xmlLines.append( '\t\t</component>' ) # END: Bit xmlLines.append( '\t</bit>' ) # END: Writing XML xmlLines.append( '</data>' ) # Create the file startingDirectory = getPresetPath( FRAME_PRESETS_PATH ) filePath = '{0}{1}'.format( startingDirectory, inModuleType ) fileName = '{0}.xml'.format( inModuleName ) newfile = file( os.path.join( filePath, fileName ), 'w') for i in xmlLines: newfile.write( i+'\n' ) newfile.close()
def parentNode( self ): if cmds.attributeQuery( 'parentName', node=self.node, exists=True ): return NodeUtility.getNodeAttrSource( self.node, 'parentName' )
def buildModule(): ''' Build function for all the rigging associated with this module. ''' # Get the frame module meta nodes in the scene. modules = NodeUtility.getMetaNodesInScene( 'frameModule' ) # Read the meta node. nodeData = NodeUtility.getFrameBitSettings( modules[0] ) prefix = nodeData['prefix'] # Get the frame module bits. frameRoot = NodeUtility.getNodeAttrSource( modules[0], 'rootBit' )[0] shoulderBit = NodeUtility.getNodeAttrSource( modules[0], 'jShoulder' )[0] elbowBit = NodeUtility.getNodeAttrSource( modules[0], 'jElbow' )[0] wristBit = NodeUtility.getNodeAttrSource( modules[0], 'jWrist' )[0] ikRootBit = NodeUtility.getNodeAttrSource( modules[0], 'ikRoot' )[0] ikEndBit = NodeUtility.getNodeAttrSource( modules[0], 'ikEnd' )[0] ikUpVecBit = NodeUtility.getNodeAttrSource( modules[0], 'ikUpVecControl' )[0] # Build shadow skeleton. jointShoulder = marigoldJoints.createJoint( nodeData['jShoulder'], shoulderBit, inPrefix=prefix ) jointElbow = marigoldJoints.createJoint( nodeData['jElbow'], elbowBit, jointShoulder, inPrefix=prefix ) jointWrist = marigoldJoints.createJoint( nodeData['jWrist'], wristBit, jointElbow, inPrefix=prefix ) # Make the FK rigging. fkControls = [ [nodeData['fkShoulderControl'], nodeData['fkShoulderControlName'], nodeData['jShoulder'], shoulderBit], [nodeData['fkElbowControl'], nodeData['fkElbowControlName'], nodeData['jElbow'],elbowBit] ] for i in fkControls: # Create the spacer. spacerName = 'j_{0}_{1}'.format( prefix, i[2] ) newSpacer = marigoldControls.makeControl().createSpacer( i[3], i[1], spacerName, True ) # Create the controller. controlSplit = i[0].split( '.' ) marigoldControls.makeControl().createController( controlSplit[0], controlSplit[1], i[1], newSpacer ) # Make the IK rigging. effSplit = nodeData['ikEffControl'].split('.') effSpacer = marigoldControls.makeControl().createSpacer( ikEndBit, nodeData['ikEffControlName'], 'j_'+prefix+'_'+nodeData['jWrist'], inDoParent=False, inPrefix=prefix ) marigoldControls.makeControl().createController( effSplit[0], effSplit[1], nodeData['ikEffControlName'], effSpacer, inPrefix=prefix ) upVecSplit = nodeData['ikUpVecControl'].split('.') upVecSpacer = marigoldControls.makeControl().createSpacer( ikUpVecBit, nodeData['ikUpVecControlName'], ikUpVecBit, inDoParent=False, inPrefix=prefix ) marigoldControls.makeControl().createController( upVecSplit[0], upVecSplit[1], nodeData['ikUpVecControlName'], upVecSpacer, inPrefix=prefix ) jointFn = OpenMayaAnim.MFnIkJoint() # IK root joint. jointShoulder = 'j_{0}_{1}'.format( prefix, nodeData['jShoulder'] ) rootJointDagPath = NodeUtility.getDagPath( jointShoulder ) # IK eff joint. jointWrist = 'j_{0}_{1}'.format( prefix, nodeData['jWrist'] ) effJointDagPath = NodeUtility.getDagPath( jointWrist ) # Do up the solver. ikHandleName = '{0}_{1}_arm'.format( nodeData['ikEffControlName'], prefix ) cmds.ikHandle( name=ikHandleName, startJoint=rootJointDagPath.fullPathName(), endEffector=effJointDagPath.fullPathName(), solver='ikRPsolver' ) effControlName = 'ct_{0}_{1}'.format( prefix, nodeData['ikEffControlName'] ) cmds.parent( ikHandleName, effControlName, absolute=True ) upVecControlName = 'ct_{0}_{1}'.format( prefix, nodeData['ikUpVecControlName'] ) cmds.poleVectorConstraint( upVecControlName, ikHandleName )