def getAttrXML( presets=False ): presetPath = XMLUtility.getPresetPath( '' ) fullPath = '{0}frames/bits/bitAttributes.xml'.format( presetPath ) returnList = [] xmlDoc = ET.parse( fullPath ) xmlRoot = xmlDoc.getroot() if presets: presetList = xmlRoot.find( 'presets' ) for preset in presetList.findall( 'preset' ): tempList = { 'presetName':preset.get('name') } tempList['attrs'] = [] for attr in preset.findall( 'attr' ): tempList['attrs'].append( attr.get('name') ) returnList.append( tempList ) else: attrList = xmlRoot.find( 'attributes' ) for attr in attrList.findall( 'attr' ): returnList.append( { 'name':attr.get('name'), 'attrType':attr.get('attrType'), 'attrDataType':attr.get('attrDataType') } ) return returnList
def buildFrameModule( inDir=None, inXMLFile=None ): from marigold.meta.metaNode import MetaNode # Get the XML settings for the frame module. dirPath = XMLUtility.getPresetPath( XMLUtility.FRAME_PRESETS_PATH+inDir ) fullPath = dirPath+'/'+inXMLFile+'.xml' xmlDict = readFrameModuleXML( fullPath ) # Get the metanode. metanode = xmlDict['metanode'] meta = metanode['name'] metaPlugs = metanode['plugs'] metaType = metanode['metaType'] metaClass = metanode['metaClass'] metanode = MetaNode( inNodeName=meta, inNodeMetaType=metaType ) metanode = cmds.ls( selection=True )[0] metaPlugs = xmlDict['metanode']['plugs'] for plug in metaPlugs: if not NodeUtility.attributeCheck( metanode, plug['name'] ): addPlug( metanode, plug['name'], plug['attrType'], plug['attrDataType'] ) if plug['connected'] == 'False': setPlug( metanode, plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) # Get the bits. bits = xmlDict['bits'] # Make a group for the module. for bit in bits: if bit['name'] == 'frame_root': for plug in bit['plugs']: if plug['name'] == 'prefix': modulePrefix = plug['value'] break moduleGroup = '|{0}'.format( cmds.group( em=True, name=modulePrefix+'_'+metaClass ) ) # Make each bit. tick = 0 storeBitConnections = [] while tick < len(bits): bitName = bits[0]['name'] if bits[0]['parent'] == 'None': # This is the root bit. The | is there to represent this. We don't need it now. # Plus it causes problems with the full path name stuff (double ||). So we # remove it. bitParent = moduleGroup else: bitParent = moduleGroup+bits[0]['parent'] bitPlugs = bits[0]['plugs'] bitShape = bits[0]['shape'] # Make the bit. if cmds.objExists( bitParent ): newBit = cmds.makeGLBit( name=bitName, objecttype=bits[0]['shapeType'] ) cmds.parent( newBit, bitParent ) # From this point we use the long name for the bit. This avoids any # name clashes. fullBitName = '{0}{1}'.format( bitParent, newBit ) # Get the frame_root for the module. We want to return this at the very end. if bitName == 'frame_root': rootFullName = fullBitName # Setup plugs for transform and custom attributes. for plug in bitPlugs: if not NodeUtility.attributeCheck( fullBitName, plug['name'] ): addPlug( fullBitName, plug['name'], plug['attrType'], plug['attrDataType'] ) if plug['value'] is not None: setPlug( fullBitName, plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) else: # Setup position and rotation. setPlug( fullBitName, plug['name'], plug['value'] ) # Connect plug to meta node. for mplug in metaPlugs: if '{0}.{1}'.format(bitName, plug['name']) == mplug['value']: inSourcePlug = fullBitName+'.'+plug['name'] inDestinationPlug = metanode+'.'+mplug['name'] NodeUtility.connectPlugs( inSourcePlug, inDestinationPlug ) # Setup plugs for shape attributes. shapeName = cmds.listRelatives( fullBitName, shapes=True ) fullShapeName = '{0}|{1}'.format( fullBitName, shapeName[0] ) for plug in bitShape: if plug['attrDataType'] == 'TdataCompound': # We skip compound nodes at this stage. They are for the child arrow drawing and must be # hooked up after all the objects are created. connectionChild = '{0}{1}'.format( moduleGroup, plug['value'] ) storeBitConnections.append( { 'parent':fullBitName, 'child':connectionChild } ) else: setPlug( fullShapeName, plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) bits.remove( bits[0] ) else: tick = tick+1 pass # Now do the hook ups for the child arrows. for i in storeBitConnections: setBitChild( i['parent'], i['child'] ) return rootFullName
def readFrameModuleXML( inFile=None, inCallScript=False ): ''' Processes an XML file to get the parts/settings for the module. @param inFullPath: Full directory path + filename + extension of the XML file. @return: A dictionary. ''' import xml.etree.ElementTree as ET if inFile is None: # 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 ) ) else: dialogResults = [ inFile ] returnDict = {} xmlDoc = ET.parse( dialogResults[0] ) xmlRoot = xmlDoc.getroot() # Process meta nodes. for metanode in xmlRoot.findall( 'metanode' ): metaType = metanode.get( 'metaType' ) returnDict[ 'metanode' ] = { 'name':metanode.get('name'), 'metaType':metanode.get('metaType'), 'metaClass':metanode.get('metaClass') } plugList = [] for plug in metanode.findall( 'plug' ): plugList.append( { 'name':plug.get('name'), 'connected':plug.get('connected'), 'attrType':plug.get('attrType'), 'attrDataType':plug.get('attrDataType'), 'value':plug.text } ) returnDict[ 'metanode' ].update( { 'plugs':plugList } ) # Process bit nodes. bitList = [] for bit in xmlRoot.findall( 'bit' ): # Get shape type. shape = bit.findall( 'shape' ) shapeType = shape[0].get('name') bitDict = { 'name':bit.get('name'), 'parent':bit.get('parent'), 'shapeType':shapeType } plugList = [] for plug in bit.findall( 'plug' ): plugList.append( { 'name':plug.get('name'), 'attrType':plug.get('attrType'), 'attrDataType':plug.get('attrDataType'), 'value':plug.text } ) bitDict[ 'plugs' ] = plugList shapePlugList = [] for plug in shape[0].findall( 'plug' ): shapePlugList.append( { 'name':plug.get('name'), 'attrType':plug.get('attrType'), 'attrDataType':plug.get('attrDataType'), 'value':plug.text } ) bitDict[ 'shape' ] = shapePlugList bitList.append( bitDict ) returnDict[ 'bits' ] = bitList # Call the script. if inCallScript: pass else: # Or just return the list. return returnDict
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()