def loadModule( inFolder, inFileName ): ''' Loads a module into the scene. @param inFolder: String. Name for the sub-folder the module XML is located. @param inFileName: String. Name of the module XML. ''' dirPath = getPresetPath( FRAME_PRESETS_PATH+inFolder ) fullPath = dirPath+'/'+inFileName+'.xml' xmlFile = readModuleXML( fullPath ) # Create a temp group to put the module inside while creating. moduleGroup = '|{0}'.format( cmds.group( em=True, name='TEMP' ) ) # Grab all the bits. bits = xmlFile['bits'] # Make each bit. tick = 0 storeBitConnections = [] while tick < len(bits): if bits[0]['parent'] == 'None': bitParent = moduleGroup else: bitParent = moduleGroup+bits[0]['parent'] bitName = bits[0]['name'] bitPlugs = bits[0]['plugs'] shapePlugs = bits[0]['shape'] bitComponents = bits[0]['components'] # Make the bit. if cmds.objExists( bitParent ): newBit = cmds.makeGLBit( name=bitName, objecttype=bits[0]['shapeType'] ) cmds.parent( newBit, bitParent ) # From this point we use the long name for the bit. This avoids any # name clashes. fullBitName = '{0}{1}'.format( bitParent, newBit ) # Setup plugs for transform and custom attributes. for plug in bitPlugs: if not NodeUtility.attributeCheck( fullBitName, plug['name'] ): NodeUtility.addPlug( fullBitName, plug['name'], plug['attrType'], plug['attrDataType'] ) if plug['value'] is not None: NodeUtility.setPlug( fullBitName, plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) else: # Setup position and rotation. NodeUtility.setPlug( fullBitName, plug['name'], plug['value'] ) # Setup plugs for shape attributes. shapeName = cmds.listRelatives( fullBitName, shapes=True ) fullShapeName = '{0}|{1}'.format( fullBitName, shapeName[0] ) for plug in shapePlugs: if plug['attrDataType'] == 'TdataCompound' or plug['attrDataType'] == 'matrix': # We skip compound nodes at this stage. They are for the child arrow drawing and must be # hooked up after all the objects are created. connectionChild = '{0}{1}'.format( moduleGroup, plug['value'] ) storeBitConnections.append( { 'parent':fullBitName, 'child':connectionChild } ) elif plug['attrDataType'] == 'message': print 'MESSAGE' else: NodeUtility.setPlug( fullShapeName, plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) # Setup bit components. for comp in bitComponents: compType = comp['name'] # We have to special case components that have additional kwargs. if compType == 'CurveControlComponent': # Handle curve control component type. for plug in comp['plugs']: if plug['name'] == 'curveType': curveType = plug['value'] newComp = components.addComponentToObject( compType, inObject=fullBitName, curveType=curveType ) else: # Handle basic component. newComp = components.addComponentToObject( compType, inObject=fullBitName ) for plug in comp['plugs']: # Bit of a hack with the parentName attribute. This attr is setup when the component is created. # So there is no need to apply the stored plug value from the XML. if plug['attrDataType'] == 'message': if plug['name'] != 'parentName': if plug['value'] != 'None': sourcePlug = plug['value'].split('.') NodeUtility.connectNodes( sourcePlug[0], sourcePlug[1], newComp.name(), plug['name'] ) else: NodeUtility.setPlug( newComp.name(), plug['name'], plug['value'], inAttrDataType=plug['attrDataType'] ) # Remove the bit from the list bits.remove( bits[0] ) #tick = tick+1 # Now do the hook ups for the child arrows. for i in storeBitConnections: NodeUtility.setBitChild( i['parent'], i['child'] )
def __init__( self ): super( UIComponentsTools, self ).__init__() layout = QtGui.QVBoxLayout( self ) # COMPONENTS MENU BAR menuFrame = QtGui.QFrame() menuFrame.setMinimumHeight( 20 ) # Meta menu. moduleMeta = QtGui.QAction( '&Module Meta', self) moduleMeta.triggered.connect( lambda a='ModuleRootComponent':Components.addComponentToObject( a ) ) characterMeta = QtGui.QAction( '&Character Meta', self) characterMeta.triggered.connect( lambda a='CharacterRootComponent':Components.addComponentToObject( a ) ) # Joints menu basicJoint = QtGui.QAction( '&Basic Joint', self) #basic_joint.setShortcut('Ctrl+Q') #basic_joint.setStatusTip('Exit application') basicJoint.triggered.connect( lambda a='BasicJointComponent':Components.addComponentToObject( a ) ) # Controls menu squareCurveControl = QtGui.QAction( '&Square', self) squareCurveControl.triggered.connect( lambda a='CurveControlComponent', b='square':Components.addComponentToObject( a, curveType=b ) ) triangleCurveControl = QtGui.QAction( '&Triangle', self) triangleCurveControl.triggered.connect( lambda a='CurveControlComponent', b='triangle':Components.addComponentToObject( a, curveType=b ) ) arrowCurveControl = QtGui.QAction( '&Arrow', self) arrowCurveControl.triggered.connect( lambda a='CurveControlComponent', b='arrow':Components.addComponentToObject( a, curveType=b ) ) plusCurveControl = QtGui.QAction( '&Plus', self) plusCurveControl.triggered.connect( lambda a='CurveControlComponent', b='plus':Components.addComponentToObject( a, curveType=b ) ) pyramidCurveControl = QtGui.QAction( '&Pyramid', self) pyramidCurveControl.triggered.connect( lambda a='CurveControlComponent', b='pyramid':Components.addComponentToObject( a, curveType=b ) ) circleCurveControl = QtGui.QAction( '&Circle', self) circleCurveControl.triggered.connect( lambda a='CurveControlComponent', b='circle':Components.addComponentToObject( a, curveType=b ) ) ringDirectionCurveControl = QtGui.QAction( '&Ring Direction', self) ringDirectionCurveControl.triggered.connect( lambda a='CurveControlComponent', b='ringDirection':Components.addComponentToObject( a, curveType=b ) ) # Setup menus. componentsMenubar = QtGui.QMenuBar( menuFrame ) metaMenu = componentsMenubar.addMenu( '&Meta' ) metaMenu.addAction( moduleMeta ) metaMenu.addAction( characterMeta ) jointsMenu = componentsMenubar.addMenu( '&Joints' ) jointsMenu.addAction( basicJoint ) controlsMenu = componentsMenubar.addMenu( '&Controls' ) controlsCurvesMenu = controlsMenu.addMenu( '&Curves' ) controlsCurvesMenu.addAction( squareCurveControl ) controlsCurvesMenu.addAction( triangleCurveControl ) controlsCurvesMenu.addAction( arrowCurveControl ) controlsCurvesMenu.addAction( plusCurveControl ) controlsCurvesMenu.addAction( pyramidCurveControl ) controlsCurvesMenu.addAction( circleCurveControl ) controlsCurvesMenu.addAction( ringDirectionCurveControl ) constraintsMenu = componentsMenubar.addMenu( '&Constraints' ) deformersMenu = componentsMenubar.addMenu( '&Deformers' ) # SELECTED HEADER self.selectedLockBtn = QTWidgets.imageTextButton( '', ':/riggingUI/icons/lock_off.png', [16,16] ) self.selectedLockBtn.setMaximumWidth( 30 ) self.selectedLockBtn.clicked.connect( self.lockSelection ) self.selectedLockActive = False self.selectedLabel = QTWidgets.basicLabel( 'nothing selected', 'bold', 14, 'white', '2B2B30', inIndent=10 ) self.selectedLabel.setMinimumHeight( 30 ) self.selectedLabel.setAlignment( QtCore.Qt.AlignCenter ) selectedGrid = QtGui.QGridLayout() selectedGrid.setContentsMargins( 0, 0, 0, 0 ) selectedGrid.setHorizontalSpacing( 0 ) selectedGrid.setColumnMinimumWidth( 0, 30 ) selectedGrid.addWidget( self.selectedLockBtn, 0, 0 ) selectedGrid.addWidget( self.selectedLabel, 0, 1 ) # SELECTED COMPONENTS LIST/EDITOR # Add the component specific GUI. self.componentsLayout = QtGui.QVBoxLayout() self.componentsLayout.setAlignment( QtCore.Qt.AlignTop ) scrollArea = QTWidgets.scrollArea( self.componentsLayout ) # Layout hookup layout.addWidget( menuFrame ) layout.addLayout( selectedGrid ) layout.addWidget( scrollArea ) # In order to delete this scriptJob when this UI is destroyed we need to # parent the scriptJob to a Maya UI item. In this case I'm using a text object # with visibility turned off. scriptJobHolder = cmds.text( visible=False ) self.SCRIPT_JOB_NUMBER = cmds.scriptJob( event=[ 'SelectionChanged', self.onSelectionChange ], protected=True, parent=scriptJobHolder ) scriptJobHolderQT = mayaToQtObject( scriptJobHolder ) layout.addWidget( scriptJobHolderQT )