def build_head(): pymelLogger.debug('Starting: build_head()...') Neck.build() Head.build() pymelLogger.debug('End: build_head()...')
def parentToControlsGrp( characterNode ): pymelLogger.debug('Starting: parentToControlsGrp()...') pm.parent( characterNode, Names.modules_grp ) pymelLogger.debug('End: parentToControlsGrp()...')
def importCrvs(): pymelLogger.debug('Starting: importCrvs()...') _importFile() _applyCurves() pymelLogger.debug('End: importCrvs()...')
def completeStretchySetup( expr, expressionNode, characterNode, curveInfoNodeBack ): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit = True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleX') pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def _makeFkControls(fkControls=None, side=None): pymelLogger.debug('Starting: _makeControls()...') topNodeList = [] for ctrl in fkControls: parent = ctrl.replace('_'+Names.suffixes['fk']+'_'+Names.suffixes['control'],'') topNode = Control.create( name=ctrl, offsets=3, shape='circle_01', size=1.5, color=_getSideColor(side), pos=None, parent=parent, typ='body' ) pm.parent(topNode, world=1) topNodeList.append(topNode) # getting ctrl and contrainting it directly to the jnt childs = topNode.listRelatives(ad=1) if 'Shape' in str(childs[0]): cc = childs[1] else: cc = childs[0] pm.parentConstraint(cc,parent, mo=1) # parent each offset to the previous ctrl topNodeList.reverse() last = '' for element in topNodeList: if last: last.setParent(element.listRelatives(ad=1)[1]) # getting transform node not shape last = element topOffsetNode = last return topOffsetNode pymelLogger.debug('End: _makeControls()...')
def build(side=None): pymelLogger.debug('Starting: build()...') # Define names if side == Names.prefixes['left']: follow_chain = [ '%s%s_%s'%(Names.prefixes['left'], jnt, Names.suffixes['follow']) for jnt in Names.joints_arm] fk_chain = [ '%s%s_%s'%(Names.prefixes['left'], jnt, Names.suffixes['fk']) for jnt in Names.joints_arm] ik_chain = [ '%s%s_%s'%(Names.prefixes['left'], jnt, Names.suffixes['ik']) for jnt in Names.joints_arm] fkControls = Names.controls_leftArmFk ikControls = Names.controls_leftArmIk if side == Names.prefixes['right']: follow_chain = [ '%s%s_%s'%(Names.prefixes['right'], jnt, Names.suffixes['follow']) for jnt in Names.joints_arm] fk_chain = [ '%s%s_%s'%(Names.prefixes['right'], jnt, Names.suffixes['fk']) for jnt in Names.joints_arm] ik_chain = [ '%s%s_%s'%(Names.prefixes['right'], jnt, Names.suffixes['ik']) for jnt in Names.joints_arm] fkControls = Names.controls_rightArmFk ikControls = Names.controls_rightArmIk # Build functions topOffsetNode = _makeFkControls(fkControls=fkControls, side = side) # topOffsetNode _cleanUp( topOffsetNode ) #_makeIkControls(ikControls=ikControls) #_makeJoints(side=side, fkChain=fk_chain, ikChain=ik_chain) #_makeFkRig(side=side, fkChain=fk_chain) #_makeIkRig(side=side, ikChain=ik_chain) #_bindFollowChain(followChain=follow_chain, fkChain=fk_chain, ikChain=ik_chain) pymelLogger.debug('End: build()...')
def stretchyBack(ikHandleTorso, jntList): pymelLogger.debug('Starting: stretchyBack()...') #Stretchy process # ArcLen to create curveInfo curveInfoNodeBack = pm.arclen(ikHandleTorso[2], ch=True) # add attr to curveinfo Node (normalizedScale) # this will have a value coming from a multiply divide node that will be # dividing the current length by the initial length of the curve # this will be used later to scale the joints pm.addAttr(curveInfoNodeBack, longName='normalizedScale', attributeType='double') # get initial length of the curve iniLen = pm.getAttr(curveInfoNodeBack + '.arcLength') # create a node multiplydivide, operation set to division MDCurveBack = pm.shadingNode('multiplyDivide', asUtility=True) pm.setAttr(MDCurveBack + '.operation', 2) # divide # Connect curve arcLength to input1X pm.connectAttr(curveInfoNodeBack + '.arcLength', MDCurveBack + '.input1X', force=True) # Set input2X to initial length of the curve pm.setAttr(MDCurveBack + '.input2X', iniLen) # connect outpux x from multiplydivide to normalized scale of the curve info pm.connectAttr(MDCurveBack + '.outputX', curveInfoNodeBack + '.normalizedScale', force=True) returnList = [curveInfoNodeBack, MDCurveBack] pymelLogger.debug('End: stretchyBack()...') return returnList
def build( side=None ): pymelLogger.debug('Starting: build()...') if side == None: raise Exception('Make sure side: %s is valid '%side) if side == Names.prefixes['left']: LegJnts = Names.joints_leftLegNoRoll elif side == Names.prefixes['right']: LegJnts = Names.joints_rightLegNoRoll else: raise Exception('Make sure side: %s is valid '%side) listJnts = createJnts(LegJnts,side) # [listJnts] # create ik leg ikReturn = createIKLeg( listJnts, side ) # [pv_cnt, foot_cnt, ikh] pv_cnt = ikReturn[0] foot_cnt = ikReturn[1] ikh = ikReturn[2] # cleanUp cleanUp( listJnts, pv_cnt, foot_cnt ) # connect to sh # list with the no rot toetoeBaseJnt = rList[0] #sourceJnts = listJnts[:-1] sourceJnts = listJnts #sourceJnts.append(toeBaseJnt[0]) connectToSH( sourceJnts, LegJnts ) # deselect selected to make sure that following module does not break pm.select(clear=1) pymelLogger.debug('End: build()...')
def createHipShoudersControls(drvStart, drvEnd, jntList): pymelLogger.debug('Starting: createHipShoudersControls()...') # Get drvStart Position drvS_pos = pm.xform(drvStart[0], query=True, translation=True) # Get drvEnd Position drvE_pos = pm.xform(drvEnd[0], query=True, translation=True) # Create Hip Control ctrl = jntList[0] + '_' + Names.suffixes['control'] rot = pm.xform(drvStart[0], q=1, ws=1, ro=1) rot = [-90, 0, 90] hips_cnt = Control.create(name=ctrl, offsets=2, shape='cube', size=[1, 1, 1], color='cyan', pos=drvS_pos, rot=rot, parent=None, typ='body') # Create Shoulder Ctrl #shoulder_cnt = Control.create() ######## fix this !!! top spine ctrl shoud b called SpineX_ctrl ctrl = jntList[-1] + '_' + Names.suffixes['control'] rot = pm.xform(jntList[-1], ws=1, q=1, ro=1) shoulder_cnt = Control.create(name=ctrl, offsets=2, shape='circle_01', size=2, color='red', pos=drvE_pos, rot=rot, parent=None, typ='body') # Connect CC to Drv Jnts pm.parentConstraint(hips_cnt.listRelatives(ad=1)[0].getParent(), drvStart, maintainOffset=True) pm.parentConstraint(shoulder_cnt.listRelatives(ad=1)[0].getParent(), drvEnd, maintainOffset=True) # Clean Ctrls Attributes (Lock and Hide Scale and Visibility) hideLockAttr(hips_cnt, lockHideSV) hideLockAttr(shoulder_cnt, lockHideSV) hideLockAttr(drvStart[0], lockHideS) hideLockAttr(drvEnd[0], lockHideS) rList = [hips_cnt, shoulder_cnt] pymelLogger.debug('End: createHipShoudersControls()...') return rList
def build(side=None): pymelLogger.debug('Starting: build()...') if side == None: raise Exception('Make sure side: %s is valid ' % side) if side == Names.prefixes['left']: LegJnts = Names.joints_leftLegNoRoll elif side == Names.prefixes['right']: LegJnts = Names.joints_rightLegNoRoll else: raise Exception('Make sure side: %s is valid ' % side) listJnts = createJnts(LegJnts, side) # [listJnts] # create ik leg ikReturn = createIKLeg(listJnts, side) # [pv_cnt, foot_cnt, ikh] pv_cnt = ikReturn[0] foot_cnt = ikReturn[1] ikh = ikReturn[2] # cleanUp cleanUp(listJnts, pv_cnt, foot_cnt) # connect to sh # list with the no rot toetoeBaseJnt = rList[0] #sourceJnts = listJnts[:-1] sourceJnts = listJnts #sourceJnts.append(toeBaseJnt[0]) connectToSH(sourceJnts, LegJnts) # deselect selected to make sure that following module does not break pm.select(clear=1) pymelLogger.debug('End: build()...')
def createIKSpline( jntList ): pymelLogger.debug('Starting: createIKSpline()...') # Make IK Spline ikHandleTorso = pm.ikHandle( startJoint=jntList[0], endEffector=jntList[-1], solver = 'ikSplineSolver', numSpans = 4, name = jntList[-1]+'_'+Names.suffixes['ikhandle']) # we should probably rename the object created to know names ...... # CAREFULL // inherits Transform OFF, to avoid double transformation when grouped later on pm.setAttr(ikHandleTorso[2] + '.inheritsTransform', 0) # Duplicate last and first joint to use as Drivers of the spine Ik curve print jntList drvStart = pm.duplicate(jntList[0], parentOnly=True, name = Names.prefixes['driver']+'_'+ jntList[0] +'_'+Names.suffixes['start']) drvEnd = pm.duplicate(jntList[-1], parentOnly=True, name = Names.prefixes['driver']+'_'+ jntList[-1] +'_'+Names.suffixes['end']) pm.parent(drvEnd, w=1) # Make radius bigger pm.joint(drvStart, edit = True, radius = 1) pm.joint(drvEnd, edit = True, radius = 1) # Skin hip/shldr jnt's to back curve pm.skinCluster(drvStart,drvEnd,ikHandleTorso[2],dr=4) # return nedded elements rList = [ikHandleTorso, drvStart, drvEnd ] pymelLogger.debug('End: createIKSpline()...') return rList
def exportAnim(self, fileName=None, assetPath=None, unityPath=None, ignore=None): ''' Export animation for each rig found in the current scene. Export camera with name from names.cameras.shot_cam_names list Rig must be referenced. ''' pymelLogger.debug('exportAnim(): Starting...') # Export to directory wih animation file name # Assets/art/animation/anim_type/anim_name try: fName = os.path.basename(fileName)[:-3] typ = fName.split('_')[-2:] typ = typ[0] + '_' + typ[1] dirName = fName.split('_')[:-2] dName = '' for each in dirName: dName += each + '_' dirName = dName[:-1] unityPath = unityPath + '/animation/' + typ + '/' + dirName except Exception, e: pymelLogger.error('exportAnim(): Error creating UnityPath.') pymelLogger.error(e) raise Exception(e)
def exportRig(self): """ will export SH and Geo found in the geo folder """ # rig and geo should not be referenced # find SH, delete constraints, parent to world # find geo folder parent to world # select SH and geo folder and export as fbx to fbx folder pymelLogger.debug( 'Starting rig export' ) export = 0 for rig in self.rootList: if cmds.objExists(rig): # check if geo folder also exists if cmds.objExists(self.geo): self._delConstraints(rig) cmds.parent(rig, w=1) cmds.parent(self.geo, w=1) cmds.select(rig,self.geo, r=1) #print rig, self.geo if self._fbxExport( 2 ): cmds.confirmDialog(m='FBX Rig Exported', button='Ok') pymelLogger.debug( 'Finished rig export' ) export = 1 break else: pymelLogger.error( 'No geo folder has been found' ) if export == 0 : pymelLogger.error( 'No Rig Exported. Note: Referenced Rigs Will Not Export' )
def completeStretchySetup(expr, expressionNode, characterNode, curveInfoNodeBack): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit=True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleX') pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def exportRig(self): """ will export SH and Geo found in the geo folder """ # rig and geo should not be referenced # find SH, delete constraints, parent to world # find geo folder parent to world # select SH and geo folder and export as fbx to fbx folder pymelLogger.debug('Starting rig export') export = 0 for rig in self.rootList: if cmds.objExists(rig): # check if geo folder also exists if cmds.objExists(self.geo): self._delConstraints(rig) cmds.parent(rig, w=1) cmds.parent(self.geo, w=1) cmds.select(rig, self.geo, r=1) #print rig, self.geo if self._fbxExport(2): cmds.confirmDialog(m='FBX Rig Exported', button='Ok') pymelLogger.debug('Finished rig export') export = 1 break else: pymelLogger.error('No geo folder has been found') if export == 0: pymelLogger.error( 'No Rig Exported. Note: Referenced Rigs Will Not Export')
def stretchyBack( ikHandleTorso, jntList ): pymelLogger.debug('Starting: stretchyBack()...') #Stretchy process # ArcLen to create curveInfo curveInfoNodeBack = pm.arclen( ikHandleTorso[2], ch=True ) # add attr to curveinfo Node (normalizedScale) # this will have a value coming from a multiply divide node that will be # dividing the current length by the initial length of the curve # this will be used later to scale the joints pm.addAttr(curveInfoNodeBack, longName='normalizedScale', attributeType='double') # get initial length of the curve iniLen = pm.getAttr( curveInfoNodeBack + '.arcLength' ) # create a node multiplydivide, operation set to division MDCurveBack = pm.shadingNode( 'multiplyDivide', asUtility=True ) pm.setAttr( MDCurveBack+'.operation', 2 ) # divide # Connect curve arcLength to input1X pm.connectAttr( curveInfoNodeBack + '.arcLength', MDCurveBack + '.input1X', force=True ) # Set input2X to initial length of the curve pm.setAttr(MDCurveBack+'.input2X', iniLen) # connect outpux x from multiplydivide to normalized scale of the curve info pm.connectAttr(MDCurveBack + '.outputX', curveInfoNodeBack + '.normalizedScale', force=True) returnList = [curveInfoNodeBack,MDCurveBack] pymelLogger.debug('End: stretchyBack()...') return returnList
def exportCrvs(): pymelLogger.debug('Starting: exportCrvs()...') ctrlList = _getCharNodeCurves() _extractCurves( ctrlList ) _exportCurvesFile() pymelLogger.debug('End: exportCrvs()...')
def build(): pymelLogger.debug('Starting: build()...') _makeControls() _constrainSHToControls() _connectToBody() pymelLogger.debug('End: build()...')
def _getSideColor(side=None): pymelLogger.debug('Starting: _getSideColor()...') if side == Names.prefixes['left']: crv_color='red' elif side == Names.prefixes['right']: crv_color='midBlue' else: crv_color='white' return crv_color pymelLogger.debug('End: _getSideColor()...')
def exportCrvs(): pymelLogger.debug('Starting: exportCrvs()...') ctrlList = _getCharNodeCurves() _extractCurves(ctrlList) _exportCurvesFile() pymelLogger.debug('End: exportCrvs()...')
def _getSideColor(side=None): pymelLogger.debug('Starting: _getSideColor()...') if side == Names.prefixes['left']: crv_color = 'red' elif side == Names.prefixes['right']: crv_color = 'midBlue' else: crv_color = 'white' return crv_color pymelLogger.debug('End: _getSideColor()...')
def createJnts(side=None, fingerJnts=None, hasEndJnt=None): pymelLogger.debug('Starting: createJnts()...') startJnts = [] endJnts = [] attNames = [] originalJnts = [] newJnts = [] for jnt in fingerJnts: # if jnt exists on the scene save it on list otherwise continue searching if pm.objExists(jnt[0]): topJnt = pm.ls(jnt[0], r=1)[0] newJntChain = pm.duplicate(topJnt, rr=True, po=False, name=topJnt + '_' + Names.suffixes['fk'])[0] newJntChain.setParent(world=1) startJnts.append(newJntChain) # getting name for attr "index, thumb ..." noSuf = newJntChain.split('_' + Names.suffixes['fk'])[0] endPart = noSuf[ noSuf.rfind(side + Names.joints_hf[0] ):] # if more than 9 jnts, it will break!!!!! endPre = len(side + Names.joints_hf[0]) attNames.append(endPart[endPre:-1].replace('|', '')) newChildJnts = newJntChain.listRelatives(ad=1) end = newChildJnts[0] # rename all the new jnts! for nJnt in newChildJnts: nJnt.rename(nJnt + '_' + Names.suffixes['fk']) newChildJnts.append(newJntChain) newJnts.append(newChildJnts) oldChildJnts = topJnt.listRelatives(ad=1) oldChildJnts.append(topJnt) originalJnts.append(oldChildJnts) # if no child will break!!!! if hasEndJnt == 1: endJnts.append(end.getParent()) else: endJnts.append(end) else: continue newJnts.reverse() originalJnts.reverse() rList = [startJnts, endJnts, attNames, newJnts, originalJnts] pymelLogger.debug('End: createJnts()...') return rList
def createJnts( LegJnts, side ): pymelLogger.debug('Starting: createJnts()...') # duplicate joints listJnts = [] print LegJnts for jnt in LegJnts: pm.select(clear=1) newJnt = pm.duplicate(jnt,rr=True,po=True, name=jnt+'_'+Names.suffixes['ik'])[0] try: newJnt.setParent(world=1) except: pass listJnts.append(newJnt) print listJnts # parent joints listJnts.reverse() index = 0 for jnt in listJnts: if index+1 == len(listJnts): break jnt.setParent(listJnts[index+1]) index = index + 1 listJnts.reverse() # joints for inverse foot ankleFloorJnt = '%s%s' %(side,'AnkleFloor_if') # duplicate only joints ww for inverse foot pm.select(clear=1) toeBaseWW = listJnts[-3] invfootname = str(toeBaseWW).replace('_'+Names.suffixes['ik'], '_inversefoot') invfootjnt = pm.duplicate( toeBaseWW, name=invfootname )[0] invfootjnt.setParent(w=1) index = 1 invjntlist = invfootjnt.listRelatives(ad=1) invjntlist.reverse() for jnt in invjntlist: jnt.rename(invfootname+str(index)) jnt.setParent(w=1) index += 1 invjntlist.reverse() invjntlist.append(invfootjnt) invjntlist.reverse() index = 0 for jnt in invjntlist: if index+1 == len(invjntlist): break jnt.setParent(invjntlist[index+1]) index = index + 1 # make them child of the Ankle floor jnt invjntlist[-1].setParent(ankleFloorJnt) pm.select(clear=1) pymelLogger.debug('End: createJnts()...') print listJnts return listJnts
def _constrainLocsToControls(): pymelLogger.debug('Starting: _constrainLocsToControls()...') # Head pm.parentConstraint(Names.controls_head[0],'Head_ctrl_bind_grp',mo=1) # Neck1 pm.parentConstraint(Names.controls_neck[1],'Neck1_grp',mo=1) # Neck pm.parentConstraint(Names.controls_neck[0],'Neck_grp',mo=1) pymelLogger.debug('End: _constrainLocsToControls()...')
def connectToSH( source_jnts, torso_jnts ): pymelLogger.debug('Starting: connectToSH()...') for jntS,jntT in zip(source_jnts,torso_jnts): try: pm.parentConstraint( jntS, jntT, mo=1 ) except: print 'Could not constraint: ' + jntS,jntT pymelLogger.debug('End: connectToSH()...')
def _connectToSH( newJnts, originalJnts ): pymelLogger.debug('Starting: connectToSH()...') for nJnts, oriJnts in zip(newJnts,originalJnts): for jntS,jntT in zip(nJnts, oriJnts): try: pm.parentConstraint( jntS, jntT, mo=1 ) except: print 'Could not constraint: ' + jntS,jntT pymelLogger.debug('End: connectToSH()...')
class Export(object): def __init__(self): ''' Export asset/rig/animation/camera as FBX to AssetLib and Unity directory. ''' self.rootList = rig_names.rootList self.assetTypes = asset_names.types self.camNames = cam_names.shot_cam_names self.geo = 'geo' self.custom = 'custom' pymelLogger.debug('Initializing...') def exportAnim(self, fileName=None, assetPath=None, unityPath=None, ignore=None): ''' Export animation for each rig found in the current scene. Export camera with name from names.cameras.shot_cam_names list Rig must be referenced. ''' pymelLogger.debug('exportAnim(): Starting...') # Export to directory wih animation file name # Assets/art/animation/anim_type/anim_name try: fName = os.path.basename(fileName)[:-3] typ = fName.split('_')[-2:] typ = typ[0] + '_' + typ[1] dirName = fName.split('_')[:-2] dName = '' for each in dirName: dName += each + '_' dirName = dName[:-1] unityPath = unityPath + '/animation/' + typ + '/' + dirName except Exception, e: pymelLogger.error('exportAnim(): Error creating UnityPath.') pymelLogger.error(e) raise Exception(e) pymelLogger.debug('File name: %s' % fileName) pymelLogger.debug('Asset path: %s' % assetPath) pymelLogger.debug('Unity path: %s' % unityPath) # Make AssetLib fbx / Unity directories if they do not exist try: if not os.path.isdir(assetPath): os.makedirs(assetPath) if not os.path.isdir(unityPath): os.makedirs(unityPath) except Exception, e: pymelLogger.error('exportAnim(): Error creating directory.') pymelLogger.error(e) raise Exception(e)
def _constrainSHToControls(): pymelLogger.debug('Starting: _constrainSHToControls()...') # Neck pm.parentConstraint(Names.controls_neck[0],'Neck',mo=1) # Neck1 pm.parentConstraint(Names.controls_neck[1],'Neck1',mo=1) pymelLogger.debug('End: _constrainSHToControls()...')
def _constrainSHToControls(): pymelLogger.debug('Starting: _constrainSHToControls()...') # Neck pm.parentConstraint(Names.controls_neck[0], 'Neck', mo=1) # Neck1 pm.parentConstraint(Names.controls_neck[1], 'Neck1', mo=1) pymelLogger.debug('End: _constrainSHToControls()...')
def build(): ''' Make Head and Face controls, parented to Neck ''' pymelLogger.debug('Starting: build()...') _makeControls() _constrainLocsToControls() _addFacePoseAttrs() _constrainSpaces() pymelLogger.debug('End: build()...')
def createJnts( side=None, fingerJnts=None, hasEndJnt=None): pymelLogger.debug('Starting: createJnts()...') startJnts = [] endJnts = [] attNames = [] originalJnts = [] newJnts = [] for jnt in fingerJnts: # if jnt exists on the scene save it on list otherwise continue searching if pm.objExists( jnt[0] ): topJnt = pm.ls(jnt[0],r=1)[0] newJntChain = pm.duplicate(topJnt,rr=True,po=False, name= topJnt + '_' + Names.suffixes['fk'] )[0] newJntChain.setParent(world=1) startJnts.append( newJntChain ) # getting name for attr "index, thumb ..." noSuf = newJntChain.split('_' + Names.suffixes['fk'])[0] endPart = noSuf[noSuf.rfind(side + Names.joints_hf[0]):] # if more than 9 jnts, it will break!!!!! endPre = len( side + Names.joints_hf[0] ) attNames.append( endPart[endPre: -1 ].replace('|','') ) newChildJnts = newJntChain.listRelatives(ad=1) end = newChildJnts[0] # rename all the new jnts! for nJnt in newChildJnts: nJnt.rename(nJnt+'_'+Names.suffixes['fk']) newChildJnts.append( newJntChain ) newJnts.append(newChildJnts) oldChildJnts = topJnt.listRelatives(ad=1) oldChildJnts.append( topJnt ) originalJnts.append(oldChildJnts) # if no child will break!!!! if hasEndJnt == 1:endJnts.append( end.getParent() ) else: endJnts.append( end ) else: continue newJnts.reverse() originalJnts.reverse() rList = [ startJnts, endJnts, attNames, newJnts, originalJnts ] pymelLogger.debug('End: createJnts()...') return rList
def _connectToSH(newJnts, originalJnts): pymelLogger.debug('Starting: connectToSH()...') for nJnts, oriJnts in zip(newJnts, originalJnts): for jntS, jntT in zip(nJnts, oriJnts): try: pm.parentConstraint(jntS, jntT, mo=1) except: print 'Could not constraint: ' + jntS, jntT pymelLogger.debug('End: connectToSH()...')
def __init__(self): ''' Export asset/rig/animation/camera as FBX to AssetLib and Unity directory. ''' self.rootList = rig_names.rootList self.assetTypes = asset_names.types self.camNames = cam_names.shot_cam_names self.geo = 'geo' self.custom = 'custom' pymelLogger.debug('Initializing...')
def connectToSH(source_jnts, torso_jnts): pymelLogger.debug('Starting: connectToSH()...') for jntS, jntT in zip(source_jnts, torso_jnts): try: pm.parentConstraint(jntS, jntT, mo=1) except: print 'Could not constraint: ' + jntS, jntT pymelLogger.debug('End: connectToSH()...')
def _cleanUp( hand_grp ): pymelLogger.debug('Starting: _cleanUp()...') # parent side+hand to hands group if not pm.objExists( Names.hands_module ): hands_module = pm.group( em=1, name=Names.hands_module ) hands_module.setParent( Names.modules_grp ) else: hands_module = pm.ls( Names.hands_module, r=1 )[0] hand_grp.setParent(hands_module) pymelLogger.debug('End: _cleanUp()...')
def _cleanUp(hand_grp): pymelLogger.debug('Starting: _cleanUp()...') # parent side+hand to hands group if not pm.objExists(Names.hands_module): hands_module = pm.group(em=1, name=Names.hands_module) hands_module.setParent(Names.modules_grp) else: hands_module = pm.ls(Names.hands_module, r=1)[0] hand_grp.setParent(hands_module) pymelLogger.debug('End: _cleanUp()...')
def build(side=None): pymelLogger.debug('Starting: build()...') if side == None: raise Exception('Make sure side: %s is valid ' % side) if side != Names.prefixes['left'] and side != Names.prefixes['right']: raise Exception('Make sure side: %s is valid ' % side) # create hand jnt handJntList = _createHandJnt(side) # [handJnt, handJntName] handJnt = handJntList[0] handJntSH = handJntList[1] # create hand switch ctrl = handJntSH + '_' + Names.suffixes['switch'] hand_switch_offset = Control.create(name=ctrl, offsets=1, shape='cube', size=[1, 1, 1], color=_getSideColor(side), pos=None, parent=handJnt, typ='body') hand_switch_offset.setParent(world=1) hand_switch = hand_switch_offset.getChildren()[ 0] # it will work only with one offset hideLockAttr(hand_switch, lockHideTRSV) # add switch attr pm.addAttr(hand_switch, longName=Names.switchIkFk, k=True, min=0, max=1) # parentConstraint switch offset to sh handJnt !!!! Make sure it will work pm.parentConstraint(handJntSH, hand_switch_offset, mo=True) # build fingers Finger.build(side=side, label='Fingers', control=hand_switch, parentJnt=handJnt, curl='Z', twist='X', spread='Y', fkNormal=(1.0, 0.0, 0.0), radius=0.3) # group switch and hand hand_grp = pm.group(hand_switch_offset, handJnt, name=handJntSH + '_' + Names.suffixes['group']) _cleanUp(hand_grp) pymelLogger.debug('End: build()...')
def exportAsset(self, fileName=None, assetPath=None, unityPath=None, ignore=None): ''' Export Assets from a .ma animation file as .fbx. ''' pymelLogger.debug('exportAsset(): Starting...') exporter = Export.Export() if not os.path.isfile(fileName): msg = 'File does not exist: %s'%fileName pymelLogger.error(msg) raise Exception(msg) # Open the file pm.openFile(fileName, f=True) pymelLogger.debug('exportAsset(): Opened file: %s'%fileName) # Export the Asset results = None results = exporter.exportAsset(fileName=fileName, assetPath=assetPath, unityPath=unityPath, ignore=ignore) if not results: msg = 'exportAsset(): Nothing exported!' pymelLogger.error(msg) raise Exception(e) for each in results: pymelLogger.debug('Exported: %s'%os.path.basename(each)) pymelLogger.debug('exportAsset(): End.') return results
def batchExportAnims(self, directory=None, unityPath=None): ''' Export rig and/or prop animation from a directories .ma files as .fbx. ''' pymelLogger.debug('batchExportAnims(): Starting...') if not os.path.isdir(directory): msg ='batchExportAnims(): %s is not a valid directory'%directory pymelLogger.debug(msg) raise Exception(msg) results = [] for root,dirs,files in os.walk(directory): for f in files: if '.svn' in root: #pymelLogger.debug('batchExportAsset(): Skipping directory: %s'%root) continue if 'incrementalSave' in root: #pymelLogger.debug('batchExportAsset(): Skipping directory: %s'%root) continue if f.endswith('.ma'): fileName = os.path.join(root,f) results.append( self.exportAnim(fileName=fileName, assetPath=os.path.dirname(fileName)+'/fbx',unityPath=unityPath) ) pymelLogger.debug('batchExportAnims(): End.') results = list(chain.from_iterable(results)) results = list(chain.from_iterable(results)) for each in results: pymelLogger.debug('Batch Exported: %s'%os.path.basename(each)) return results
def _createHandJnt( side ): pymelLogger.debug('Starting: _createHandJnt()...') handJntName = side + Names.joints_hf[0] handSHJnt = pm.ls(handJntName,r=1)[0] if not handSHJnt: raise 'Hand Jnt could not be found, make sure naming is correct and jnt exists' handJnt = handSHJnt.duplicate(rr=True,po=True, name = handJntName + '_' + Names.suffixes['attach'])[0] handJnt.setParent(world=True) handJnt.setAttr('radius',1) rList = [handJnt, handSHJnt] return rList pymelLogger.debug('End: _createHandJnt()...')
def exportAsset(self, fileName=None, assetPath=None, unityPath=None, ignore=None): """ Export 'custom' group geo and SH skeleton. """ pymelLogger.debug('Starting: exportAsset()...') # Export to directories with type and asset file name print unityPath print assetPath found = False for typ in self.assetTypes: platform = sys.platform if 'win' in platform: #pathElems = assetPath.split(os.sep) pathElems = assetPath.split('/') else: if '/' in assetPath: pathElems = assetPath.split('/') else: pathElems = assetPath.split('\\') if typ in pathElems: pymelLogger.debug('exportAsset(): Type: %s' % typ) unityPath = unityPath + '/%s/' % typ + os.path.basename( assetPath[:-4]) found = True break if not found: msg = 'exportAsset(): Asset is not in a directory named after a type.' pymelLogger.error(msg) raise Exception(msg) pymelLogger.debug('File name: %s' % fileName) pymelLogger.debug('Asset path: %s' % assetPath) pymelLogger.debug('Unity path: %s' % unityPath) # Make AssetLib fbx / Unity directories if they do not exist try: if not os.path.isdir(assetPath): os.makedirs(assetPath) if not os.path.isdir(unityPath): os.makedirs(unityPath) except Exception, e: pymelLogger.error('exportAsset(): Error creating directory.') pymelLogger.error(e) raise Exception(e)
def _getCharNodeCurves(): pymelLogger.debug('Starting: getCharNodeCurves()...') # get characterNodes Curves charNodes = pm.ls(Names.character_nodes) controlList = [] for cn in charNodes: cnAttrs = cn.listAttr(ud=1) # listing only user defined attrs for attr in cnAttrs: attrCon = attr.listConnections() if attrCon: controlList.append(attrCon[0]) pymelLogger.debug('End: getCharNodeCurves()...') return controlList
def _connectToHandJnt(handJnt, newJnts, offsetGrps): pymelLogger.debug('Starting: _connectToHandJnt()...') print offsetGrps for nJnts, oGrps in zip(newJnts, offsetGrps): nJnts[-1].setParent(handJnt) oGrps[0].setParent(handJnt) # for now we will be parentconstraining sh jnt to handjnt # later on it should be attached to the follow handJntSH = handJnt[:handJnt.rfind('_' + Names.suffixes['attach'])] pm.parentConstraint(handJntSH, handJnt, mo=1) pymelLogger.debug('End: _connectToHandJnt()...')
def _extractCurves(controlList): pymelLogger.debug('Starting: _extractCurves()...') # create grp to place curves crvsExpGrp = pm.group(em=1, name='curvesExport') for cnt in controlList: nameori = cnt.name() newCnt = cnt.duplicate()[0] if len(newCnt.getChildren()) > 1: for child in newCnt.getChildren(): if not child == newCnt.getShape(): pm.delete(child) newCnt.setParent(crvsExpGrp) newCnt.rename(name=nameori + '_export') pymelLogger.debug('End: _extractCurves()...')
def importCurve(crvName): ''' Import curve ''' pymelLogger.debug('Starting: importCurve()...') # checkfile exists # import file into scene path = templates + crvName + '.ma' if os.path.exists(path): pm.importFile(path) # return crv pm obj crv = pm.ls(crvName, r=1)[0] pymelLogger.debug('End: importCurve()...') return crv else: return invalidFile
def _extractCurves( controlList ): pymelLogger.debug('Starting: _extractCurves()...') # create grp to place curves crvsExpGrp = pm.group(em=1, name='curvesExport') for cnt in controlList: nameori = cnt.name() newCnt = cnt.duplicate()[0] if len( newCnt.getChildren() ) > 1: for child in newCnt.getChildren(): if not child == newCnt.getShape(): pm.delete(child) newCnt.setParent(crvsExpGrp) newCnt.rename(name=nameori+'_export') pymelLogger.debug('End: _extractCurves()...')
def build(side=None): pymelLogger.debug('Starting: build()...') # Define names if side == Names.prefixes['left']: follow_chain = [ '%s%s_%s' % (Names.prefixes['left'], jnt, Names.suffixes['follow']) for jnt in Names.joints_arm ] fk_chain = [ '%s%s_%s' % (Names.prefixes['left'], jnt, Names.suffixes['fk']) for jnt in Names.joints_arm ] ik_chain = [ '%s%s_%s' % (Names.prefixes['left'], jnt, Names.suffixes['ik']) for jnt in Names.joints_arm ] fkControls = Names.controls_leftArmFk ikControls = Names.controls_leftArmIk if side == Names.prefixes['right']: follow_chain = [ '%s%s_%s' % (Names.prefixes['right'], jnt, Names.suffixes['follow']) for jnt in Names.joints_arm ] fk_chain = [ '%s%s_%s' % (Names.prefixes['right'], jnt, Names.suffixes['fk']) for jnt in Names.joints_arm ] ik_chain = [ '%s%s_%s' % (Names.prefixes['right'], jnt, Names.suffixes['ik']) for jnt in Names.joints_arm ] fkControls = Names.controls_rightArmFk ikControls = Names.controls_rightArmIk # Build functions topOffsetNode = _makeFkControls(fkControls=fkControls, side=side) # topOffsetNode _cleanUp(topOffsetNode) #_makeIkControls(ikControls=ikControls) #_makeJoints(side=side, fkChain=fk_chain, ikChain=ik_chain) #_makeFkRig(side=side, fkChain=fk_chain) #_makeIkRig(side=side, ikChain=ik_chain) #_bindFollowChain(followChain=follow_chain, fkChain=fk_chain, ikChain=ik_chain) pymelLogger.debug('End: build()...')
def PRINT(msg='', item='', type='info'): printMsg = '|| %s || %s' %(msg.ljust(65), item.ljust(20)) if type == 'debug': pymelLogger.debug('\t\t\t%s'%printMsg) elif type == 'info': pymelLogger.info('\t\t\t%s'%printMsg) elif type == 'warning': pymelLogger.warning('\t%s'%printMsg) elif type == 'error': pymelLogger.error('\t%s'%printMsg) elif type == 'critical': pymelLogger.critical('\t%s'%printMsg) else: pymelLogger.error('Cannot Print Message: Invalid Type') return
def _createHandJnt(side): pymelLogger.debug('Starting: _createHandJnt()...') handJntName = side + Names.joints_hf[0] handSHJnt = pm.ls(handJntName, r=1)[0] if not handSHJnt: raise 'Hand Jnt could not be found, make sure naming is correct and jnt exists' handJnt = handSHJnt.duplicate(rr=True, po=True, name=handJntName + '_' + Names.suffixes['attach'])[0] handJnt.setParent(world=True) handJnt.setAttr('radius', 1) rList = [handJnt, handSHJnt] return rList pymelLogger.debug('End: _createHandJnt()...')
def _exportCurvesFile(): pymelLogger.debug('Starting: _exportCurvesFile()...') result = pm.promptDialog(title='Curves Files Name',message='Enter Name:',button=['OK', 'Cancel'], defaultButton='OK',cancelButton='Cancel',dismissString='Cancel') if result == 'OK': fileName = pm.promptDialog(query=True, text=True) else: raise 'Curves not exported because No name was passed' if os.path.exists(curvesFolder): pm.select('curvesExport', r=1) pm.exportSelected(curvesFolder + fileName, type='mayaAscii', f=1) pm.delete('curvesExport') else: raise 'Path to curves folder does no exist!' pymelLogger.debug('Starting: _exportCurvesFile()...')
def _makeIkControls(ikControls=None): pymelLogger.debug('Starting: _makeIkControls()...') for ctrl in ikControls: if 'IK' in ctrl: if Names.prefixes['left'] in ctrl: parent = '%s%s'%(Names.prefixes['left'],Names.joints_arm[-1]) if Names.prefixes['right'] in ctrl: parent = '%s%s'%(Names.prefixes['right'],Names.joints_arm[-1]) topNode = Control.create( name=ctrl, offsets=3, shape='circle_01', size=None, color=None, pos=None, parent=parent, typ='body' ) pm.parent(topNode, 'controls') if 'PV' in ctrl: pass pymelLogger.debug('End: _makeIkControls()...')
def bodyCtrlSetUp(fkJnts, hips_cnt, shoulder_cnt, drvStart): pymelLogger.debug('Starting: bodyCtrlSetUp()...') # Body control pos = pm.xform(hips_cnt, q=1, ws=1, rp=1) body_cnt_offset = Control.create(name=Names.controls_torso_cog, offsets=1, shape='circle_2_arrow', size=[1, 1, 1], color='darkBlue', pos=pos, parent=None, typ='body') body_cnt = body_cnt_offset.listRelatives(ad=1)[0].getParent() # position and freeze #rootPos = pm.xform(drvStart[0], query = True, translation = True) #body_cnt.setTranslation(rootPos) #pm.makeIdentity(body_cnt, apply=True) # Change rotation order cc_body #setRotateOrder(body_cnt, 2) # Lock and Hide Scale - Vis hideLockAttr(body_cnt, lockHideSV) # Parent torso_baseJnt to cc_body (CAREFUL!!! If no FKControls created this will not work now!!!!) pm.parent(fkJnts[0], body_cnt) # Group cc_jc_hip and parent it to torso_baseJnt (We group it first to keep de cc zeroed out) grp_cc_hip = pm.group(hips_cnt, name=Names.torso_hips_grp) pm.parent(grp_cc_hip, fkJnts[0]) # Group cc_jc_shoulder and parent it to torso_endJnt (We group it first to keep de cc zeroed out) grp_cc_shoulder = pm.group(shoulder_cnt, name=Names.torso_shoulders_grp) pm.parent(grp_cc_shoulder, fkJnts[-1]) # Lock and Hide Attr groups created hideLockAttr(grp_cc_hip, lockHideTRSV) hideLockAttr(grp_cc_shoulder, lockHideTRSV) pymelLogger.debug('End: bodyCtrlSetUp()...') return body_cnt_offset
def _exportCurvesFile(): pymelLogger.debug('Starting: _exportCurvesFile()...') result = pm.promptDialog(title='Curves Files Name', message='Enter Name:', button=['OK', 'Cancel'], defaultButton='OK', cancelButton='Cancel', dismissString='Cancel') if result == 'OK': fileName = pm.promptDialog(query=True, text=True) else: raise 'Curves not exported because No name was passed' if os.path.exists(curvesFolder): pm.select('curvesExport', r=1) pm.exportSelected(curvesFolder + fileName, type='mayaAscii', f=1) pm.delete('curvesExport') else: raise 'Path to curves folder does no exist!' pymelLogger.debug('Starting: _exportCurvesFile()...')