Advertisement
Flynny85

Simple FBX Exporter for Maya

Sep 21st, 2016
480
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 33.85 KB | None | 0 0
  1. import maya.cmds as cmds
  2. import os
  3. import maya.mel as mel
  4.  
  5. Width_Height_Open = [ 250 , 50 ]
  6. Red_Btn_Col = ( .73 , .29 , .29 )
  7. Bright_Red_Btn_Col = ( 1 , .2 , .2 )
  8. Yel_Btn_Col = ( .84 , .76 , .31 )
  9. Art_Btn_Col = ( .50 , .80 , .50 )
  10. Anims_Btn_Col = ( .50 , .60 , .70 )
  11. Misc_Btn_Col = ( .80 , .50 , .50 )
  12. Grn_Btn_Col = ( .34 , .76 , .31 )
  13. Drk_Grey = [ .3 , .3 , .3 ]
  14. Lte_Grey = [ .47 , .45 , .45 ]
  15. global MainJntToFind   
  16. MainJntToFind = str( 'bjRoot')
  17.  
  18. """ Change Log:
  19.  
  20. # 2/4/2014: Updated exporter to remove scale nodes from the scene before exporting rig ( stops squished rigs.. )
  21.  
  22. """
  23. global CurrentPath_full
  24. CurrentPath_full = ''
  25. BodyPartListToRemove = [ 'default' , 'm_npc_' , 'm_char_' ]
  26. Bits_To_Del = [ '*tmXML*' , '*Guide*' , '*Snap*' , '*deleteme*'] # items deleted from the scene before export to make sure the fbx is clean.
  27.  
  28. def init():
  29.     FBXExport_Win()
  30.    
  31. def FBXExport_Win_TmpMode_On():
  32.     cmds.rowColumnLayout( 'FBXExport_MainWin' , edit=True , bgc= ( .1 , .1 , .1 ) )
  33.     cmds.rowColumnLayout( 'FBXExport_Btns' , edit = True , vis=False ) 
  34.     cmds.rowColumnLayout( 'FBXExport_List_title' , edit = True , vis=False )   
  35.     cmds.scrollLayout( 'FBXExport_List_scroll' , edit = True , vis=False )     
  36.     cmds.frameLayout( 'FBXExport_Prop_OptsTab' , edit = True , vis=False ) 
  37.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col' , edit = True , vis=False )      
  38.     cmds.button(  'btn_TmpMode_1' , bgc = Bright_Red_Btn_Col , label='You are in a temporary file...' , parent = 'FBXExport_MainWin' ,  command = 'FBXExport_Win_TmpMode_OpenFile()' )
  39.     cmds.button(  'btn_TmpMode_2' , bgc = Bright_Red_Btn_Col , label='..click here to reload the actual file?' , parent = 'FBXExport_MainWin' , command = 'FBXExport_Win_TmpMode_OpenFile()' )
  40.    
  41. def FBXExport_Win_TmpMode_Off():   
  42.     cmds.rowColumnLayout( 'FBXExport_MainWin' , edit=True , bgc= Drk_Grey )
  43.     cmds.rowColumnLayout( 'FBXExport_Btns' , edit = True , vis=True )  
  44.     cmds.rowColumnLayout( 'FBXExport_List_title' , edit = True , vis=True )
  45.     cmds.scrollLayout( 'FBXExport_List_scroll' , edit = True , vis=True )      
  46.     cmds.frameLayout( 'FBXExport_Prop_OptsTab' , edit = True , vis=True )  
  47.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col' , edit = True , vis=True )       
  48.     buttons_todel1 = cmds.button(  'btn_TmpMode_1' , exists=True  )
  49.     if buttons_todel1 is True:
  50.         cmds.deleteUI( 'btn_TmpMode_1' )
  51.         cmds.deleteUI( 'btn_TmpMode_2' )
  52.     else:
  53.         pass
  54.  
  55. def FBXExport_Win_TmpMode_OpenFile():
  56.     global Current_File
  57.     cmds.file( Current_File , o=True , f=True)
  58.     FBXExport_Win_TmpMode_Off()
  59.    
  60. def FBXExport_Win_ExportPathUpdate():   #edits the path button
  61.     global CurrentPath_full
  62.     CurrentPath = cmds.button( 'FBXExport_Prop_PathBtn' , query = True , label = True )
  63.     if CurrentPath is 'Export Meshs to :- (directory path )' :
  64.         CurrentPath = ''
  65.         CurrentPath_full = ''
  66.     else:
  67.         pass
  68.     tmp = cmds.fileDialog2( dir = CurrentPath , dialogStyle = 1 , fm = 3 )
  69.    
  70.     if tmp is None:
  71.         pass
  72.     else:
  73.         cmds.button( 'FBXExport_Prop_PathBtn' , edit = True , label = tmp[0] , width = Width_Height_Open[0]  , ann = tmp[0] )
  74.         CurrentPath_full = tmp[0]
  75.  
  76. def FBXExport_Win_ListUpdate_ADD():
  77.     Current_Sel = Items_Selected_BW()
  78.     if len(Current_Sel) < 1:
  79.         pass
  80.     else:
  81.         tmp = cmds.text( 'FBXExport_ItemsTxtAll' , query = True , label = True )
  82.         cmds.select( clear=True )
  83.         if tmp is None:
  84.             pass
  85.         else:
  86.             if len(tmp) < 1:
  87.                 pass
  88.             else:
  89.                 Current_In_List = tmp.split('@')
  90.                 for x in Current_In_List:
  91.                     if x is '':
  92.                         pass
  93.                     else:
  94.                         cmds.select( x , add=True )
  95.         cmds.select( Current_Sel , add=True  ) 
  96.         Items_List = cmds.ls( selection=True )
  97.         Items_List_String = '@'.join( Items_List )
  98.         cmds.text( 'FBXExport_ItemsTxtAll' , edit = True , label = Items_List_String )
  99.         FBXExport_Win_ListUpdate_Updater( Items_List )
  100.  
  101. def FBXExport_Win_ListUpdate_REM():
  102.     Current_Sel = Items_Selected_BW()
  103.     if len(Current_Sel) < 1:
  104.         pass
  105.     else:
  106.         tmp = cmds.text( 'FBXExport_ItemsTxtAll' , query = True , label = True )
  107.         cmds.select( clear=True )
  108.         if tmp is None:
  109.             pass
  110.         else:
  111.             Current_In_List = tmp.split('@')
  112.             if len(Current_In_List) < 2:
  113.                 pass
  114.             else:
  115.                 cmds.select( clear=True )
  116.                 cmds.select( Current_In_List , add=True )
  117.         cmds.select( Current_Sel , deselect=True  )
  118.         Items_List = cmds.ls( selection=True )
  119.         Items_List_String = '@'.join( Items_List )
  120.         cmds.text( 'FBXExport_ItemsTxtAll' , edit = True , label = Items_List_String )
  121.         FBXExport_Win_ListUpdate_Updater( Items_List )
  122.  
  123. def FBXExport_Win_ListUpdate_CLR():
  124.     cmds.text( 'FBXExport_ItemsTxtAll' , edit = True , label = '' )
  125.     OldBtns = cmds.rowColumnLayout( 'FBXExport_List' , query =True , ca=True ) 
  126.     if OldBtns is None:
  127.         pass
  128.     else:
  129.         for x in OldBtns:
  130.             cmds.deleteUI(x)
  131.         cmds.scrollLayout( 'FBXExport_List_scroll' , edit=True , h= 10 , vis=False )
  132.     global Glbl_MeshList
  133.     Glbl_MeshList = []
  134.  
  135. def FBXExport_Win_ListUpdate_Updater( list ):  
  136.     MaxHeight = 250
  137.     OldBtns = cmds.rowColumnLayout( 'FBXExport_List' , query =True , ca=True ) 
  138.     if OldBtns is None:
  139.         pass
  140.     else:
  141.         for x in OldBtns:
  142.             cmds.deleteUI(x)
  143.     Char_Lengths = []
  144.     for x in list:
  145.         Char_Lengths.append( (len(x)) )
  146.        
  147.     print OldBtns
  148.     if len(Char_Lengths) < 1:
  149.         Val = 10
  150.         adder = 1
  151.     else:
  152.         Char_Lengths.sort( reverse=True )
  153.         Val = (sum(Char_Lengths) / len(Char_Lengths))
  154.         adder = 1
  155.     cmds.deleteUI( 'FBXExport_List' )
  156.     if Val < 20:
  157.         if Val < 15:
  158.             if Val < 10:
  159.                 cmds.rowColumnLayout( 'FBXExport_List' , numberOfColumns=4 , width = Width_Height_Open[0] , parent = 'FBXExport_List_scroll' ) 
  160.                 adder = 4
  161.             else:
  162.                 cmds.rowColumnLayout( 'FBXExport_List' , numberOfColumns=3 , width = Width_Height_Open[0] , parent = 'FBXExport_List_scroll' ) 
  163.                 adder = 3
  164.         else:
  165.             cmds.rowColumnLayout( 'FBXExport_List' , numberOfColumns=2 , width = Width_Height_Open[0] , parent = 'FBXExport_List_scroll' ) 
  166.             adder = 2
  167.     else:
  168.         cmds.rowColumnLayout( 'FBXExport_List' , numberOfColumns=1 , width = Width_Height_Open[0] , parent = 'FBXExport_List_scroll' ) 
  169.     count = 0
  170.     while count < len(list):
  171.         count+=adder
  172.     Num_Rows = ( count / adder )
  173.     Scroll_Height = ( (Num_Rows * 20) + 20 )
  174.     if Scroll_Height < MaxHeight :
  175.         cmds.scrollLayout( 'FBXExport_List_scroll' , edit=True , h= Scroll_Height , vis=True ) 
  176.     else:
  177.         cmds.scrollLayout( 'FBXExport_List_scroll' , edit=True , h= MaxHeight , vis=True )
  178.     count = .3 
  179.     for x in list:
  180.         print x
  181.         print ( "BtnItem_SelectForMe(" + x + ")" )
  182.         cmds.button( x , bgc = [ 0.5 , count , 0.3 ], label = x , parent = 'FBXExport_List' , command =  'BtnItem_SelectForMe("' + x + '")'  )
  183.         if count < .6:
  184.             count+=.1
  185.         else:
  186.             count = .3
  187.  
  188.     global Glbl_MeshList
  189.     Glbl_MeshList = list
  190.     # FBXExport_Win_TagAtr( 'Read' )
  191.  
  192. def BtnItem_SelectForMe( Item ):
  193.     print 'fired'
  194.     print
  195.     cmds.select( clear = True )
  196.     cmds.select( Item )
  197.  
  198. def Items_Selected_BW():    #returns selected + error msgs 
  199.     selcted= []
  200.     selcted = cmds.ls( selection=True , transforms = True )
  201.     if selcted is None:
  202.         pass
  203.     else:
  204.         return selcted 
  205.    
  206. def Find_User_PathForTmp():
  207.     User_Path = ''
  208.     pass    #for now just going to give direct path above
  209.     Script_Dir_Test = cmds.internalVar( uwd =True)
  210.     if 'Library/Preferences/' in Script_Dir_Test:
  211.         pass #Mac address!
  212.         tmp = Script_Dir_Test.split( 'Library' )
  213.         User_Path = Script_Dir_Test
  214.     else:
  215.         pass #must be pc address...
  216.         tmp = Script_Dir_Test.split( 'maya' )
  217.         User_Path = Script_Dir_Test
  218.     print (  "Saving temp Location :- \n" + User_Path + "\n" )   # doesnt seem to be firing
  219.     return User_Path
  220.  
  221. def CleanUpProc():
  222.     global Current_File
  223.     Current_File = FileImporter()   #imports all refs in scene and saves to tmp location, returns this address
  224.     FBX_UnitsSettings()
  225.    
  226. def FBX_UnitsSettings():
  227.     pass #sort maya units 1st!
  228.     cmds.currentUnit( linear='cm' , t='ntsc' ) #sets units as meter and time as 30fps ntsc
  229.     # cmds.currentUnit( linear='cm' , t='game' ) #sets units as meter and time as 30fps ntsc   
  230.     # cmds.currentUnit( linear='cm' , t='ntsc' ) #sets units as meter and time as 30fps ntsc   
  231.     # cmds.currentUnit( linear='m' , t='ntsc' ) #sets units as meter and time as 30fps ntsc
  232.     pass    #set settings
  233.     mel.eval('FBXResetExport')
  234.     mel.eval('FBXExportFileVersion "FBX200900"')
  235.     mel.eval('FBXExportInputConnections -v 1')
  236.     mel.eval('FBXExportUseSceneName -v true')
  237.     mel.eval('FBXExportAnimationOnly -v false')
  238.     mel.eval('FBXExportSmoothingGroups -v true')
  239.     mel.eval('FBXExportSmoothMesh -v true')    
  240.     mel.eval('FBXExportSkins -v true')     
  241.     mel.eval('FBXExportEmbeddedTextures -v false')
  242.     mel.eval('FBXExportScaleFactor 1.0')
  243.     # mel.eval('FBXExportGenerateLog -v false')
  244.  
  245. def Export_Opt_Prop():
  246.     ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=False )   # export entire scene, use scene name
  247.     BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=False )   # export bodyparts
  248.     AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=False )    #export meshes AND animations
  249.     IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=False )
  250.     # FBXExport_Win_TagAtr( 'Export' )
  251.     MeshTrigger()
  252.    
  253. def Export_Opt_PropAnim():
  254.     ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=False )   # export entire scene, use scene name
  255.     BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=False )   # export bodyparts
  256.     AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=True ) #export meshes AND animations
  257.     IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=True )
  258.     # FBXExport_Win_TagAtr( 'Export' )
  259.     MeshTrigger()
  260.    
  261. def Export_Opt_Char():
  262.     global Glbl_MeshList
  263.     #check weights are fine first!
  264.     test = getSkinWeights()
  265.     print ( 'test = ' + str(test) )
  266.     if test is 0:
  267.         ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=True )    # export entire scene, use scene name
  268.         BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=True )    # export bodyparts
  269.         AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=True ) #export meshes AND animations
  270.         IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=False )
  271.         AnimTrigger()
  272.     else:
  273.         cmds.warning( 'see warning! stopping export.' )
  274.  
  275. def Export_Opt_CharAnimNoMesh():
  276.     ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=False )   # export entire scene, use scene name
  277.     BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=False )   # export bodyparts
  278.     AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=False )    #export meshes AND animations
  279.     IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=False )
  280.     # FBXExport_Win_TagAtr( 'Export' )
  281.     AnimTrigger()
  282.  
  283. def Export_Opt_CharAnimAndMesh():
  284.     global Glbl_MeshList
  285.     #check weights are fine first!
  286.     test = getSkinWeights()
  287.     print ( 'test = ' + str(test) )
  288.     if test is 0:
  289.         ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=False )   # export entire scene, use scene name
  290.         BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=False )   # export bodyparts
  291.         AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=True ) #export meshes AND animations
  292.         IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=False )
  293.         # FBXExport_Win_TagAtr( 'Export' )
  294.         AnimTrigger()
  295.     else:
  296.         cmds.warning( 'see warning! stopping export..' )   
  297.  
  298.    
  299. def Export_Opt_CharBodyParts():
  300.     global Glbl_MeshList
  301.     test = getSkinWeights()
  302.     print ( 'test = ' + str(test) )
  303.     if test is 0:
  304.         # FBXExport_Win_TagAtr( 'Export' )
  305.         for x in Glbl_MeshList:
  306.             cmds.select( x )
  307.             ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , edit=True , value=False )   # export entire scene, use scene name
  308.             BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , edit=True , value=True )    # export bodyparts
  309.             AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , edit=True , value=False )    #export meshes AND animations
  310.             IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , edit=True , value=False )
  311.             MeshTrigger()
  312.     else:
  313.         cmds.warning( 'see warning! stopping export...' )      
  314.    
  315. def FBXExport_Win_CenteredItems():         
  316.     global Glbl_MeshList
  317.     CenterCheck_Val = cmds.checkBox( 'FBXExport_Check_Center' , query=True , value=True )
  318.     if CenterCheck_Val is True:
  319.         cmds.select( clear =True )
  320.         Newgroup = cmds.group( em=True, name= 'CenterGrp_Wrld'  )
  321.         for x in Glbl_MeshList:
  322.             cmds.select( clear =True )
  323.             NewCons = cmds.parentConstraint( Newgroup , x ,  mo=False)
  324.             cmds.select( clear =True )
  325.             cmds.select( NewCons )
  326.             cmds.Delete()  
  327.         cmds.select( Newgroup )
  328.         cmds.Delete()          
  329.         cmds.select( clear=True )
  330.     else:
  331.         pass
  332.    
  333. def FBXExport_Win_IsAnimated():    
  334.     IsAnimated_Val = cmds.checkBox( 'FBXExport_Check_ISAnimated' , query=True , value=True )
  335.     if IsAnimated_Val is True:
  336.         FBX_UnitsSettings()
  337.         mel.eval('FBXProperty Export|IncludeGrp|Animation -v true;')
  338.         Time_Start = cmds.playbackOptions(query=True , minTime=True)
  339.         Time_End = cmds.playbackOptions(query=True , maxTime=True)
  340.         mel.eval('FBXExportBakeComplexAnimation -v true;')
  341.         mel.eval('FBXExportBakeComplexStart -v ' + str(Time_Start) + ';')
  342.         mel.eval('FBXExportBakeComplexEnd -v ' + str(Time_End) + ';')      
  343.        
  344.     else:
  345.         FBX_UnitsSettings()
  346.         mel.eval('FBXExportInputConnections -v 0;')            
  347.         mel.eval('FBXExportAnimationOnly -v false;')               
  348.         mel.eval('FBXProperty Export|IncludeGrp|Animation -v false;')
  349.         mel.eval('FBXExportSkins -v false')
  350.    
  351. def FBXExport_Win_ExportAll()
  352.     global Current_File
  353.     global Glbl_MeshList
  354.     global CurrentPath_full
  355.     ExportAll_Val = cmds.checkBox( 'FBXExport_Check_ExportAll' , query=True , value=True ) 
  356.     if ExportAll_Val is True:
  357.         print 'exporting using scene name instead of mesh/parts'
  358.         FileName = FileNameStrip()
  359.         tmp = ( CurrentPath_full + '\\' + FileName + '.Fbx' )
  360.         FinalPath_Mixed = tmp.replace('\\' , '/')
  361.         start = 'FBXExport -f '
  362.         end = ' -s' #only export selected part/toggle
  363.         print (  start + '"' + FinalPath_Mixed + '"' + ';')
  364.         cmds.select( Glbl_MeshList )
  365.         import maya.mel as mel
  366.         mel.eval(  start + '"' + FinalPath_Mixed + '"' + end + ';')
  367.         # mel.eval(  start + '"' + FinalPath_Mixed + '"' + ';')    
  368.     else:
  369.         BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , query=True , value=True ) 
  370.         if BodyParts_Val is True:
  371.             print 'doing body parts'
  372.             FBXExport_Win_ExportBodyParts()
  373.         else:
  374.             print 'exporting each mesh/parts'
  375.             for x in Glbl_MeshList:
  376.                 tmp33 = NameStrip( x ) 
  377.                 PropName_Val = cmds.checkBox( 'FBXExport_Check_DontAddProp_Name' , query=True , value=True )   
  378.                 if PropName_Val is True:
  379.                     ItemName = tmp33
  380.                 else:
  381.                     tmp44 = tmp33.replace( 'prop_' , '' )
  382.                     ItemName = tmp44.replace( 'm_' , 'prop_' )
  383.                 tmp = ( CurrentPath_full + '\\' + ItemName + '.Fbx' )
  384.                 FinalPath_Mixed = tmp.replace('\\' , '/')
  385.                 start = 'FBXExport -f '
  386.                 end = ' -s' #only export selected part/toggle
  387.                 print (  start + '"' + FinalPath_Mixed + '"' + ';')
  388.                 cmds.select( x )
  389.                 import maya.mel as mel
  390.                 mel.eval(  start + '"' + FinalPath_Mixed + '"' + end + ';')
  391.  
  392. def FBXExport_Win_ReLoadFile():
  393.     global Current_File
  394.     Reload_Val = cmds.checkBox( 'FBXExport_Check_ReOpen' , query=True , value=True )   
  395.     if Reload_Val is False:
  396.         cmds.file( Current_File , o=True , f=True)
  397.         FBXExport_Win_TmpMode_Off()
  398.     else:
  399.         FBXExport_Win_TmpMode_On()
  400.    
  401. def getSkinWeights():
  402.     ''' Get the weights per vertex on the meshName with the skinClusterName'''
  403.     MaxValue_Infs = cmds.intSliderGrp( 'FBXExport_MaxInfluences' , query=True , v=True )   
  404.     global Glbl_MeshList
  405.     #check weights are fine first!
  406.     Test_Verts = []
  407.     for x in Glbl_MeshList:
  408.         mesh = x
  409.         cmds.select( clear=True )
  410.         cmds.select( x )
  411.         mel.eval ('$mesh = "%s";' % (mesh))
  412.         skinClusterName = mel.eval('findRelatedSkinCluster($mesh);')
  413.         if len(skinClusterName) < 1:
  414.             print 'no skin cluster found, passing'# return 0
  415.         else:
  416.             weights = []
  417.             cmds.skinPercent( skinClusterName , mesh , pruneWeights=0.015 )
  418.             # get the Influence Objects
  419.             influenceObjects = cmds.skinCluster(skinClusterName, q=True, weightedInfluence=True)
  420.             # get the size of the vertex weight list
  421.             weightListSize = cmds.getAttr(skinClusterName + ".weightList", size=True)
  422.             # build weight dictionary
  423.             for vertexId in range(0,weightListSize):
  424.                 # to store vertex weights
  425.                 vertexWeights = {}
  426.                 for influenceId in range(len(influenceObjects)):
  427.                     weight = cmds.getAttr(skinClusterName + ".weightList[%d].weights[%d]" % (vertexId,influenceId))
  428.                     #print weight
  429.                     # only store non-zero weights
  430.                     if weight != 0:
  431.                         vertexWeights[influenceId] = weight
  432.                 # store the weights for the vertex id
  433.                 if len(vertexWeights) > MaxValue_Infs :
  434.                     BadVert = ( str(mesh) + '.vtx[' + str(vertexId) + ']' )
  435.                     weights.append( BadVert )
  436.                 else:
  437.                     pass
  438.             if len(weights) < 1:
  439.                 print ( 'all weight influences are fine on ' + x + '\n')
  440.             else:
  441.                 cmds.warning ( 'there are  ' + str(len(weights)) + '  vertexs with weights beyond what you have selected in the exporter on .. ' + x  )
  442.                 for y in weights:
  443.                     Test_Verts.append(y)
  444.     if len(Test_Verts) > 1:
  445.         print len(Test_Verts)
  446.         cmds.select( Test_Verts )
  447.         return Test_Verts
  448.     else:
  449.         return 0
  450.  
  451. def FileNameStrip():
  452.     global Current_File
  453.     tmp = Current_File.split('/')  
  454.     tmp2 = tmp[-1]
  455.     tmp3 = tmp2.split('.')
  456.     tmp4 = tmp3[0]
  457.     return tmp4.lower()
  458.    
  459. def NameStrip( Item ):
  460.     tmp = Item.split(':')  
  461.     tmp2 = tmp[-1]
  462.     tmp3 = tmp2.replace( '|' , '' )
  463.     return tmp3.lower()
  464.    
  465. def BodyPartClean( Item ):
  466.     Item = NameStrip( Item )
  467.     for x in BodyPartListToRemove:
  468.         Item = Item.replace( x , '' )
  469.     return Item.lower()
  470.  
  471. def BodyPartClean_Numerix( Item ):
  472.     import re
  473.     Item_cleaned = re.sub('[^a-z_]','',Item)
  474.     return Item_cleaned
  475.        
  476. def FileCheck_Exists( file_ToLoad ) :
  477.     Exists_test = cmds.file( file_ToLoad , q=True, ex=True )
  478.     if Exists_test is True:
  479.         return True
  480.     else:
  481.         os.makedirs( file_ToLoad )
  482.         return False
  483.        
  484. def MeshTrigger():
  485.     global CurrentPath_full
  486.     if CurrentPath_full is '':
  487.         print 'path not found'
  488.         FBXExport_Win_ExportPathUpdate()
  489.     else:
  490.         print 'path found moving on.'
  491.     global Current_File
  492.     global Glbl_MeshList
  493.     ## here needs a pause to check user saved file?!
  494.     _userChose = cmds.confirmDialog( title='Have you saved?!', message=( 'Are you sure you have saved, unsaved changes will be lost ' + os.environ['USER'] + '?'), button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
  495.     if _userChose == 'Yes':
  496.         FBXExport_Win_TagAtr( 'Export' )
  497.         FBXExport_Win_TmpMode_On()
  498.         CleanUpProc()  
  499.         FBXExport_Win_CenteredItems()
  500.         FBXExport_Win_IsAnimated()
  501.         FBXExport_Win_ExportAll()
  502.         FBXExport_Win_ReLoadFile()
  503.    
  504. def AnimExport_NoMesh():
  505.     AnimNOMesh_Val = cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , query=True , value=True )
  506.     if AnimNOMesh_Val is True:
  507.         BodyParts_Val = cmds.checkBox( 'FBXExport_Check_BodyParts' , query=True , value=True ) 
  508.         if BodyParts_Val is True:
  509.             mel.eval('FBXProperty Export|IncludeGrp|Animation -v false;')
  510.             print 'keeping anims and meshes' #used for exporting incidental creature anims
  511.         else:
  512.             mel.eval('FBXProperty Export|IncludeGrp|Animation -v true;') #used for exporting character setup meshes with no anims.
  513.         global Glbl_MeshList
  514.         print Glbl_MeshList
  515.         if len(Glbl_MeshList) < 1:
  516.             pass
  517.         else:
  518.             for x in Glbl_MeshList:
  519.                 print x
  520.                 try:
  521.                     cmds.parent( x , world=True )
  522.                 except:
  523.                     print ( 'error selecting ' + x )
  524.             tmp = cmds.ls( ( '*' + MainJntToFind ) , r=True , type='joint' )   
  525.             if len(tmp) > 0:
  526.                 cmds.select(clear=True)
  527.                 cmds.select( ado=True )
  528.                 cmds.select( tmp[0] , deselect=True)
  529.             for x in Glbl_MeshList:
  530.                 try:           
  531.                     cmds.select(  x , deselect=True)
  532.                 except:
  533.                     print ( 'error selecting for scene clean up ' + x )
  534.             cmds.delete()
  535.     else:
  536.         tmp = cmds.ls( ( '*' + MainJntToFind ) , r=True , type='joint' )       
  537.         if len(tmp) > 0:
  538.             cmds.select(clear=True)
  539.             cmds.select(ado=True)
  540.             cmds.select( tmp[0] , deselect=True)
  541.             cmds.delete()
  542.         print 'removing meshes from scene before export!'
  543.     CleanUpper()
  544.  
  545. def AnimTrigger():
  546.     global CurrentPath_full
  547.     if CurrentPath_full is '':
  548.         print 'path not found'
  549.         FBXExport_Win_ExportPathUpdate()
  550.     else:
  551.         print 'path found moving on.'
  552.     global Current_File
  553.     global Glbl_MeshList
  554.     FBXExport_Win_TagAtr( 'Export' )
  555.     ## here needs a pause to check user saved file?!
  556.     _userChose = cmds.confirmDialog( title='Have you saved?!', message=( 'Are you sure you have saved, unsaved changes will be lost ' + os.environ['USER'] + '?'), button=['Yes','No'], defaultButton='Yes', cancelButton='No', dismissString='No' )
  557.     if _userChose == 'Yes':
  558.         FBXExport_Win_TagAtr( 'Export' )
  559.         FBXExport_Win_TmpMode_On()
  560.         CleanUpProc()   #imports all ref files and sets maya units
  561.         Export_Baker_Cmd() #bake down rig model
  562.         CleanUpper()
  563.         FileName = FileNameStrip()
  564.         FileClean = BodyPartClean( FileName )
  565.         AnimExport_NoMesh()
  566.         tmp = ( CurrentPath_full + '\\' + FileName + '.Fbx' )
  567.         FinalPath_Mixed = tmp.replace('\\' , '/')
  568.         start = 'FBXExport -f '
  569.         print (  start + '"' + FinalPath_Mixed + '"' + ';')
  570.         mel.eval(  start + '"' + FinalPath_Mixed + '"' + ';')
  571.         FBXExport_Win_ReLoadFile()
  572.    
  573. def CleanUpper():
  574.     for x in Bits_To_Del:
  575.         tmp = cmds.ls( x , r=True )
  576.         if tmp is None:
  577.             pass
  578.         else:
  579.             if len(tmp) < 1:
  580.                 pass
  581.             else:
  582.                 cmds.select( clear=True )
  583.                 cmds.select( tmp )
  584.                 cmds.delete()
  585.  
  586. def FBXExport_Win_TagAtr( type ):  
  587.     global CurrentPath_full
  588.  
  589.  
  590. def FileCheck_Exists_Importer( file_ToLoad ):
  591.     Exists_test = cmds.file( file_ToLoad , q=True, ex=True )
  592.     if Exists_test is True:
  593.         return True
  594.     else:
  595.         print file_ToLoad
  596.         return False
  597.    
  598. def FileImporter():     #looks for any refferance files and imports all..
  599.     global Current_File
  600.     Current_File = ''
  601.     Save_File = ''
  602.     global File_Tmp_Location_Export
  603.     tmp = cmds.file( sn=True , query=True)
  604.     tmp2 = tmp.split('/')
  605.     File_Tmp_Location_Export = tmp2[-1]
  606.     File_Tmp_Location_Save = 'TmpSave.ma'   #this is the filename, can be changed
  607.     Current_File = cmds.file( sn=True , query=True)
  608.     pass    #auto save!
  609.     if len(Current_File) < 2:   #file not saved, create tmp save!!!
  610.         print Current_File
  611.     else:
  612.         print Current_File
  613.     pass# Now to break the file
  614.    
  615.     File_list = ['']
  616.     File_list = cmds.file( list=True , query=True)
  617.     if len( File_list ) > 1:
  618.         for x in File_list[1:]:
  619.             Test_MA = '.ma' in x
  620.             if Test_MA is True:
  621.                 print 'importing:'
  622.                 print x
  623.                 print '\n'
  624.                 cmds.file( x , ir=True , f=True )
  625.             else:
  626.                 pass
  627.     else:
  628.         pass
  629.     return Current_File    
  630.        
  631.        
  632. def Find_User_PathForTmp():
  633.     User_Path = ''
  634.     pass    #for now just going to give direct path above
  635.     Script_Dir_Test = cmds.internalVar( uwd =True)
  636.     if 'Library/Preferences/' in Script_Dir_Test:
  637.         pass #Mac address!
  638.         tmp = Script_Dir_Test.split( 'Library' )
  639.         User_Path = Script_Dir_Test
  640.        
  641.     else:
  642.         pass #must be pc address...
  643.         tmp = Script_Dir_Test.split( 'maya' )
  644.         User_Path = Script_Dir_Test
  645.     return User_Path
  646.        
  647.  
  648. def RenameBits():
  649.     HI_Top_Jnt= cmds.ls( ( '*' + MainJntToFind ) , type='joint' )
  650.     if len(HI_Top_Jnt) < 1:
  651.         HI_Top_Jnt= cmds.ls( ( '*:' + MainJntToFind ) , type='joint' )
  652.         if len(HI_Top_Jnt) < 1:
  653.             print 'hip joint not found, please rename to Hip_Jnt and try again'
  654.         else:
  655.             Search_Char_Rig = cmds.ls( '*:Character_Rig')
  656.             if len(Search_Char_Rig) < 1:
  657.                 print 'character rig not found, attempting basic export?'
  658.                 print ( 'Hip Jnt Found = ' + str(HI_Top_Jnt) )
  659.                 cmds.select( HI_Top_Jnt)
  660.                 cmds.pickWalk( d='up' )
  661.                 cmds.select( hi=True )
  662.                 tmp = cmds.ls( selection=True , fl=True , transforms=True )
  663.                 count = 1
  664.                 print tmp
  665.                 while count < len(tmp):
  666.                     count_r = (len(tmp) - count)
  667.                     x = tmp[count_r]
  668.                     print x
  669.                     tmp1 = x.split(':')
  670.                     tmp2 = tmp1[-1]
  671.                     cmds.select(clear=True)
  672.                     cmds.select( x )
  673.                     cmds.rename( tmp2 )
  674.                     print tmp2
  675.                     count+=1
  676.                 cmds.select(clear=True)
  677.                 cmds.select( tmp[0] )
  678.                 tmp1 = tmp[0].split(':')   
  679.                 tmp2 = tmp1[-1]
  680.                 cmds.rename( tmp2 )
  681.             else:
  682.                 cmds.select( clear=True )
  683.                 cmds.select( Search_Char_Rig )
  684.                 cmds.pickWalk( d='up' )
  685.                 cmds.select( hi=True )
  686.                 tmp = cmds.ls( selection=True , fl=True , transforms=True )
  687.                 count = 1
  688.                 while count < len(tmp):
  689.                     count_r = (len(tmp) - count)
  690.                     x = tmp[count_r]
  691.                     tmp1 = x.split(':')
  692.                     tmp2 = tmp1[-1]
  693.                     cmds.select(clear=True)
  694.                     cmds.select( x )
  695.                     cmds.rename( tmp2 )
  696.                     count+=1
  697.    
  698. def Export_Baker_Cmd():
  699.     RenameBits()
  700.     global Character_Stripped
  701.     Character_Stripped = False
  702.     HI_Top_Jnt= cmds.ls( ( '*' + MainJntToFind ) , type='joint' )
  703.     if len(HI_Top_Jnt) <1:
  704.         print 'Character Rig not found, possibly renamed or not in the scene?'
  705.     else:
  706.         pass    #Find out if it has a parent? it should do!
  707.         Parent_Test = cmds.listRelatives( HI_Top_Jnt[0] , parent=True )
  708.         if Parent_Test is None:
  709.             cmds.currentTime(1)
  710.             print 'parent not found, baking as is on hips.'
  711.         else:      
  712.             cmds.currentTime(1)
  713.             cmds.parent( HI_Top_Jnt[0] , world = True) 
  714.         cmds.select(HI_Top_Jnt[0] , hi = True )
  715.         tmp = cmds.ls( selection = True )
  716.        
  717.         for x in tmp:
  718.             channels = [ 'tx' , 'ty' , 'tz' , 'rx' , 'ry' , 'rz' , 'sx' , 'sy' , 'sz' ]
  719.             for chan in channels:
  720.                 cmds.setAttr( ( x + '.' + chan ) , k = True )
  721.  
  722.         cmds.select( clear = True )
  723.         cmds.select( HI_Top_Jnt[0] , hi = True )                   
  724.         Time_Start = cmds.playbackOptions(query=True , minTime=True)
  725.         Time_End = cmds.playbackOptions(query=True , maxTime=True)
  726.         cmds.bakeResults( time= ( Time_Start , Time_End) , simulation=True )
  727.         cmds.select(HI_Top_Jnt[0] , hi=True )
  728.         tmp = cmds.ls(selection=True)
  729.         print tmp
  730.         for x in tmp:
  731.             cmds.select(clear=True)
  732.             cmds.select(x)     
  733.             test_Joint = cmds.objectType(x)
  734.             if test_Joint == 'joint':
  735.                 pass
  736.             else:
  737.                 print 'deleting'
  738.                 print x
  739.                 cmds.delete(x)
  740.         pass #Find the meshes!
  741.         MeshList = cmds.ls( '*Mesh' , type='transform' )
  742.         if MeshList is None:
  743.             pass
  744.         else:
  745.             if len(MeshList)> 0:
  746.                 Parent_Test = cmds.listRelatives( MeshList[0] , parent=True )
  747.                 if Parent_Test is None:
  748.                     pass
  749.                 else:              
  750.                     cmds.parent( MeshList[0] , world=True)
  751.                     cmds.select( MeshList[0] )
  752.                     cmds.select( hi=True )
  753.                     cmds.select( MeshList[0] , deselect=True )
  754.                     ALL_Bits_Shapes = cmds.ls( selection=True , shapes=True )
  755.                     for x in ALL_Bits_Shapes:
  756.                         cmds.select( clear=True )
  757.                         cmds.select( x )
  758.                         Transform = cmds.pickWalk(d='up')
  759.                         cmds.parent( Transform , world=True)   
  760.                     cmds.delete(MeshList[0])           
  761.             else:
  762.                 print 'no meshes found?'
  763.         pass #Cleanup time!
  764.         pass # find all scale nodes and delete first!
  765.         Time_Begin = cmds.playbackOptions(query=True , minTime=True)
  766.         cmds.currentTime( Time_Begin )
  767.        
  768.         AllScaleNodes = cmds.ls( type = 'blendColors' )
  769.         if len( AllScaleNodes ) > 0:
  770.             cmds.delete( AllScaleNodes )
  771.         ToDel = cmds.ls( '*Character_Rig')
  772.         if len(ToDel) < 1:
  773.             pass
  774.         else:  
  775.             Parent_Test = cmds.listRelatives( ToDel[0] , parent=True )
  776.             if Parent_Test is None:
  777.                 pass
  778.             else:      
  779.                 if ToDel is None:
  780.                     pass
  781.                     print 'nothing to delete'
  782.                 else:
  783.                     cmds.delete( Parent_Test[0] )
  784.                     cmds.currentTime(1)
  785.         Character_Stripped = True
  786.     tmpfile = cmds.file( sn=True , query=True)     
  787.  
  788.  
  789. def FBXExport_Win():
  790.     FBXExport_Win = "FBXExport_Win"
  791.  
  792.     if cmds.window('FBXExport_Win', exists=True):
  793.         cmds.deleteUI('FBXExport_Win', window=True)
  794.         cmds.windowPref( 'FBXExport_Win', remove=True )
  795.     cmds.window( 'FBXExport_Win' ,  rtf=True , toolbox=True , widthHeight = Width_Height_Open )
  796.    
  797.     cmds.rowColumnLayout( 'FBXExport_MainWin' , numberOfColumns=1 , width = Width_Height_Open[0] , bgc= Drk_Grey ) 
  798.     cmds.text( label= '-: FBX Exporter :- ' , align='center' , parent = 'FBXExport_MainWin' , width = Width_Height_Open[0] )       
  799.  
  800.     cmds.rowColumnLayout( 'FBXExport_Btns' , numberOfColumns=3 , width = Width_Height_Open[0] , parent = 'FBXExport_MainWin' ) 
  801.     cmds.button( 'FBXExport_Prop_AddBtn' , bgc = Grn_Btn_Col , label='Add' , width = (Width_Height_Open[0] / 3) , parent = 'FBXExport_Btns' , command = 'FBXExport_Win_ListUpdate_ADD()')
  802.     cmds.button( 'FBXExport_Prop_RemBtn' , bgc = Yel_Btn_Col , label='Remove' , width = (Width_Height_Open[0] / 3) , parent = 'FBXExport_Btns' , command = 'FBXExport_Win_ListUpdate_REM()')
  803.     cmds.button( 'FBXExport_Prop_ClrBtn' , bgc = Red_Btn_Col , label='Clear List' , width = (Width_Height_Open[0] / 3) , parent = 'FBXExport_Btns' , command = 'FBXExport_Win_ListUpdate_CLR()')
  804.  
  805.     cmds.rowColumnLayout( 'FBXExport_List_title' , numberOfColumns=1 , width = Width_Height_Open[0] , parent = 'FBXExport_MainWin' )   
  806.     cmds.button( 'FBXExport_Prop_PathBtn' , bgc= Lte_Grey , label='Export Meshs to :- (directory path )'  , parent = 'FBXExport_List_title' , command = 'FBXExport_Win_ExportPathUpdate()' )   
  807.     cmds.setParent()
  808.     cmds.scrollLayout( 'FBXExport_List_scroll' , parent = 'FBXExport_MainWin' , h= 10 , cr=True , vis=False)       
  809.     cmds.rowColumnLayout( 'FBXExport_List' , numberOfColumns=2 , width = Width_Height_Open[0] , parent = 'FBXExport_List_scroll' ) 
  810.     cmds.setParent()
  811.  
  812.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col' , numberOfColumns=1 , width = Width_Height_Open[0] , parent = 'FBXExport_MainWin' )  
  813.    
  814.     cmds.text( label= '-: Export Art :- ' , parent = 'FBXExport_Btns_Export_Col' , align='center' , width = Width_Height_Open[0] )     
  815.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col2' , numberOfColumns=2 , width = Width_Height_Open[0] , parent = 'FBXExport_Btns_Export_Col' ) 
  816.     cmds.button(  label='Prop / Mesh' , bgc= Art_Btn_Col , parent = 'FBXExport_Btns_Export_Col2' , width = ( Width_Height_Open[0] / 2 ) , command = 'Export_Opt_Prop()' )
  817.     cmds.button(  label='Character Rigged' , bgc= Art_Btn_Col , parent = 'FBXExport_Btns_Export_Col2' , width = ( Width_Height_Open[0] / 2 ) , command = 'Export_Opt_Char()' )
  818.     cmds.setParent()
  819.    
  820.     cmds.text( label= '-: Export Animation :- ' , parent = 'FBXExport_Btns_Export_Col' , align='center' , width = Width_Height_Open[0] )   
  821.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col3' , numberOfColumns=2 , width = Width_Height_Open[0] , parent = 'FBXExport_Btns_Export_Col' ) 
  822.  
  823.     cmds.button(  label='Animated Mesh (rigid)' , bgc= Anims_Btn_Col , parent = 'FBXExport_Btns_Export_Col3' , width = ( Width_Height_Open[0] / 2 ) , command = 'Export_Opt_PropAnim()' )
  824.     cmds.button(  label='Char Joint Anim only' , bgc= Anims_Btn_Col , parent = 'FBXExport_Btns_Export_Col3' , width = ( Width_Height_Open[0] / 2 ) , command = 'Export_Opt_CharAnimNoMesh()' )
  825.     cmds.button(  label='Char and Mesh Anim' , bgc= Anims_Btn_Col , parent = 'FBXExport_Btns_Export_Col3' , width = ( Width_Height_Open[0] / 2 ) , command = 'Export_Opt_CharAnimAndMesh()' )
  826.     cmds.setParent()
  827.  
  828.     cmds.text( label= '-: Misc :- ' , parent = 'FBXExport_Btns_Export_Col' , align='center' , width = Width_Height_Open[0] )       
  829.     cmds.rowColumnLayout( 'FBXExport_Btns_Export_Col4' , numberOfColumns=2 , width = Width_Height_Open[0] , parent = 'FBXExport_Btns_Export_Col' ) 
  830.     cmds.setParent()
  831.     #misc section..
  832.     cmds.frameLayout( 'FBXExport_Prop_OptsTab' , label = 'extra options' , vis=True , cll=True , cl =True , parent='FBXExport_MainWin' , width = Width_Height_Open[0] )
  833.     cmds.rowColumnLayout( 'FBXExport_Prop_OptsTab_col' , numberOfColumns=1 , width = Width_Height_Open[0] , parent = 'FBXExport_Prop_OptsTab' )
  834.     cmds.checkBox( 'FBXExport_Check_Center' , label='Center Each Mesh to world zero and export.' , parent = 'FBXExport_Prop_OptsTab_col' , ann= 'Check this for all items to be batch exported to be moved to 0,0,0 before the process.' )
  835.     # cmds.checkBox( 'FBXExport_Check_OptInForPath' , label='Use last known path automaticly for export' , parent = 'FBXExport_Prop_OptsTab_col'  )
  836.     cmds.intSliderGrp( 'FBXExport_MaxInfluences' , field=True , label='Vert Influences allowed' , max=4 , min=1 , v=3 )
  837.     cmds.checkBox( 'FBXExport_Check_ReOpen' , label='Dont Reload the Maya file after export.' , ann= 'Check this to force the file to not reload (leaves you in the tmp broken file, good for debugging).' )
  838.     # cmds.button(  label='TagMainJnt' , bgc= Anims_Btn_Col , parent = 'FBXExport_Prop_OptsTab_col' , width = ( Width_Height_Open[0] / 2 ) , command = 'TagRig()' )
  839.     #misc section thats hidden!
  840.     cmds.frameLayout( 'FBXExport_Prop_OptsTab1' , label = 'extra options' , vis=False , cll=True , cl =True , parent='FBXExport_MainWin' , width = Width_Height_Open[0] )
  841.     cmds.rowColumnLayout( 'FBXExport_Prop_OptsTab_col1' , numberOfColumns=1 , width = Width_Height_Open[0] , parent = 'FBXExport_Prop_OptsTab' )   
  842.     cmds.checkBox( 'FBXExport_Check_ISAnimated' , vis=False , label='Is an animated prop / mesh (without joints)' , parent = 'FBXExport_Prop_OptsTab_col1' , ann= 'Check this if the prop/mesh is animated.' )
  843.     cmds.checkBox( 'FBXExport_Check_ExportAll' , vis=False , label='Export entire scene (Use scene name instead).' , parent = 'FBXExport_Prop_OptsTab_col1' , ann= 'Check this to export the entire scene rather than indidual FBX files.' )
  844.     cmds.checkBox( 'FBXExport_Check_BodyParts' , vis=False , label='Meshs are Char/ BodyParts (no animation exported)' , parent = 'FBXExport_Prop_OptsTab_col1' , ann= 'Check this to export the Char/NPC body part meshes which use a different naming scheme...' )
  845.     cmds.checkBox( 'FBXExport_Check_KeepAnimMeshes' , vis=False , label='Preserve Mesh data in Anim export.' , parent = 'FBXExport_Prop_OptsTab_col1' , ann= 'Check this if you dont want the meshes being deleted from the anim export (makes file larger).' )
  846.     cmds.checkBox( 'FBXExport_Check_DontAddProp_Name' , v = 1 , vis= False , label='Use mesh name as filename (Otherwise m_ replaced with prop..).' , parent = 'FBXExport_Prop_OptsTab_col' , ann= 'Check this if you dont want the file name being changed from m_ to prop_ instead...' )
  847.     cmds.text( 'FBXExport_ItemsTxtAll' , vis = False , label = '' , parent = 'FBXExport_Prop_OptsTab_col1' , width = ( Width_Height_Open[0] ) )    
  848.     cmds.showWindow( 'FBXExport_Win' ) 
  849.    
  850. FBXExport_Win()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement