def applyStoredTransforms( sourceObj, targetObj ): ''' Applies stored transform data for a control object. @param sourceObj: String. Name of object to pull data from. @param targetObj: String. Name of object to apply data to. ''' #print 'applyStoredTransforms @@@@@@' #print 'sourceObj: {0}'.format( sourceObj ) #print 'targetObj: {0}'.format( targetObj ) MFnTrans = OpenMaya.MFnTransform() targetDagPath = NodeUtility.getDagPath( targetObj ) MFnTrans.setObject( targetDagPath ) sourcePosPlug = NodeUtility.getPlug( sourceObj, 'controlPosition' ) sourcePosValue = NodeUtility.getPlugValue( sourcePosPlug ) sourcePos = OpenMaya.MVector( sourcePosValue[0], sourcePosValue[1], sourcePosValue[2] ) MFnTrans.setTranslation( sourcePos, OpenMaya.MSpace.kTransform ) sourceRotPlug = NodeUtility.getPlug( sourceObj, 'controlRotation' ) sourceRotValue = NodeUtility.getPlugValue( sourceRotPlug ) sourceRot = OpenMaya.MEulerRotation( sourceRotValue[0], sourceRotValue[1], sourceRotValue[2] ) MFnTrans.setRotation( sourceRot ) sourceSclPlug = NodeUtility.getPlug( sourceObj, 'controlScale' ) sourceSclValue = NodeUtility.getPlugValue( sourceSclPlug ) scaleDoubleArray = OpenMaya.MScriptUtil() scaleDoubleArray.createFromList( [sourceSclValue[0], sourceSclValue[1], sourceSclValue[2]], 3 ) scaleDoubleArrayPtr = scaleDoubleArray.asDoublePtr() MFnTrans.setScale( scaleDoubleArrayPtr )
def applyDeformerMesh(): ''' Applies the deformer mesh to the OpenGL values of the active controller. ''' selList = OpenMaya.MSelectionList() OpenMaya.MGlobal.getActiveSelectionList( selList ) if selList.length() is 1: control = OpenMaya.MObject() selList.getDependNode( 0, control ) controlDagNode = OpenMaya.MFnDagNode( control ) controlShape = controlDagNode.child( 0 ) controlShapeDep = OpenMaya.MFnDependencyNode( controlShape ) locCheck = False meshCheck = False for c in xrange( controlDagNode.childCount() ): child = controlDagNode.child( c ) if child.apiType() == OpenMaya.MFn.kPluginLocatorNode: locCheck = True elif child.apiType() == OpenMaya.MFn.kMesh: # Set the check to True. meshCheck = True # Grab the mesh. deformMesh = OpenMaya.MFnMesh( child ) # Grab the vertices of the mesh. vertexCount = OpenMaya.MIntArray() vertexList = OpenMaya.MIntArray() vertexArray = OpenMaya.MFloatPointArray() deformMesh.getVertices( vertexCount, vertexList ) deformMesh.getPoints( vertexArray, OpenMaya.MSpace.kObject ) # Set the OpenGL points. glPosition = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'localPosition' ) ) glWidth = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'width' ) ) glHeight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'height' ) ) glDepth = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'depth' ) ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botBackRight' ), [ (vertexArray[0].x-(-glWidth/2))-glPosition[0],(vertexArray[0].y-(-glHeight/2))-glPosition[1],(vertexArray[0].z-(-glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botBackLeft' ), [ (vertexArray[1].x-(glWidth/2))-glPosition[0],(vertexArray[1].y-(-glHeight/2))-glPosition[1],(vertexArray[1].z-(-glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botFrontLeft' ), [ (vertexArray[2].x-(glWidth/2))-glPosition[0],(vertexArray[2].y-(-glHeight/2))-glPosition[1],(vertexArray[2].z-(glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botFrontRight' ), [ (vertexArray[3].x-(-glWidth/2))-glPosition[0],(vertexArray[3].y-(-glHeight/2))-glPosition[1],(vertexArray[3].z-(glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topBackRight' ), [ (vertexArray[4].x-(-glWidth/2))-glPosition[0],(vertexArray[4].y-(glHeight/2))-glPosition[1],(vertexArray[4].z-(-glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topFrontRight' ), [ (vertexArray[5].x-(-glWidth/2))-glPosition[0],(vertexArray[5].y-(glHeight/2))-glPosition[1],(vertexArray[5].z-(glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topFrontLeft' ), [ (vertexArray[6].x-(glWidth/2))-glPosition[0],(vertexArray[6].y-(glHeight/2))-glPosition[1],(vertexArray[6].z-(glDepth/2))-glPosition[2] ] ) NodeUtility.setPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topBackLeft' ), [ (vertexArray[7].x-(glWidth/2))-glPosition[0],(vertexArray[7].y-(glHeight/2))-glPosition[1],(vertexArray[7].z-(-glDepth/2))-glPosition[2] ] ) # Clean up by deleting the mesh. MDGMod = OpenMaya.MDGModifier() MDGMod.deleteNode( child ) MDGMod.doIt() if locCheck is False: sys.stderr.write( 'applyDeformerMesh: This is the wrong type of object. Needs to be an OpenGl Controller.' ) if meshCheck is False: sys.stderr.write( 'applyDeformerMesh: This control object doesn\'t have a deformer mesh.' ) elif selList.length() > 1: sys.stderr.write( 'applyDeformerMesh: To many things selected. Only select one controller.' ) else: sys.stderr.write( 'applyDeformerMesh: Nothing selected.' )
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 copyBitSettings(): ''' Copies the bit shape settings (OpenGL stuff) from the second object to the first (in selection order). ''' selList = cmds.ls( selection=True, long=True ) depFn = OpenMaya.MFnDependencyNode() if len(selList) == 2: # First object is target. targetShape = cmds.listRelatives( selList[0], shapes=True, fullPath=True )[0] targetShapeMObj = NodeUtility.getDependNode( targetShape ) depFn.setObject( targetShapeMObj ) targetShapeType = depFn.typeName() # Second object is source. sourceShape = cmds.listRelatives( selList[1], shapes=True, fullPath=True )[0] sourceShapeMObj = NodeUtility.getDependNode( sourceShape ) depFn.setObject( sourceShapeMObj ) sourceShapeType = depFn.typeName() if targetShapeType == sourceShapeType: # The types match. Do the copy of attribute settings. for attr in cmds.listAttr( sourceShape, multi=True, keyable=True ): # Get the plugs. sourcePlug = NodeUtility.getPlug( sourceShape, attr ) targetPlug = NodeUtility.getPlug( targetShape, attr ) # Get the source plug value. sourcePlugValue = NodeUtility.getPlugValue( sourcePlug ) # Set the target's plug value. NodeUtility.setPlugValue( targetPlug, sourcePlugValue ) else: raise ValueError( '{0} and {1} do not match.'.format( selList[0], selList[1] ) )
def __init__( self, nodeName, parent=None ): super( componentWidget, self ).__init__( parent ) self.parent = parent def on_context_menu( point, inNodeName ): popMenu = QtGui.QMenu() deleteAction = QtGui.QAction( 'Delete Component', popMenu, triggered=lambda a=inNodeName:self.deleteComponentFromObject( a ) ) popMenu.addAction( deleteAction ) popMenu.exec_( self.componentLabel.mapToGlobal( point ) ) # Setup layout. verticalLayout = QtGui.QVBoxLayout() verticalLayout.setContentsMargins( 0,0,0,0 ) verticalLayout.setSpacing( 0 ) verticalLayout.setAlignment( QtCore.Qt.AlignTop ) # Label for component componentLabel = QTWidgets.basicLabel( nodeName, 'bold', 10, 'black', '6E9094', inIndent=20 ) componentLabel.setMinimumHeight( 18 ) componentLabel.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) componentLabel.customContextMenuRequested.connect( lambda point, nodeName=nodeName:on_context_menu( point, nodeName ) ) # Properties propertyStack = QtGui.QVBoxLayout() propertyFrame = QTWidgets.basicFrame() propertyFrame.setMinimumHeight( 40 ) propertyFrame.setMaximumHeight( 40 ) # Add string edit property modulePlug = NodeUtility.getPlug( nodeName, 'moduleName' ) moduleValue = NodeUtility.getPlugValue( modulePlug ) moduleTextLayout = QTWidgets.stringProperty( 'Module Name', moduleValue ) ''' ADD EDIT FIELDS FOR PRIORITY AND CHARACTER ROOT!!!!!!!!! ''' # Add everything to the vertical layout. propertyStack.addLayout( moduleTextLayout ) propertyFrame.setLayout( propertyStack ) verticalLayout.addWidget( componentLabel ) verticalLayout.addWidget( propertyFrame ) # Connections moduleTextBox = propertyFrame.findChild( QtGui.QLineEdit, 'Module Name' ) moduleTextBox.editingFinished.connect( lambda inPlugName='moduleName', inQTType='QLineEdit', inPlugValue=moduleTextBox, inNodeName=nodeName :ModuleRootComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) #return mainWidget self.setLayout( verticalLayout )
def __init__( self, nodeName, parent=None ): super( componentWidget, self ).__init__( parent ) self.parent = parent def on_context_menu( point, inNodeName ): popMenu = QtGui.QMenu() buildAction = QtGui.QAction( 'Build Joint', popMenu, triggered=lambda a=inNodeName:self.buildNode( a ) ) popMenu.addAction( buildAction ) deleteAction = QtGui.QAction( 'Delete Component', popMenu, triggered=lambda a=inNodeName:self.deleteComponentFromObject( a ) ) popMenu.addAction( deleteAction ) popMenu.exec_( componentLabel.mapToGlobal( point ) ) # Setup layout. verticalLayout = QtGui.QVBoxLayout() verticalLayout.setContentsMargins( 0,0,0,0 ) verticalLayout.setSpacing( 0 ) verticalLayout.setAlignment( QtCore.Qt.AlignTop ) # Label for component componentLabel = QTWidgets.basicLabel( nodeName, 'bold', 10, 'black', '6E9094', inIndent=20 ) componentLabel.setMinimumHeight( 18 ) componentLabel.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) componentLabel.customContextMenuRequested.connect( lambda point, node=nodeName:on_context_menu( point, node ) ) # Properties propertyStack = QtGui.QVBoxLayout() propertyFrame = QTWidgets.basicFrame() propertyFrame.setMinimumHeight( 40 ) propertyFrame.setMaximumHeight( 40 ) # Add string edit property propertyPlug = NodeUtility.getPlug( nodeName, 'jointName' ) propertyValue = NodeUtility.getPlugValue( propertyPlug ) jointTextLayout = QTWidgets.stringProperty( 'Joint Name', propertyValue ) propertyStack.addLayout( jointTextLayout ) propertyFrame.setLayout( propertyStack ) verticalLayout.addWidget( componentLabel ) verticalLayout.addWidget( propertyFrame ) # Connections textBox = propertyFrame.findChild( QtGui.QLineEdit ) textBox.editingFinished.connect( lambda inPlugName='jointName', inQTType='QLineEdit', inPlugValue=textBox, inNodeName=nodeName :BasicJointComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) self.setLayout( verticalLayout )
def nodeRotation( self ): ''' dagFn= OpenMaya.MFnDagNode( self.fNodePath ) path = OpenMaya.MDagPath() dagFn.getPath( path ) path.pop() transformFn = OpenMaya.MFnTransform( path ) q = OpenMaya.MQuaternion() transformFn.getRotation( q, OpenMaya.MSpace.kWorld ) return q ''' plug = NodeUtility.getPlug( 'ControlBox1', 'rotate' ) rot = NodeUtility.getPlugValue( plug ) e = OpenMaya.MEulerRotation( rot[0], rot[1], rot[2] ) return e
def getFrameBitSettings( inFrameBit ): ''' Retrieves the settings for the frame bit. @param inFrameBit: String. Name of frame bit. @return: Dictionary. All the custom attributes on the frame bit. ''' attrList = cmds.listAttr( inFrameBit, userDefined=True ) if attrList is not None: tempDict = {} for attr in attrList: plug = NodeUtility.getPlug( inFrameBit, attr ) plugValue = NodeUtility.getPlugValue( plug ) tempDict[ attr ] = plugValue else: tempDict = None return tempDict
def saveModule( self ): ''' Save the module into an XML file for re-use. We assume that the root node of the module is the one with the module root meta node. This means it and all of it's children will be saved in the XML. ''' # Get the selected module item = cmds.ls( long=True, selection=True )[0] # Try to get the module meta component. moduleComp = Components.searchModule( item, 'ModuleRootComponent' ) if moduleComp: # Get the module info and save it as an XML. modulePlug = NodeUtility.getPlug( moduleComp[1], 'moduleName' ) moduleName = NodeUtility.getPlugValue( modulePlug ) XMLUtility.writeModuleXML( moduleComp[0], self.SELECTED_ITEM, moduleName )
def componentGui( inNodeName ): def on_context_menu( point ): popMenu = QtGui.QMenu() popMenu.addAction( 'actionEdit' ) popMenu.addAction( 'actionDelete' ) popMenu.addSeparator() popMenu.addAction( 'actionAdd' ) popMenu.exec_( componentLabel.mapToGlobal( point ) ) mainWidget = QtGui.QWidget() verticalLayout = QtGui.QVBoxLayout( mainWidget ) verticalLayout.setContentsMargins( 0,0,0,0 ) verticalLayout.setSpacing( 0 ) verticalLayout.setAlignment( QtCore.Qt.AlignTop ) # Label for component componentLabel = QTWidgets.basicLabel( inNodeName, 'bold', 10, 'black', 448094 ) componentLabel.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) componentLabel.customContextMenuRequested.connect( on_context_menu ) propertyFrame = QTWidgets.basicFrame() propertyFrame.setMinimumHeight( 40 ) propertyFrame.setMaximumHeight( 40 ) # Add string edit property plug = NodeUtility.getPlug( inNodeName, 'jointName' ) plugValue = NodeUtility.getPlugValue( plug ) QTWidgets.stringProperty( propertyFrame, 'Joint Name', plugValue ) # Add everything to the vertical layout. verticalLayout.addWidget( componentLabel ) verticalLayout.addWidget( propertyFrame ) #print 'test2: {0}'.format( prop.takeAt(0).widget() ) #print propertyFrame.count() #print propertyFrame.findChild( QtGui.QLineEdit ) #for item in xrange( propertyFrame.count() ): # print propertyFrame.itemAt( item ).widget() return mainWidget
def readCurveValues(inObj): """ Read stored curve CV values on an object. Object must have curve CV attributes created with addCurveValues(). @param inObj: String. Name of object to add curve cv values too. @return: List of dicts. """ curveAttrs = cmds.listAttr(inObj, string="curve*", category="nurbCurve") # [cur, cur, ...] # cur[i] = { #:[x,y,z] } curList = [] for attr in curveAttrs: plug = NodeUtility.getPlug(inObj, attr) plugValue = NodeUtility.getPlugValue(plug) cvDict = {} for index, point in enumerate(plugValue): cvDict[index] = point curList.append(cvDict) curList return curList
def __init__( self, nodeName, parent=None ): super( componentWidget, self ).__init__( parent ) self.parent = parent def on_context_menu( point, inNodeName ): popMenu = QtGui.QMenu() deleteAction = QtGui.QAction( 'Delete Component', popMenu, triggered=lambda a=inNodeName:self.deleteComponentFromObject( a ) ) popMenu.addAction( deleteAction ) popMenu.exec_( self.componentLabel.mapToGlobal( point ) ) # Colors. userColors = GeneralUtility.getUserDefinedColors( inType=1 ) self.colorList = [] for color in userColors: self.colorList.append( GeneralUtility.convertRGB( color, inType=1 ) ) # Setup layout. verticalLayout = QtGui.QVBoxLayout() verticalLayout.setContentsMargins( 0,0,0,0 ) verticalLayout.setSpacing( 0 ) verticalLayout.setAlignment( QtCore.Qt.AlignTop ) # Label for component #self.componentLabel = QTWidgets.basicLabel( nodeName, 'bold', 10, 'black', '6E9094', inIndent=20 ) self.componentLabel = QtGui.QLabel() self.componentLabel.setText( nodeName ) self.componentLabel.setIndent( 20 ) controlColorPlug = NodeUtility.getPlug( nodeName, 'controlColor' ) self.COLOR = NodeUtility.getPlugValue( controlColorPlug ) self.componentLabel.setStyleSheet( 'font:bold; font-size:10px; color:black; background-color:rgb({0},{1},{2})'.format(self.colorList[self.COLOR-1][0], self.colorList[self.COLOR-1][1], self.colorList[self.COLOR-1][2] ) ) self.componentLabel.setMinimumHeight( 18 ) self.componentLabel.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) self.componentLabel.customContextMenuRequested.connect( lambda point, nodeName=nodeName:on_context_menu( point, nodeName ) ) propertyFrame = QTWidgets.basicFrame() propertyFrame.setMinimumHeight( 100 ) propertyFrame.setMaximumHeight( 100 ) propertyStack = QtGui.QVBoxLayout() # Add string edit property propertyRow = QtGui.QHBoxLayout() propertyPlug = NodeUtility.getPlug( nodeName, 'controlName' ) propertyValue = NodeUtility.getPlugValue( propertyPlug ) self.textBox = QtGui.QLineEdit() self.textBox.setAlignment( QtCore.Qt.AlignLeft ) self.textBox.setMinimumHeight( 20 ) if propertyValue: self.textBox.setText( propertyValue ) textBoxLabel = QtGui.QLabel() textBoxLabel.setText( 'Control Name' ) textBoxLabel.setAlignment( QtCore.Qt.AlignCenter ) textBoxLabel.setMinimumHeight( 12 ) propertyRow.addWidget( self.textBox ) propertyRow.addWidget( textBoxLabel ) # Colors. colorRow = QtGui.QHBoxLayout() color1Btn = QtGui.QPushButton() color1Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[0][0], self.colorList[0][1], self.colorList[0][2] ) ) color1Btn.clicked.connect( lambda a=nodeName, b=1:self.colorChange( a, b ) ) color2Btn = QtGui.QPushButton() color2Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[1][0], self.colorList[1][1], self.colorList[1][2] ) ) color2Btn.clicked.connect( lambda a=nodeName, b=2:self.colorChange( a, b ) ) color3Btn = QtGui.QPushButton() color3Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[2][0], self.colorList[2][1], self.colorList[2][2] ) ) color3Btn.clicked.connect( lambda a=nodeName, b=3:self.colorChange( a, b ) ) color4Btn = QtGui.QPushButton() color4Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[3][0], self.colorList[3][1], self.colorList[3][2] ) ) color4Btn.clicked.connect( lambda a=nodeName, b=4:self.colorChange( a, b ) ) color5Btn = QtGui.QPushButton() color5Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[4][0], self.colorList[4][1], self.colorList[4][2] ) ) color5Btn.clicked.connect( lambda a=nodeName, b=5:self.colorChange( a, b ) ) color6Btn = QtGui.QPushButton() color6Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[5][0], self.colorList[5][1], self.colorList[5][2] ) ) color6Btn.clicked.connect( lambda a=nodeName, b=6:self.colorChange( a, b ) ) color7Btn = QtGui.QPushButton() color7Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[6][0], self.colorList[6][1], self.colorList[6][2] ) ) color7Btn.clicked.connect( lambda a=nodeName, b=7:self.colorChange( a, b ) ) color8Btn = QtGui.QPushButton() color8Btn.setStyleSheet( 'background-color:rgb({0},{1},{2}); width:20'.format( self.colorList[7][0], self.colorList[7][1], self.colorList[7][2] ) ) color8Btn.clicked.connect( lambda a=nodeName, b=8:self.colorChange( a, b ) ) colorRow.addWidget( color1Btn ) colorRow.addWidget( color2Btn ) colorRow.addWidget( color3Btn ) colorRow.addWidget( color4Btn ) colorRow.addWidget( color5Btn ) colorRow.addWidget( color6Btn ) colorRow.addWidget( color7Btn ) colorRow.addWidget( color8Btn ) # Edit buttons. self.editButton = QtGui.QToolButton() self.editButton.setCheckable( True ) self.editButton.setText( 'Edit Control' ) self.editButton.toggled.connect( lambda:self.editCurveProperties() ) propertyStack.addLayout( propertyRow ) propertyStack.addLayout( colorRow ) propertyStack.addWidget( self.editButton ) propertyFrame.setLayout( propertyStack ) # Add everything to the vertical layout. verticalLayout.addWidget( self.componentLabel ) verticalLayout.addWidget( propertyFrame ) # Connections self.textBox.editingFinished.connect( lambda inPlugName='controlName', inQTType='QLineEdit', inPlugValue=self.textBox, inNodeName=nodeName :CurveControlComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) #return mainWidget self.setLayout( verticalLayout )
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 draw( self, view, path, style, status ): socketNode = OpenMaya.MFnDependencyNode( self.thisMObject() ) trX= OpenMaya.MPlug( self.thisMObject(), self.localPositionX ).asFloat() trY= OpenMaya.MPlug( self.thisMObject(), self.localPositionY ).asFloat() trZ= OpenMaya.MPlug( self.thisMObject(), self.localPositionZ ).asFloat() lw = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'lineWidth' ) ).asInt() rt = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'rotate' ) ) a = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'transparency' ) ).asFloat() ba = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'backAlpha' ) ).asFloat() cl = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'color' )) dt = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'drawType' ) ).asInt() width = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'width' ) ).asFloat()#X height = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'height' ) ).asFloat()#Y depth = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute( 'depth' ) ).asFloat()#Z rotation = NodeUtility.getPlugValue( rt ) color = NodeUtility.getPlugValue( cl ) ( r, g, b ) = tuple( color )[:3] # Get the point attributes used to offset each corner of the cube. tfr = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'topFrontRight' ) ) tfl = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'topFrontLeft' ) ) tbr = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'topBackRight' ) ) tbl = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'topBackLeft' ) ) bfr = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'botFrontRight' ) ) bfl = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'botFrontLeft' ) ) bbr = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'botBackRight' ) ) bbl = OpenMaya.MPlug( self.thisMObject(), socketNode.attribute ( 'botBackLeft' ) ) # Get the values of each point plug. vTFR = NodeUtility.getPlugValue( tfr ) vTFL = NodeUtility.getPlugValue( tfl ) vTBR = NodeUtility.getPlugValue( tbr ) vTBL = NodeUtility.getPlugValue( tbl ) vBFR = NodeUtility.getPlugValue( bfr ) vBFL = NodeUtility.getPlugValue( bfl ) vBBR = NodeUtility.getPlugValue( bbr ) vBBL = NodeUtility.getPlugValue( bbl ) # Do the maths! For each point we factor in the width/height/depth, the point tweak value and the offset object offset position. drawPoints = [] drawPoints.append( [ ( width/2 + vBFL[0] ) + trX, ( -height/2+vBFL[1] ) + trY, ( depth/2+vBFL[2] ) + trZ ] ) #bottomFrontLeft drawPoints.append( [ ( -width/2 + vBFR[0] ) + trX, ( -height/2+vBFR[1] ) + trY, ( depth/2+vBFR[2] ) + trZ ] ) #bottomFrontRight drawPoints.append( [ ( width/2+vBBL[0] ) + trX, ( -height/2+vBBL[1] ) + trY, ( -depth/2+vBBL[2] ) + trZ ] ) #bottomBackLeft drawPoints.append( [ ( -width/2+vBBR[0] ) + trX, ( -height/2+vBBR[1] ) + trY, ( -depth/2+vBBR[2] ) + trZ ] ) #bottomBackRight drawPoints.append( [ ( width/2 + vTFL[0] ) + trX, ( height/2+vTFL[1] ) + trY, ( depth/2+vTFL[2] ) + trZ ] ) #topFrontLeft drawPoints.append( [ ( -width/2 + vTFR[0] ) + trX, ( height/2+vTFR[1] ) + trY, ( depth/2+vTFR[2] ) + trZ ] ) #topFrontRight drawPoints.append( [ ( width/2+vTBL[0] ) + trX, ( height/2+vTBL[1] ) + trY, ( -depth/2+vTBL[2] ) + trZ ] ) #topBackLeft drawPoints.append( [ ( -width/2+vTBR[0] ) + trX, ( height/2+vTBR[1] ) + trY, ( -depth/2+vTBR[2] ) + trZ ] ) #topBackRight # Calculate bounding box min and max points. Basically bbp1 is the bottom or negative point # while bbp2 is the top or positive point. X, Y, Z = ( [] for i in range( 3 ) ) for point in drawPoints: X.append( point[0] ) Y.append( point[1] ) Z.append( point[2] ) self.bbp1 = OpenMaya.MPoint( min( X ), min( Y ), min( Z ) ) self.bbp2 = OpenMaya.MPoint( max( X ), max( Y ), max( Z ) ) def drawObject( self ): # Draw the box glFT.glBegin( OpenMayaRender.MGL_QUADS ) # Front. Normal faces +Z. glFT.glVertex3f( drawPoints[1][0], drawPoints[1][1], drawPoints[1][2] )#bottom right glFT.glVertex3f( drawPoints[0][0], drawPoints[0][1], drawPoints[0][2] )#bottom left glFT.glVertex3f( drawPoints[4][0], drawPoints[4][1], drawPoints[4][2] )#top left glFT.glVertex3f( drawPoints[5][0], drawPoints[5][1], drawPoints[5][2] )#top right # Back. Normal faces -Z. glFT.glVertex3f( drawPoints[3][0], drawPoints[3][1], drawPoints[3][2] )#bottom right glFT.glVertex3f( drawPoints[7][0], drawPoints[7][1], drawPoints[7][2] )#top right glFT.glVertex3f( drawPoints[6][0], drawPoints[6][1], drawPoints[6][2] )#top left glFT.glVertex3f( drawPoints[2][0], drawPoints[2][1], drawPoints[2][2] )#bottom left # Right. Normal faces -X. glFT.glVertex3f( drawPoints[3][0], drawPoints[3][1], drawPoints[3][2] )#bottom back glFT.glVertex3f( drawPoints[1][0], drawPoints[1][1], drawPoints[1][2] )#bottom front glFT.glVertex3f( drawPoints[5][0], drawPoints[5][1], drawPoints[5][2] )#top front glFT.glVertex3f( drawPoints[7][0], drawPoints[7][1], drawPoints[7][2] )#top back # Left. Normal faces +X. glFT.glVertex3f( drawPoints[0][0], drawPoints[0][1], drawPoints[0][2] )#bottom front glFT.glVertex3f( drawPoints[2][0], drawPoints[2][1], drawPoints[2][2] )#bottom back glFT.glVertex3f( drawPoints[6][0], drawPoints[6][1], drawPoints[6][2] )#top back glFT.glVertex3f( drawPoints[4][0], drawPoints[4][1], drawPoints[4][2] )#top front # Top. Normal faces +Y. glFT.glVertex3f( drawPoints[5][0], drawPoints[5][1], drawPoints[5][2] )#front right glFT.glVertex3f( drawPoints[4][0], drawPoints[4][1], drawPoints[4][2] )#front left glFT.glVertex3f( drawPoints[6][0], drawPoints[6][1], drawPoints[6][2] )#back left glFT.glVertex3f( drawPoints[7][0], drawPoints[7][1], drawPoints[7][2] )#back right # Bottom. Normal faces -Y. glFT.glVertex3f( drawPoints[3][0], drawPoints[3][1], drawPoints[3][2] )#back right glFT.glVertex3f( drawPoints[2][0], drawPoints[2][1], drawPoints[2][2] )#back left glFT.glVertex3f( drawPoints[0][0], drawPoints[0][1], drawPoints[0][2] )#front left glFT.glVertex3f( drawPoints[1][0], drawPoints[1][1], drawPoints[1][2] )#front right glFT.glEnd() def drawShaded(self): glFT.glEnable( OpenMayaRender.MGL_CULL_FACE ) glFT.glFrontFace( OpenMayaRender.MGL_CCW ) drawObject( self ) glFT.glDisable( OpenMayaRender.MGL_CULL_FACE ) glFT.glPolygonMode(OpenMayaRender.MGL_FRONT_AND_BACK, OpenMayaRender.MGL_LINE) drawObject( self ) glFT.glCullFace( OpenMayaRender.MGL_BACK ) def drawWireframe(self): glFT.glPolygonMode( OpenMayaRender.MGL_FRONT_AND_BACK, OpenMayaRender.MGL_LINE ) drawObject( self ) def drawText( self, string, vec ): halfV = vec * 0.5 # Draw the text string. glFT.glColor4f( 1.0, 0.2, 0.0, 1.0 ) textPoint = OpenMaya.MPoint( halfV.x, halfV.y, halfV.z) view.drawText( string, textPoint ) view.beginGL() glFT.glPushMatrix() # Change the rotation of the controller. glFT.glRotatef( rotation[ 0 ], 1.0,0.0,0.0 ) glFT.glRotatef( rotation[ 1 ], 0.0,1.0,0.0 ) glFT.glRotatef( rotation[ 2 ], 0.0,0.0,1.0 ) glFT.glPushAttrib( OpenMayaRender.MGL_ALL_ATTRIB_BITS ) # Handle switching between wireframe and shaded. f = drawShaded if style not in [ OpenMayaUI.M3dView.kFlatShaded, OpenMayaUI.M3dView.kGouraudShaded ]: f = drawWireframe if dt == 1: f = drawShaded elif dt == 0: f = drawWireframe glFT.glClearDepth( 1.0 ) glFT.glEnable( OpenMayaRender.MGL_BLEND ) glFT.glEnable( OpenMayaRender.MGL_DEPTH_TEST ) glFT.glDepthFunc( OpenMayaRender.MGL_LEQUAL ) glFT.glShadeModel( OpenMayaRender.MGL_SMOOTH ) glFT.glBlendFunc( OpenMayaRender.MGL_SRC_ALPHA, OpenMayaRender.MGL_ONE_MINUS_SRC_ALPHA ) glFT.glDepthMask( OpenMayaRender.MGL_FALSE ) # Sets the color of the polygons. statusColor( r, g, b, a, status ) glFT.glLineWidth( lw ) f( self ) # Sets the color of the wireframes. statusColor( r, g, b, ba, status ) f( self ) glFT.glPopAttrib() glFT.glPopMatrix() view.endGL()
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 createControlXML(): ''' Creates/updates module XML file. ''' # Controller attributes. cAttr = [ 'color', 'localPosition', 'rotate', 'transparency', 'backAlpha', 'lineWidth', 'width', 'height', 'depth', 'drawType', 'topFrontRight', 'topFrontLeft', 'topBackRight', 'topBackLeft', 'botFrontRight', 'botFrontLeft', 'botBackRight', 'botBackLeft' ] # Browse for file to replace or new file to make. moduleFilter = "*.xml" dialogResults = cmds.fileDialog2( fileFilter=moduleFilter, dialogStyle=2, startingDirectory=getPresetPath( CONTROLLER_PRESETS_PATH ) ) tempPath = dialogResults[0].split( '/' ) fileName = tempPath[ len( tempPath )-1 ] filePath = dialogResults[0].rstrip( fileName ) objName = fileName.split( '.' )[0] # Get the selected object. Only takes one object. sel = cmds.ls( selection=True, dagObjects=True, allPaths=True, transforms=True ) # Build a list for each line in an XML file. xmlList = [] xmlList.append( '<data>' ) # Grab the shape node. transNode = NodeUtility.getDagPath( sel[0] ) shapeNode = transNode.child( 0 ) MFnDagNode = OpenMaya.MFnDagNode() MFnDagNode.setObject( shapeNode ) # Get the attributes and format them for the XML file. if MFnDagNode.typeName() == 'ControlBox': # Create a <control>. xmlList.append( '\t<control name=\"{0}\" type=\"{1}\">'.format( sel[0], MFnDagNode.typeName() ) ) xmlList.append( '\t</control>' ) for a in cAttr: # Get the attributes. xmlList.insert( len( xmlList ) - 1, '\t\t<attr name=\"{0}">'.format( a ) ) plug = NodeUtility.getPlug( MFnDagNode.name(), a ) plugValue = NodeUtility.getPlugValue( plug ) if isinstance( plugValue, types.ListType ): for i in plugValue: xmlList.insert( len( xmlList ) - 1, '\t\t\t<value>{0}</value>'.format( i ) ) else: xmlList.insert( len( xmlList ) - 1, '\t\t\t<value>{0}</value>'.format( plugValue ) ) xmlList.insert( len( xmlList ) - 1, '\t\t</attr>' ) # close the data tag xmlList.append( '</data>' ) # create new file newfile = file( os.path.join( filePath, fileName ), 'w') for i in xmlList: newfile.write( i+'\n' ) newfile.close()
def controlScale( self ): sourcePosPlug = NodeUtility.getPlug( 'CurveControlComponent1', 'controlScale' ) return NodeUtility.getPlugValue( sourcePosPlug )
def __init__( self, nodeName, parent=None ): super( componentWidget, self ).__init__( parent ) self.parent = parent def on_context_menu( point, inNodeName ): popMenu = QtGui.QMenu() deleteAction = QtGui.QAction( 'Delete Component', popMenu, triggered=lambda a=inNodeName:self.deleteComponentFromObject( a ) ) popMenu.addAction( deleteAction ) popMenu.exec_( self.componentLabel.mapToGlobal( point ) ) # Setup layout. verticalLayout = QtGui.QVBoxLayout() verticalLayout.setContentsMargins( 0,0,0,0 ) verticalLayout.setSpacing( 0 ) verticalLayout.setAlignment( QtCore.Qt.AlignTop ) # Label for component componentLabel = QTWidgets.basicLabel( nodeName, 'bold', 10, 'black', '6E9094', inIndent=20 ) componentLabel.setMinimumHeight( 18 ) componentLabel.setContextMenuPolicy( QtCore.Qt.CustomContextMenu ) componentLabel.customContextMenuRequested.connect( lambda point, nodeName=nodeName:on_context_menu( point, nodeName ) ) # Properties propertyStack = QtGui.QVBoxLayout() propertyFrame = QTWidgets.basicFrame() propertyFrame.setMinimumHeight( 120 ) propertyFrame.setMaximumHeight( 120 ) # Add string edit property characterPlug = NodeUtility.getPlug( nodeName, 'characterName' ) characterValue = NodeUtility.getPlugValue( characterPlug ) characterTextLayout = QTWidgets.stringProperty( 'Character Name', characterValue ) skelGroupPlug = NodeUtility.getPlug( nodeName, 'skeletonGroupName' ) skelGroupValue = NodeUtility.getPlugValue( skelGroupPlug ) skelGroupTextLayout = QTWidgets.stringProperty( 'Skeleton Group Name', skelGroupValue ) rigGroupPlug = NodeUtility.getPlug( nodeName, 'rigGroupName' ) rigGroupValue = NodeUtility.getPlugValue( rigGroupPlug ) rigGroupTextLayout = QTWidgets.stringProperty( 'Rigging Group Name', rigGroupValue ) ''' ADD MODULES BUTTON. PROBABLY HAVE A POPUP LISTING UNCONNECTED MODULES IN THE SCENE?? ''' # Add everything to the vertical layout. propertyStack.addLayout( characterTextLayout ) propertyStack.addLayout( skelGroupTextLayout ) propertyStack.addLayout( rigGroupTextLayout ) propertyFrame.setLayout( propertyStack ) verticalLayout.addWidget( componentLabel ) verticalLayout.addWidget( propertyFrame ) # Connections charTextBox = propertyFrame.findChild( QtGui.QLineEdit, 'Character Name' ) charTextBox.editingFinished.connect( lambda inPlugName='characterName', inQTType='QLineEdit', inPlugValue=charTextBox, inNodeName=nodeName :CharacterRootComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) skelTextBox = propertyFrame.findChild( QtGui.QLineEdit, 'Skeleton Group Name' ) skelTextBox.editingFinished.connect( lambda inPlugName='skeletonGroupName', inQTType='QLineEdit', inPlugValue=skelTextBox, inNodeName=nodeName :CharacterRootComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) rigTextBox = propertyFrame.findChild( QtGui.QLineEdit, 'Rigging Group Name' ) rigTextBox.editingFinished.connect( lambda inPlugName='rigGroupName', inQTType='QLineEdit', inPlugValue=rigTextBox, inNodeName=nodeName :CharacterRootComponent( inNodeName ).setComponentAttributeFromQT( inPlugName, inQTType, inPlugValue, inNodeName ) ) #return mainWidget self.setLayout( verticalLayout )
def makeDeformerMesh(): ''' Creates a deformer mesh for the active controller. ''' # Get the current user selection. selList = OpenMaya.MSelectionList() OpenMaya.MGlobal.getActiveSelectionList( selList ) if selList.length() is 1: control = OpenMaya.MObject() selList.getDependNode( 0, control ) controlDagNode = OpenMaya.MFnDagNode( control ) # Check if the selected control already has a deformer mesh. if controlDagNode.childCount() > 1: for c in xrange( controlDagNode.childCount() ): if controlDagNode.child( c ).apiType() == OpenMaya.MFn.kMesh: print 'The selected controller has a deformer mesh already.' return controlShape = controlDagNode.child( 0 ) controlShapeDep = OpenMaya.MFnDependencyNode( controlShape ) if controlShape.apiType() == OpenMaya.MFn.kPluginLocatorNode: # Get the controller OpenGL attributes. glPosition = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'localPosition' ) ) #glRotation = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'rotate' ) ) glWidth = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'width' ) ) glHeight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'height' ) ) glDepth = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'depth' ) ) glBottomBackRight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botBackRight' ) ) glBottomBackLeft = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botBackLeft' ) ) glBottomFrontLeft = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botFrontLeft' ) ) glBottomFrontRight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'botFrontRight' ) ) glTopBackRight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topBackRight' ) ) glTopFrontRight = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topFrontRight' ) ) glTopFrontLeft = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topFrontLeft' ) ) glTopBackLeft = NodeUtility.getPlugValue( NodeUtility.getPlug( controlShapeDep.name(), 'topBackLeft' ) ) # Mesh cube attributes. numPolygons = 6 numVertices = 8 numPolygonConnects = 4 * numPolygons # Floating point array listing the XYZ for each vertex in the cube. # Add in the Width/Height/Depth values and the offset translation. vertexArray = OpenMaya.MFloatPointArray() vertexArray.setLength( numVertices ) vertexArray.set( OpenMaya.MFloatPoint( ( -glWidth/2+glBottomBackRight[0] ) + glPosition[0], ( -glHeight/2+glBottomBackRight[1] ) + glPosition[1], ( -glDepth/2+glBottomBackRight[2] ) + glPosition[2] ), 0 )#bottomBackRight vertexArray.set( OpenMaya.MFloatPoint( ( glWidth/2+glBottomBackLeft[0] ) + glPosition[0], ( -glHeight/2+glBottomBackLeft[1] ) + glPosition[1], ( -glDepth/2+glBottomBackLeft[2] ) + glPosition[2] ), 1 )#bottomBackLeft vertexArray.set( OpenMaya.MFloatPoint( ( glWidth/2 + glBottomFrontLeft[0] ) + glPosition[0], ( -glHeight/2+glBottomFrontLeft[1] ) + glPosition[1], ( glDepth/2+glBottomFrontLeft[2] ) + glPosition[2] ), 2 )#bottomFrontLeft vertexArray.set( OpenMaya.MFloatPoint( ( -glWidth/2 + glBottomFrontRight[0] ) + glPosition[0], ( -glHeight/2+glBottomFrontRight[1] ) + glPosition[1], ( glDepth/2+glBottomFrontRight[2] ) + glPosition[2] ), 3 )#bottomFrontRight vertexArray.set( OpenMaya.MFloatPoint( ( -glWidth/2+glTopBackRight[0] ) + glPosition[0], ( glHeight/2+glTopBackRight[1] ) + glPosition[1], ( -glDepth/2+glTopBackRight[2] ) + glPosition[2] ), 4 )#topBackRight vertexArray.set( OpenMaya.MFloatPoint( ( -glWidth/2 + glTopFrontRight[0] ) + glPosition[0], ( glHeight/2 + glTopFrontRight[1] ) + glPosition[1], ( glDepth/2 + glTopFrontRight[2] ) + glPosition[2] ), 5 )#topFrontRight vertexArray.set( OpenMaya.MFloatPoint( ( glWidth/2 + glTopFrontLeft[0] ) + glPosition[0], ( glHeight/2+glTopFrontLeft[1] ) + glPosition[1], ( glDepth/2+glTopFrontLeft[2] ) + glPosition[2] ), 6 )#topFrontLeft vertexArray.set( OpenMaya.MFloatPoint( ( glWidth/2+glTopBackLeft[0] ) + glPosition[0], ( glHeight/2+glTopBackLeft[1] ) + glPosition[1], ( -glDepth/2+glTopBackLeft[2] ) + glPosition[2] ), 7 )#topBackLeft # Int array listing the number of vertices for each face. In this case there are # 4 vertices per face and a total of 6 faces. polygonCounts = OpenMaya.MIntArray() polygonCounts.setLength( numPolygons ) polygonCounts.set( 4, 0 ) polygonCounts.set( 4, 1 ) polygonCounts.set( 4, 2 ) polygonCounts.set( 4, 3 ) polygonCounts.set( 4, 4 ) polygonCounts.set( 4, 5 ) # Int array listing the vertices for every face. # The first number is the vertex index from vertexArray. polygonConnects = OpenMaya.MIntArray() polygonConnects.setLength( numPolygonConnects ) # Bottom face. -Y. polygonConnects.set(0, 0) polygonConnects.set(1, 1) polygonConnects.set(2, 2) polygonConnects.set(3, 3) # Top face. +Y. polygonConnects.set(4, 4) polygonConnects.set(5, 5) polygonConnects.set(6, 6) polygonConnects.set(7, 7) # Front face. +Z. polygonConnects.set(3, 8) polygonConnects.set(2, 9) polygonConnects.set(6, 10) polygonConnects.set(5, 11) # Right face. -X. polygonConnects.set(0, 12) polygonConnects.set(3, 13) polygonConnects.set(5, 14) polygonConnects.set(4, 15) # Back Face. -Z. polygonConnects.set(0, 16) polygonConnects.set(4, 17) polygonConnects.set(7, 18) polygonConnects.set(1, 19) # Left face. +X. polygonConnects.set(1, 20) polygonConnects.set(7, 21) polygonConnects.set(6, 22) polygonConnects.set(2, 23) # Make the mesh cube. meshFn = OpenMaya.MFnMesh() meshFn.create(numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, control ) else: sys.stderr.write( 'makeDeformerMesh: Wrong type of object selected.') else: sys.stderr.write( 'makeDeformerMesh: Nothing selected.' )