Esempio n. 1
0
def storeControlTransforms( sourceObj, targetObj ):
    '''
    Store control transform data.
    
    @param sourceObj: String. Name of object to pull data from.
    @param targetObj: String. Name of object to store data on.
    '''    
    sourceMatrix = TransformUtility.getMatrix( sourceObj, 'matrix' )
    
    # Store the position
    targetPosPlug = NodeUtility.getPlug( targetObj, 'controlPosition' )
    sourceTranslation = TransformUtility.getMatrixTranslation( sourceMatrix, OpenMaya.MSpace.kTransform )
    pos = [ sourceTranslation.x, sourceTranslation.y, sourceTranslation.z ]
    NodeUtility.setPlugValue( targetPosPlug, pos )
    
    # Store the rotation
    targetRotPlug = NodeUtility.getPlug( targetObj, 'controlRotation' )
    sourceRotation = TransformUtility.getMatrixRotation( sourceMatrix, 'euler' )
    #rot = [ degrees(angle) for angle in (sourceRotation.x, sourceRotation.y, sourceRotation.z) ]
    rot = [ sourceRotation.x, sourceRotation.y, sourceRotation.z ]
    NodeUtility.setPlugValue( targetRotPlug, rot )
    
    # Store the scale.
    targetSclPlug = NodeUtility.getPlug( targetObj, 'controlScale' )
    sourceScale = TransformUtility.getMatrixScale( sourceMatrix, OpenMaya.MSpace.kTransform )
    scl = [ sourceScale.x, sourceScale.y, sourceScale.z ]
    NodeUtility.setPlugValue( targetSclPlug, scl )
Esempio n. 2
0
 def bitsGUI( self ):
     col = cmds.columnLayout( adjustableColumn=True, columnAttach=('both', 5), parent=self.fillArea )
     cmds.separator( style='none', height=4, width=413 )
     
     # Primitives section.
     cmds.text( label='BIT PRIMITIVES', height=20, font='boldLabelFont', backgroundColor=[0.2,0.2,0.2] )
     cmds.separator( style='none', height=5 )
     cmds.gridLayout( numberOfColumns=5, cellWidthHeight=( 50, 50 ) )
     cmds.button( label='Sphere', command=lambda b, a1='glSphere': cmds.makeGLBit( objecttype=a1 ) )
     cmds.button( label='Box', command=lambda b, a1='glBox': cmds.makeGLBit( objecttype=a1 ) )
     cmds.button( label='Cylinder', command=lambda b, a1='glCylinder': cmds.makeGLBit( objecttype=a1 ) )
     cmds.button( label='Cone', command=lambda b, a1='glCone': cmds.makeGLBit( objecttype=a1 ) )
     cmds.button( label='Torus', command=lambda b, a1='glTorus': cmds.makeGLBit( objecttype=a1 ) )
     cmds.setParent( '..' )#gridLayout
     cmds.separator( style='none', height=10 )
     
     # Transform section.
     cmds.text( label='TRANSFORM TOOLS', height=20, font='boldLabelFont', backgroundColor=[0.2,0.2,0.2] )
     cmds.separator( style='none', height=5 )
     cmds.gridLayout( numberOfColumns=3, cellWidthHeight=( 50, 50 ) )
     cmds.iconTextButton( annotation='match translation', style='iconOnly',
                          image1='icon_match_translation.png',
                          command=lambda a1='tran': TransformUtility.matchTransforms(a1) )
     cmds.iconTextButton( annotation='match rotation', style='iconOnly',
                          image1='icon_match_rotation.png',
                          label='match rotation', command=lambda a1='rot': TransformUtility.matchTransforms(a1) )
     cmds.iconTextButton( annotation='match all', style='iconOnly',
                          image1='icon_match_all.png',
                          label='match all', command=lambda a1='all': TransformUtility.matchTransforms(a1) )
     cmds.setParent( '..' )#gridLayout
     cmds.separator( style='none', height=10 )
     
     cmds.setParent( '..' )#col 
Esempio n. 3
0
def mirrorObject( inSourceObj=None, inTargetObj=None, inMirrorAxis=None ):
    # Mirrors the position and rotation of one object(source) and applies it to another (target).
    
    if inSourceObj is None or inTargetObj is None:
        # Target object should be selected first, followed by source object.
        selList = cmds.ls( selection=True, long=True )
        if len( selList ) == 2:
            inTargetObj = selList[0]
            inSourceObj = selList[1]
        
    if inMirrorAxis is None:
        inMirrorAxis = int( cmds.layoutDialog( ui=mirrorObjectPrompt ) )
        
    if inMirrorAxis is not None:
        # Get the source module's root world matrix.
        sourceWorldMatrix = TransformUtility.getMatrix( inSourceObj, 'worldMatrix' )
        
        # Get the source's translation vector.
        sourceWorldTranslation = TransformUtility.getMatrixTranslation( sourceWorldMatrix, OpenMaya.MFn.kWorld )
        
        # Get the source's rotation matrix.
        sourceRotationMatrix = OpenMaya.MTransformationMatrix( sourceWorldMatrix ).asRotateMatrix()
        
        # Mirror the translation across the selected axis.
        if inMirrorAxis is 0:
            sourceWorldTranslation.x = sourceWorldTranslation.x * -1
        elif inMirrorAxis is 1:
            sourceWorldTranslation.y = sourceWorldTranslation.y * -1        
        elif inMirrorAxis is 2:
            sourceWorldTranslation.z = sourceWorldTranslation.z * -1    
    
        # Apply the mirrored position back to the target object.
        MFnTrans = OpenMaya.MFnTransform()
        targetDagPath = NodeUtility.getDagPath( inTargetObj )
        MFnTrans.setObject( targetDagPath )
        MFnTrans.setTranslation( sourceWorldTranslation, OpenMaya.MSpace.kWorld )
        
        # Mirror the rotation.
        baseVectors = {}
            
        for row in xrange( 3 ):
            # We only need the first three rows.
            rowPtr = sourceRotationMatrix[row]
            baseVectors[ row ] = []
            for col in xrange( 3 ):
                # We only need the first three columns.
                if col is not inMirrorAxis:
                    origValue = OpenMaya.MScriptUtil.getDoubleArrayItem( rowPtr, col ) * -1
                    OpenMaya.MScriptUtil.setDoubleArray( rowPtr, col, origValue )
    
        targetInverseMatrix = TransformUtility.getMatrix( inTargetObj, 'parentInverseMatrix' )
        mirroredTarget = sourceRotationMatrix * targetInverseMatrix
        toEuler = OpenMaya.MTransformationMatrix( mirroredTarget ).eulerRotation()
        #x,y,z = map(math.degrees,(toEuler.x,toEuler.y,toEuler.z))
        #print x,y,z 
        
        MFnTrans.setRotation( toEuler )
Esempio n. 4
0
def createSpacer(inBitName, inGroupName="newGroup", inTargetObject=None, inDoParent=False, inPrefix=None):
    """
    Creates an empty group. Optionally, the group's transforms can be matched to
    another object.
    
    @param inGroupName: String. Name to give the new group.
    @param inTargetObject: String. Name of object to match the group's transforms
    to.
    @return: The newly created group.
    """
    # Create empty group.
    if inPrefix is not None:
        groupName = inPrefix + "_" + inGroupName
    else:
        groupName = inGroupName

    newGroup = cmds.group(em=True, name=groupName)

    # Set its transforms.
    if inTargetObject is not None:
        # Get target objects matrix.
        targetMatrix = TransformUtility.getMatrix(inTargetObject, "worldMatrix")

        # Get groups transform.
        MFnTrans = OpenMaya.MFnTransform()
        groupDagPath = NodeUtility.getDagPath(newGroup)
        MFnTrans.setObject(groupDagPath)

        # Apply the targets translation to the group.
        targetTranslation = TransformUtility.getMatrixTranslation(targetMatrix, OpenMaya.MSpace.kWorld)
        MFnTrans.setTranslation(targetTranslation, OpenMaya.MSpace.kWorld)

        # Apply the targets rotation to the group.
        targetRotation = TransformUtility.getMatrixRotation(targetMatrix, "quat")
        MFnTrans.setRotation(targetRotation, OpenMaya.MSpace.kWorld)

        # Parent the spacer.
        if inDoParent:
            parent = cmds.listRelatives(inBitName, parent=True)
            if NodeUtility.attributeCheck(parent[0], "controlName"):
                parentControl = NodeUtility.getFrameBitSettings(parent[0])["controlName"]
                cmds.parent(newGroup, parentControl, absolute=True)

    return newGroup
Esempio n. 5
0
    def doIt( self, *args ):
        # ui settings.
        self.winWidth = 306
        self.winHeight = 400
        self.iconWidth = 32
        self.iconHeight = 32
        
        # clean up old uis before opening a new one.
        try:
            cmds.deleteUI( self.winName )
        except:
            pass
        
        self.mainWindow = cmds.window( self.winName, title=self.winTitle, sizeable=False, resizeToFitChildren=False )
        cmds.frameLayout( borderVisible=False, labelVisible=False )
        
        self.conTools = cmds.columnLayout( height=self.winHeight/3 )
        cmds.text( label='Controller Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.conGrid = cmds.gridLayout( numberOfColumns=4, numberOfRows=2, cellWidthHeight=(self.winWidth/4, 50) )
        cmds.button( label='Make Control', command='cmds.rigController()' )
        cmds.button( label='Make From XML', command='XMLUtility.createControlFromXML()' )
        cmds.button( label='Apply XML', command='XMLUtility.applyXMLtoControl()' )
        cmds.button( label='Save XML', command='XMLUtility.createControlXML()' )
        cmds.button( label='Make Deformer', command='makeDeformerMesh()')
        cmds.button( label='Apply Deformer', command='applyDeformerMesh()')
        cmds.setParent( '..' )#self.conGrid
        cmds.separator( style='none', height=20 )
        cmds.text( label='Position Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.transGrid = cmds.gridLayout( numberOfColumns=3, cellWidthHeight=(self.winWidth/3, 50) )
        cmds.button( label='Match Translation', command=lambda *args: TransformUtility.matchTransforms( 'tran' ) )
        cmds.button( label='Match Rotation', command=lambda *args: TransformUtility.matchTransforms( 'rot' )  )
        cmds.button( label='Match All', command=lambda *args: TransformUtility.matchTransforms( 'all' )  )
        cmds.setParent( '..' )#self.transGrid
        cmds.setParent( '..' )#self.conTools
        
        cmds.setParent( '..' )#framelayout

         # show the ui.
        cmds.showWindow( self.winName )
Esempio n. 6
0
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()
Esempio n. 7
0
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()
Esempio n. 8
0
    def doIt( self, *args ):
        # Window settings.
        self.winWidth = 206
        self.winHeight = 400
        self.iconWidth = 32
        self.iconHeight = 32
        
        # Window colors
        self.rowColors = [[0.4,0.4,0.4],[0.5,0.5,0.5]]
        
        # Clean up old uis before opening a new one.
        try:
            cmds.deleteUI( self.winName )
        except:
            pass
        
        # Setup the form layout.
        self.mainWindow = cmds.window( self.winName, title=self.winTitle, sizeable=False, resizeToFitChildren=False )
        self.form = cmds.formLayout()
        self.tabs = cmds.tabLayout( innerMarginWidth=5, innerMarginHeight=5 )
                
        # Attach the tabs layout to the form layout.
        cmds.formLayout( self.form, edit=True, attachForm=( (self.tabs, 'top', 0), (self.tabs, 'left', 0), (self.tabs, 'bottom', 0), (self.tabs, 'right', 0) ) )
        
        # Create each of the tabs.
        # TAB: META NODES: START
        self.tabMeta = cmds.rowColumnLayout( numberOfRows=2, width=self.winWidth )
        
        self.colMeta = cmds.rowColumnLayout( numberOfColumns=1, height=self.winHeight/2 )
        cmds.text( label='Meta Nodes', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.gridMeta = cmds.gridLayout( numberOfColumns=4, cellWidthHeight=( 50, 50 ) )        
        cmds.button( label='Basic', command=lambda b, a1='frameModule': metaNode.MetaNode( inNodeMetaType=a1 ) )
        cmds.button( label='Character', command=lambda b, a1=False: metaNode.MetaCharacter( doModel=a1 ) )
        cmds.setParent( '..' )#self.gridMeta
        cmds.setParent( '..' )#self.colMeta
        
        self.colMetaTools = cmds.rowColumnLayout( numberOfColumns=1 )
        cmds.text( label='Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.rowMetaTools = cmds.rowColumnLayout( numberOfRows=1 )
        cmds.button( label='Meta Node List', annotation='meta node list',
                     command=lambda b: SelectMetaUI.selectMetaUI() )                       
        cmds.setParent( '..' )#self.rowMetaTools
        cmds.setParent( '..' )#self.colMetaTools

        cmds.setParent( '..' )#self.tabMeta
        # TAB: META NODES: END
        
        # TAB: BITS, START
        self.tabBits = cmds.rowColumnLayout( numberOfRows=3, width=self.winWidth )
        
        self.bitsCol = cmds.rowColumnLayout( numberOfColumns=1, height=self.winHeight/3 )
        cmds.text( label='Bit Primitives', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.bitsGrid = cmds.gridLayout( numberOfColumns=4, cellWidthHeight=( 50, 50 ) )
        cmds.button( label='Sphere', command=lambda b, a1='glSphere': cmds.makeGLBit( objecttype=a1 ) )
        cmds.button( label='Box', command=lambda b, a1='glBox': cmds.makeGLBit( objecttype=a1 ) )
        cmds.button( label='Cylinder', command=lambda b, a1='glCylinder': cmds.makeGLBit( objecttype=a1 ) )
        cmds.button( label='Cone', command=lambda b, a1='glCone': cmds.makeGLBit( objecttype=a1 ) )
        cmds.button( label='Torus', command=lambda b, a1='glTorus': cmds.makeGLBit( objecttype=a1 ) )
        cmds.setParent( '..' )#self.bitsGrid
        cmds.setParent( '..' )#self.bitsCol
        
        self.toolsCol = cmds.rowColumnLayout( numberOfColumns=1 )
        cmds.text( label='Transform Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.toolRow = cmds.rowColumnLayout( numberOfRows=1 )
        cmds.iconTextButton( annotation='match translation', style='iconOnly',
                             width=self.winWidth/3, image1='icon_match_translation.png',
                             command=lambda a1='tran': TransformUtility.matchTransforms(a1) )
        cmds.iconTextButton( annotation='match rotation', style='iconOnly',
                             width=self.winWidth/3, image1='icon_match_rotation.png',
                             label='match rotation', command=lambda a1='rot': TransformUtility.matchTransforms(a1) )
        cmds.iconTextButton( annotation='match all', style='iconOnly',
                             width=self.winWidth/3, image1='icon_match_all.png',
                             label='match all', command=lambda a1='all': TransformUtility.matchTransforms(a1) )                             
        cmds.setParent( '..' )#self.toolRow
        cmds.setParent( '..' )#self.toolsCol

        self.childCol = cmds.rowColumnLayout( numberOfColumns=1 )
        cmds.text( label='General Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.childRow = cmds.rowColumnLayout( numberOfColumns=2 )
        cmds.button( label='Add Child', command=lambda b: NodeUtility.setBitChild() )
        cmds.button( label='Remove Child', command=lambda b: NodeUtility.deleteBitChild() )
        cmds.button( label='Copy Settings', command=lambda b: NodeUtility.copyBitSettings() )
        cmds.setParent( '..' )#self.childRow
        cmds.setParent( '..' )#self.childCol
        
        cmds.setParent( '..' )#self.tabBits
        # TAB: BITS, END
        
        # TAB: ATTRIBUTES, START
        self.tabAttrs = cmds.rowColumnLayout( numberOfRows=2 )
        
        # Top
        self.attrTop = cmds.rowColumnLayout( numberOfColumns=1 )
        cmds.text( label='Attribute List', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        
        # Top rows.
        self.attrList = cmds.scrollLayout( horizontalScrollBarThickness=16, verticalScrollBarThickness=16, height=150 )
        self.fillAttrList()
        cmds.setParent( '..' )#attrList
        # Bottom buttons
        cmds.rowColumnLayout( numberOfColumns=2 )
        #cmds.button( label='Add Custom Attribute' )
        cmds.button( label='Delete Attributes', command=lambda b: deleteAttrUI.createDeleteAttrUI() )
        cmds.button( label='Add Selected', command=lambda b: self.addAttrsFromList() )
        cmds.separator( style='none', height=10 )
        cmds.setParent( '..' )#button columns
        cmds.setParent( '..' )#self.attrTop
        
        self.attrPresets = cmds.rowColumnLayout( numberOfColumns=1 )
        cmds.text( label='Attribute Presets', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )
        self.presets = cmds.gridLayout( numberOfColumns=4, cellWidthHeight=( 50, 50 ) )
        self.fillAttrPresets()
        cmds.setParent( '..' )#self.presets
        cmds.setParent( '..' )#self.attrPresets
        
        cmds.setParent( '..' )#self.tabAttrs
        # TAB: ATTRIBUTES, END
        
        # TAB: XML: START
        self.tabXML = cmds.rowColumnLayout( numberOfRows=2, width=self.winWidth )
        
        self.colXML = cmds.rowColumnLayout( numberOfColumns=1, height=self.winHeight/2 )
        cmds.text( label='XML Tools', width=self.winWidth, wordWrap=True, align='center', font='boldLabelFont', backgroundColor=(0.15,0.15,0.15) )
        cmds.separator( style='none', height=4 )        
        cmds.button( label='Save Frame Module XML', command=lambda b: FrameUtility.createFrameModuleXML() )
        cmds.setParent( '..' )#self.colXML

        cmds.setParent( '..' )#self.tabXML
        # TAB: XML: END
        
        # Added the tabs to the tab layout.
        cmds.tabLayout( self.tabs, edit=True, tabLabel=( (self.tabMeta, 'Metas'),
                                                         (self.tabBits, 'Bits'),
                                                         (self.tabAttrs, 'Attributes'),
                                                         (self.tabXML, 'XML') ) )

        # Show the window.
        cmds.showWindow( self.winName )
Esempio n. 9
0
 def build_bits_gui( self ):
     '''
     Build the bits GUI sub-layout.
     '''
     # Build bits controls
     # Primitive buttons.        
     self.sphere_btn = QtGui.QToolButton( self )
     self.sphere_btn.setStyleSheet( 'border:0' )
     self.sphere_btn.setAutoRaise( True )
     self.sphere_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_sphere.png' ) )
     self.sphere_btn.setIconSize( QtCore.QSize(32,32) )
     self.sphere_btn.setText( 'Sphere' )
     self.sphere_btn.clicked.connect( self.primitive_buttons )
     
     self.box_btn = QtGui.QToolButton( self )
     self.box_btn.setStyleSheet( 'border:0' )
     self.box_btn.setAutoRaise( True )
     self.box_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_box.png' ) )
     self.box_btn.setIconSize( QtCore.QSize(32,32) )
     self.box_btn.setText( 'Box' )
     self.box_btn.clicked.connect( self.primitive_buttons )
     
     self.cylinder_btn = QtGui.QToolButton( self )
     self.cylinder_btn.setStyleSheet( 'border:0' )
     self.cylinder_btn.setAutoRaise( True )
     self.cylinder_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_cylinder.png' ) )
     self.cylinder_btn.setIconSize( QtCore.QSize(32,32) )
     self.cylinder_btn.setText( 'Cylinder' )
     self.cylinder_btn.clicked.connect( self.primitive_buttons )
     
     self.cone_btn = QtGui.QToolButton( self )
     self.cone_btn.setStyleSheet( 'border:0' )
     self.cone_btn.setAutoRaise( True )
     self.cone_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_cone.png' ) )
     self.cone_btn.setIconSize( QtCore.QSize(32,32) )
     self.cone_btn.setText( 'Cone' )
     self.cone_btn.clicked.connect( self.primitive_buttons )
     
     self.torus_btn = QtGui.QToolButton( self )
     self.torus_btn.setStyleSheet( 'border:0' )
     self.torus_btn.setAutoRaise( True )
     self.torus_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_torus.png' ) )
     self.torus_btn.setIconSize( QtCore.QSize(32,32) )
     self.torus_btn.setText( 'Torus' )
     self.torus_btn.clicked.connect( self.primitive_buttons )
     
     # Bit tools.
     self.match_translation_btn = QtGui.QPushButton( 'Match Translation' )
     self.match_translation_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/icon_match_translation.png' ) )
     self.match_translation_btn.setIconSize( QtCore.QSize(16,16) )
     self.match_translation_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.match_translation_btn.clicked.connect( lambda a='tran':TransformUtility.matchTransforms( a ) )
     
     self.match_rotation_btn = QtGui.QPushButton( 'Match Rotation' )
     self.match_rotation_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/icon_match_rotation.png' ) )
     self.match_rotation_btn.setIconSize( QtCore.QSize(16,16) )
     self.match_rotation_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.match_rotation_btn.clicked.connect( lambda a='rot':TransformUtility.matchTransforms( a ) )
     
     self.match_all_btn = QtGui.QPushButton( 'Match All' )
     self.match_all_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/icon_match_all.png' ) )
     self.match_all_btn.setIconSize( QtCore.QSize(16,16) )
     self.match_all_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.match_all_btn.clicked.connect( lambda a='all':TransformUtility.matchTransforms( a ) )
     
     self.copy_bit_settings_btn = QtGui.QPushButton( 'Copy Bit Settings' )
     self.copy_bit_settings_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_copy_settings.png' ) )
     self.copy_bit_settings_btn.setIconSize( QtCore.QSize(16,16) )
     self.copy_bit_settings_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.copy_bit_settings_btn.clicked.connect( lambda:FrameUtility.copyBitSettings() )
     
     self.add_child_btn = QtGui.QPushButton( 'Add Child' )
     self.add_child_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_add_child.png' ) )
     self.add_child_btn.setIconSize( QtCore.QSize(16,16) )
     self.add_child_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.add_child_btn.clicked.connect( lambda:FrameUtility.setBitChild() )
     
     self.delete_child_btn = QtGui.QPushButton( 'Delete Child' )
     self.delete_child_btn.setIcon( QtGui.QIcon( ':/riggingUI/icons/bit_delete_child.png' ) )
     self.delete_child_btn.setIconSize( QtCore.QSize(16,16) )
     self.delete_child_btn.setStyleSheet( 'text-align: left; padding: 4px' )
     self.delete_child_btn.clicked.connect( lambda:FrameUtility.deleteBitChild() )
     
     # Build bits layout.
     # Primitive buttons
     bit_primitives_header = QtGui.QLabel()
     bit_primitives_header.setText( 'Bit Primitives' )
     bit_primitives_header.setAlignment( QtCore.Qt.AlignCenter )
     bit_primitives_header.setStyleSheet( 'font:bold; font-size:14px; background-color:#2B2B30' )
     
     primitive_frame = QtGui.QFrame()
     primitive_frame.setFrameShadow( QtGui.QFrame.Sunken )
     primitive_frame.setFrameShape( QtGui.QFrame.Box )
     primitive_frame.setLineWidth( 1 )
     
     #self.primitive_groupbox.setStyleSheet( 'border:4px; border-style:outset' )
     primitive_layout = QtGui.QHBoxLayout()
     primitive_layout.addWidget( self.sphere_btn )
     primitive_layout.addWidget( self.box_btn )
     primitive_layout.addWidget( self.cylinder_btn )
     primitive_layout.addWidget( self.cone_btn )
     primitive_layout.addWidget( self.torus_btn )
     primitive_frame.setLayout( primitive_layout )
     
     # Bit tools.
     bit_tools_header = QtGui.QLabel()
     bit_tools_header.setText( 'Bit Tools' )
     bit_tools_header.setAlignment( QtCore.Qt.AlignCenter )
     bit_tools_header.setStyleSheet( 'font:bold; font-size:14px; background-color:#2B2B30' )
     
     bit_tools_grid = QtGui.QGridLayout()
     bit_tools_grid.setColumnMinimumWidth( 0, 100 )
     bit_tools_grid.setColumnMinimumWidth( 1, 100 )
     bit_tools_grid.setColumnMinimumWidth( 2, 100 )
     bit_tools_grid.setSpacing( 2 )
     bit_tools_grid.setContentsMargins( 0,0,0,0 )
     # widget, row, col
     bit_tools_grid.addWidget( self.match_translation_btn, 0, 0 )
     bit_tools_grid.addWidget( self.match_rotation_btn, 0, 1 )
     bit_tools_grid.addWidget( self.match_all_btn, 0, 2 )
     bit_tools_grid.addWidget( self.copy_bit_settings_btn, 1, 0 )
     bit_tools_grid.addWidget( self.add_child_btn, 1, 1 )
     bit_tools_grid.addWidget( self.delete_child_btn, 1, 2 )
     
     # Added the bits widgets to the sub-layout of the main window.
     self.sub_layout.addWidget( bit_primitives_header )
     self.sub_layout.addWidget( primitive_frame )
     self.sub_layout.addWidget( bit_tools_header )
     self.sub_layout.addLayout( bit_tools_grid )
Esempio n. 10
0
def createJoint( inJointName, inJointRef, inJointParent=None, inJointRadius=4.0, inPrefix=None ):
    '''
    Creates a single joint.
    
    @param inBit: String. Name of the frame bit.
    @param inParent: MObject. Parent MObject for the new joint.
    @return: The MObject of the joint created.
    '''
    # Create the joint.
    dagMod = OpenMaya.MDagModifier()
    if inJointParent:
        newJoint = dagMod.createNode( 'joint', inJointParent )
    else:
        newJoint = dagMod.createNode( 'joint' )
    dagMod.doIt()
        
    # Name the joint.
    if inPrefix is None:
        jointName = inJointName
    else:
        jointName = inPrefix+'_'+inJointName
    depFn = OpenMaya.MFnDependencyNode( newJoint )
    depFn.setName( jointName )
        
    # Modify the joint.
    jointFn = OpenMayaAnim.MFnIkJoint()
    jointFn.setObject( newJoint )
    
    parentDepNode = OpenMaya.MFnDependencyNode( jointFn.parent( 0 ) )
    bitLocalMatrix = TransformUtility.getMatrix( inJointRef, 'matrix' )
    bitWorldMatrix = TransformUtility.getMatrix( inJointRef, 'worldMatrix' )
    
    # Set orientation.
    if parentDepNode.name() == 'world':
        #print 'set world euler'
        bitEuler = TransformUtility.getMatrixRotation( bitWorldMatrix, 'euler' )
        jointFn.setOrientation( bitEuler )
    else:
        #print 'set local euler'
        bitEuler = TransformUtility.getMatrixRotation( bitLocalMatrix, 'euler' )                
        jointFn.setOrientation( bitEuler )
    
    # Set position.
    bitWorldTranslationVector = TransformUtility.getMatrixTranslation( bitWorldMatrix, OpenMaya.MSpace.kWorld )
    if parentDepNode.name() == 'world':
        # If the joint's parent is the world, then we take the translation vector straight
        # from the frame bit's world matrix.
        jointVector = bitWorldTranslationVector
        space = OpenMaya.MSpace.kTransform
    else:
        # If the joint's parent is another joint, then we need to get the parent's world
        # matrix and use it as a change of basis for the frame bit's world matrix.
        parentMatrix = TransformUtility.getMatrix( parentDepNode.name(), 'worldMatrix' )
        basisMatrix = bitWorldMatrix * parentMatrix.inverse()            
        jointVector = TransformUtility.getMatrixTranslation( basisMatrix, OpenMaya.MSpace.kWorld )
        space = OpenMaya.MSpace.kWorld
    jointFn.setTranslation( jointVector, space )
    
    # Set rotation order.
    # TODO
    
    # Set rotation.
    #if parentDepNode.name() == 'world':
        #print 'set world euler'
        #bitEuler = TransformUtility.getMatrixRotation( bitWorldMatrix, 'euler' )
        #jointFn.setRotation( bitEuler )
    #else:
        #print 'set local euler'
        #bitEuler = TransformUtility.getMatrixRotation( bitLocalMatrix, 'euler' )                
        #jointFn.setRotation( bitEuler )
    
    # Set preferred angle.
    # TODO
    
    # Set joint radius.
    cmds.setAttr( jointName+'.radius', inJointRadius )
    
    return newJoint
Esempio n. 11
0
    print 'Row 1: {0}'.format( row1 )
    print 'Row 2: {0}'.format( row2 )
    print 'Row 3: {0}'.format( row3 )
    print 'Row 4: {0}'.format( row4 )


## setup double[4][4]
fileTran = [-10.330358779423445, 3.5726726411932432, 7.329368248748317]
fileRotMatrix = [0.9035851814735454, -0.41914955150032557, -0.08858596558426181, 0.0]
fileRotMatrix.extend([0.4263705359882413, 0.8999962921054725, 0.09063575584448433, 0.0])
fileRotMatrix.extend([0.04173710414631, -0.11966757151992792, 0.991936331860066, 0.0])
fileRotMatrix.extend([0.0, 0.0, 0.0, 1.0])

util = OpenMaya.MScriptUtil()

mat = TransformUtility.getMatrix( 'pSphere1', 'worldMatrix' )
rotMat = OpenMaya.MTransformationMatrix( mat ).asRotateMatrix()

## create a zero matrix
matrixZero = OpenMaya.MMatrix()

## set the zero matrix to the file values
rotMatT = OpenMaya.MTransformationMatrix( rotMat )
x = util.asDoublePtr()
y = util.asDoublePtr()
z = util.asDoublePtr()
w = util.asDoublePtr()
rotMatT.getRotationQuaternion(x,y,z,w)
print y
print util.getDouble(y)
quat = OpenMaya.MQuaternion(util.getDouble(x),
Esempio n. 12
0
    def __init__( self ):
        super( UIBitsTools, self ).__init__()
        
        layout = QtGui.QVBoxLayout( self )

        # Build bits controls
        # Presets
        moduleRootBtn = QTWidgets.imageButton( 'Create Module', ':/riggingUI/icons/preset_module.png', [32,32] )
        moduleRootBtn.clicked.connect( lambda a=1:self.preset_buttons(a) )
        
        characterRootBtn = QTWidgets.imageButton( 'Create Character', ':/riggingUI/icons/preset_character.png', [32,32] )
        characterRootBtn.clicked.connect( lambda a=2:self.preset_buttons(a) )
        
        # Primitive buttons.        
        sphereBtn = QTWidgets.imageButton( 'Sphere', ':/riggingUI/icons/bit_sphere.png', [32,32] )
        sphereBtn.clicked.connect( self.primitive_buttons )
        
        boxBtn = QTWidgets.imageButton( 'Box', ':/riggingUI/icons/bit_box.png', [32,32] )
        boxBtn.clicked.connect( self.primitive_buttons )
        
        cylinderBtn = QTWidgets.imageButton( 'Cylinder', ':/riggingUI/icons/bit_cylinder.png', [32,32] )
        cylinderBtn.clicked.connect( self.primitive_buttons )
        
        coneBtn = QTWidgets.imageButton( 'Cone', ':/riggingUI/icons/bit_cone.png', [32,32] )
        coneBtn.clicked.connect( self.primitive_buttons )
        
        torusBtn = QTWidgets.imageButton( 'Torus', ':/riggingUI/icons/bit_torus.png', [32,32] )
        torusBtn.clicked.connect( self.primitive_buttons )
        
        # Bit tools.
        matchTranslationBtn = QTWidgets.imageTextButton( 'Match Translation', ':/riggingUI/icons/icon_match_translation.png', [16,16] )
        matchTranslationBtn.clicked.connect( lambda a='tran':TransformUtility.matchTransforms( a ) )
        
        matchRotationBtn = QTWidgets.imageTextButton( 'Match Rotation', ':/riggingUI/icons/icon_match_rotation.png', [16,16] )
        matchRotationBtn.clicked.connect( lambda a='rot':TransformUtility.matchTransforms( a ) )
        
        matchAllBtn = QTWidgets.imageTextButton( 'Match All', ':/riggingUI/icons/icon_match_all.png', [16,16] )
        matchAllBtn.clicked.connect( lambda a='all':TransformUtility.matchTransforms( a ) )
        
        copyBitSettingsBtn = QTWidgets.imageTextButton( 'Copy Bit Settings', ':/riggingUI/icons/bit_copy_settings.png', [16,16] )
        copyBitSettingsBtn.clicked.connect( lambda:NodeUtility.copyBitSettings() )
        
        addChildBtn = QTWidgets.imageTextButton( 'Add Child', ':/riggingUI/icons/bit_add_child.png', [16,16] ) 
        addChildBtn.clicked.connect( lambda:NodeUtility.setBitChild() )
        
        deleteChildBtn = QTWidgets.imageTextButton( 'Delete Child', ':/riggingUI/icons/bit_delete_child.png', [16,16] )
        deleteChildBtn.clicked.connect( lambda:NodeUtility.deleteBitChild() )
        
        # Build bits layout.
        # Presets.
        presetsHeader = QTWidgets.basicLabel( 'Bit Presets', 'bold', 14, 'white', '2B2B30' )
        presetsHeader.setMinimumHeight( 30 )
        presetsHeader.setAlignment( QtCore.Qt.AlignCenter )
        
        presetsFrame = QTWidgets.basicFrame()
        presetsLayout = QtGui.QHBoxLayout()
        presetsLayout.addWidget( moduleRootBtn )
        presetsLayout.addWidget( characterRootBtn )
        presetsFrame.setLayout( presetsLayout )
        
        # Primitive buttons
        bitPrimitivesHeader = QTWidgets.basicLabel( 'Bit Primitives', 'bold', 14, 'white', '2B2B30' )
        bitPrimitivesHeader.setMinimumHeight( 30 )
        bitPrimitivesHeader.setAlignment( QtCore.Qt.AlignCenter )
        
        primitiveFrame = QTWidgets.basicFrame()
        
        primitiveLayout = QtGui.QHBoxLayout()
        primitiveLayout.addWidget( sphereBtn )
        primitiveLayout.addWidget( boxBtn )
        primitiveLayout.addWidget( cylinderBtn )
        primitiveLayout.addWidget( coneBtn )
        primitiveLayout.addWidget( torusBtn )
        primitiveFrame.setLayout( primitiveLayout )
        
        # Bit tools.
        bitToolsHeader = QTWidgets.basicLabel( 'Bit Tools', 'bold', 14, 'white', '2B2B30' )
        bitToolsHeader.setMinimumHeight( 30 )
        bitToolsHeader.setAlignment( QtCore.Qt.AlignCenter )
        
        bitToolsGrid = QtGui.QGridLayout()
        bitToolsGrid.setColumnMinimumWidth( 0, 100 )
        bitToolsGrid.setColumnMinimumWidth( 1, 100 )
        bitToolsGrid.setColumnMinimumWidth( 2, 100 )
        bitToolsGrid.setSpacing( 2 )
        bitToolsGrid.setContentsMargins( 0,0,0,0 )
        # widget, row, col
        bitToolsGrid.addWidget( matchTranslationBtn, 0, 0 )
        bitToolsGrid.addWidget( matchRotationBtn, 0, 1 )
        bitToolsGrid.addWidget( matchAllBtn, 0, 2 )
        bitToolsGrid.addWidget( copyBitSettingsBtn, 1, 0 )
        bitToolsGrid.addWidget( addChildBtn, 1, 1 )
        bitToolsGrid.addWidget( deleteChildBtn, 1, 2 )
        
        # Added the bits widgets to the sub-layout of the main window.
        layout.addWidget( presetsHeader )
        layout.addWidget( presetsFrame )
        layout.addWidget( bitPrimitivesHeader )
        layout.addWidget( primitiveFrame )
        layout.addWidget( bitToolsHeader )
        layout.addLayout( bitToolsGrid )