324 lines
9.5 KiB
Python
324 lines
9.5 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import maya.cmds as cmds
|
|
import maya.mel as mel
|
|
from scripts.utils.Core import Descriptor, RenameBlendShapes, ResetBlendShapes
|
|
|
|
def export_fbx_window():
|
|
"""
|
|
创建FBX导出窗口
|
|
"""
|
|
# 检查SuperRiggingEditor窗口是否存在
|
|
if not cmds.window('SuperRiggingEditor', exists=True):
|
|
return
|
|
|
|
# 如果导出窗口已存在则删除
|
|
if cmds.window('exportFBXWin', exists=True):
|
|
cmds.deleteUI('exportFBXWin')
|
|
|
|
# 获取UI标签
|
|
labels = get_ui_labels()
|
|
|
|
# 创建窗口
|
|
cmds.window(
|
|
'exportFBXWin',
|
|
title="ExportFBX",
|
|
width=310,
|
|
height=100,
|
|
sizeable=True,
|
|
toolbox=True,
|
|
parent='SuperRiggingEditor'
|
|
)
|
|
|
|
# 创建主布局
|
|
cmds.columnLayout(
|
|
adjustableColumn=True,
|
|
columnAttach=['both', 5],
|
|
rowSpacing=2,
|
|
columnWidth=150
|
|
)
|
|
|
|
# 创建分隔符
|
|
cmds.separator(height=10, style="in")
|
|
|
|
# 创建LOD复选框组
|
|
cmds.checkBoxGrp(
|
|
'export_FBX_Check_1',
|
|
numberOfCheckBoxes=4,
|
|
labelArray4=['LOD0', 'LOD1', 'LOD2', 'LOD3'],
|
|
columnWidth4=[55, 55, 55, 55],
|
|
value1=1
|
|
)
|
|
|
|
cmds.checkBoxGrp(
|
|
'export_FBX_Check_2',
|
|
numberOfCheckBoxes=4,
|
|
labelArray4=['LOD4', 'LOD5', 'LOD6', 'LOD7'],
|
|
columnWidth4=[55, 55, 55, 55]
|
|
)
|
|
|
|
# 创建分隔符
|
|
cmds.separator(height=10, style="in")
|
|
|
|
# 创建头部导出控件
|
|
cmds.rowLayout(numberOfColumns=2, columnWidth2=[45, 20], adjustableColumn=2)
|
|
cmds.checkBox(
|
|
'check_Select_All_1',
|
|
label=labels['All'],
|
|
value=0,
|
|
changeCommand=export_head_check_command
|
|
)
|
|
cmds.button(
|
|
label=labels['ExportHeadFBX'],
|
|
align="center",
|
|
command=lambda x: export_head_command()
|
|
)
|
|
cmds.setParent('..')
|
|
|
|
cmds.button(
|
|
label=labels['ExportSelectHeadFBX'],
|
|
align="center",
|
|
command=lambda x: export_select_head_command()
|
|
)
|
|
|
|
# 创建分隔符
|
|
cmds.separator(height=10, style="in")
|
|
|
|
# 创建身体导出控件
|
|
cmds.rowLayout(numberOfColumns=2, columnWidth2=[45, 20], adjustableColumn=2)
|
|
cmds.checkBox(
|
|
'check_Select_All_2',
|
|
label=labels['All'],
|
|
value=0,
|
|
changeCommand=export_body_check_command
|
|
)
|
|
cmds.button(
|
|
label=labels['ExportBodyFBX'],
|
|
align="center",
|
|
command=lambda x: export_body_command()
|
|
)
|
|
cmds.setParent('..')
|
|
|
|
cmds.button(
|
|
label=labels['ExportSelectBodyFBX'],
|
|
align="center",
|
|
command=lambda x: export_select_body_command()
|
|
)
|
|
|
|
# 创建分隔符
|
|
cmds.separator(height=10, style="in")
|
|
|
|
# 显示窗口
|
|
cmds.showWindow('exportFBXWin')
|
|
|
|
def get_ui_labels():
|
|
"""获取UI标签"""
|
|
is_chinese = Descriptor(l=True) == "ZH"
|
|
|
|
if is_chinese:
|
|
return {
|
|
'All': '全选',
|
|
'ExportHeadFBX': '导出头部LOD到FBX',
|
|
'ExportSelectHeadFBX': '导出选择的头部到FBX',
|
|
'ExportBodyFBX': '导出身体LOD到FBX',
|
|
'ExportSelectBodyFBX': '导出选择的身体到FBX'
|
|
}
|
|
else:
|
|
return {
|
|
'All': 'All',
|
|
'ExportHeadFBX': 'Export Head LOD To FBX',
|
|
'ExportSelectHeadFBX': 'Export Select Head To FBX',
|
|
'ExportBodyFBX': 'Export Body LOD To FBX',
|
|
'ExportSelectBodyFBX': 'Export Select Body To FBX'
|
|
}
|
|
|
|
def export_fbx(file_path):
|
|
"""
|
|
导出FBX文件
|
|
|
|
参数:
|
|
file_path (str): FBX文件保存路径
|
|
"""
|
|
# 重置FBX导出设置
|
|
mel.eval('FBXResetExport')
|
|
|
|
# 设置FBX导出选项
|
|
mel.eval('FBXExportBakeComplexAnimation -v true')
|
|
mel.eval('FBXExportBakeComplexStart -v 1')
|
|
mel.eval('FBXExportBakeComplexStep -v 1')
|
|
mel.eval('FBXExportBakeComplexEnd -v 1')
|
|
mel.eval('FBXExportConstraints -v true')
|
|
mel.eval('FBXExportSkeletonDefinitions -v true')
|
|
mel.eval('FBXExportInputConnections -v true')
|
|
mel.eval('FBXExportSmoothingGroups -v true')
|
|
mel.eval('FBXExportSkins -v true')
|
|
mel.eval('FBXExportShapes -v true')
|
|
mel.eval('FBXExportCameras -v false')
|
|
mel.eval('FBXExportLights -v false')
|
|
mel.eval('FBXExportUpAxis "y"')
|
|
|
|
# 执行导出
|
|
mel.eval(f'FBXExport -f "{file_path}" -s')
|
|
print(f"{file_path}: Export completed...")
|
|
|
|
def export_head_check_command():
|
|
"""处理头部全选复选框"""
|
|
value = cmds.checkBox('check_Select_All_1', query=True, value=True)
|
|
for i in range(1, 5):
|
|
cmds.checkBoxGrp('export_FBX_Check_1', edit=True, value=[value]*4)
|
|
cmds.checkBoxGrp('export_FBX_Check_2', edit=True, value=[value]*4)
|
|
|
|
def export_body_check_command():
|
|
"""处理身体全选复选框"""
|
|
value = cmds.checkBox('check_Select_All_2', query=True, value=True)
|
|
cmds.checkBoxGrp('export_FBX_Check_1', edit=True, value=[value]*4)
|
|
|
|
def export_head_command():
|
|
"""导出头部LOD的FBX"""
|
|
# 检查并加载FBX插件
|
|
if not cmds.pluginInfo('fbxmaya', query=True, loaded=True):
|
|
cmds.loadPlugin('fbxmaya')
|
|
|
|
# 检查根关节
|
|
if not cmds.objExists('DHIhead:root'):
|
|
cmds.error('Missing "DHIhead:root" joint...')
|
|
return
|
|
|
|
# 重命名混合变形
|
|
RenameBlendShapes()
|
|
|
|
# 获取LOD选择状态
|
|
lods = []
|
|
for i in range(4):
|
|
lods.append(cmds.checkBoxGrp('export_FBX_Check_1', query=True, value1=True))
|
|
for i in range(4):
|
|
lods.append(cmds.checkBoxGrp('export_FBX_Check_2', query=True, value1=True))
|
|
|
|
# 导出每个选中的LOD
|
|
for i, is_selected in enumerate(lods):
|
|
if is_selected:
|
|
export_grp = f"head_lod{i}_grp"
|
|
if cmds.ls(export_grp, dag=True, geometry=True):
|
|
path = Descriptor(p=True)
|
|
name = Descriptor(n=True)
|
|
file_path = f"{path}/{name}_lod{i}_head.fbx"
|
|
|
|
cmds.select(clear=True)
|
|
cmds.select(export_grp, replace=True)
|
|
cmds.select('DHIhead:root', add=True)
|
|
export_fbx(file_path)
|
|
else:
|
|
cmds.error(f'"{export_grp}" No geometry found within the group...')
|
|
|
|
# 重置混合变形
|
|
ResetBlendShapes()
|
|
|
|
# 打开输出文件夹
|
|
folder_path = Descriptor(p=True).replace('/', '\\')
|
|
os.system(f'explorer "{folder_path}"')
|
|
|
|
def export_select_head_command():
|
|
"""导出选中的头部到FBX"""
|
|
# 检查并加载FBX插件
|
|
if not cmds.pluginInfo('fbxmaya', query=True, loaded=True):
|
|
cmds.loadPlugin('fbxmaya')
|
|
|
|
# 检查根关节
|
|
if not cmds.objExists('DHIhead:root'):
|
|
cmds.error('Missing "DHIhead:root" joint...')
|
|
return
|
|
|
|
# 检查选择
|
|
selection = cmds.ls(selection=True)
|
|
if not selection:
|
|
cmds.error('Selection is empty...')
|
|
return
|
|
|
|
# 重命名混合变形
|
|
RenameBlendShapes()
|
|
|
|
# 导出选中物体
|
|
cmds.select(clear=True)
|
|
cmds.select(selection, replace=True)
|
|
cmds.select('DHIhead:root', add=True)
|
|
|
|
path = Descriptor(p=True)
|
|
name = Descriptor(n=True)
|
|
file_path = f"{path}/{name}_lod_head.fbx"
|
|
export_fbx(file_path)
|
|
|
|
# 重置混合变形
|
|
ResetBlendShapes()
|
|
|
|
# 打开输出文件夹
|
|
folder_path = Descriptor(p=True).replace('/', '\\')
|
|
os.system(f'explorer "{folder_path}"')
|
|
|
|
def export_body_command():
|
|
"""导出身体LOD的FBX"""
|
|
# 检查并加载FBX插件
|
|
if not cmds.pluginInfo('fbxmaya', query=True, loaded=True):
|
|
cmds.loadPlugin('fbxmaya')
|
|
|
|
# 检查根关节
|
|
if not cmds.objExists('DHIbody:root'):
|
|
cmds.error('Missing "DHIbody:root" joint...')
|
|
return
|
|
|
|
# 获取LOD选择状态
|
|
lods = []
|
|
for i in range(4):
|
|
lods.append(cmds.checkBoxGrp('export_FBX_Check_1', query=True, value1=True))
|
|
|
|
# 导出每个选中的LOD
|
|
for i, is_selected in enumerate(lods):
|
|
if is_selected:
|
|
export_grp = f"body_lod{i}_grp"
|
|
if cmds.ls(export_grp, dag=True, geometry=True):
|
|
path = Descriptor(p=True)
|
|
name = Descriptor(n=True)
|
|
file_path = f"{path}/{name}_lod{i}_body.fbx"
|
|
|
|
cmds.select(clear=True)
|
|
cmds.select(export_grp, replace=True)
|
|
cmds.select('DHIbody:root', add=True)
|
|
export_fbx(file_path)
|
|
else:
|
|
cmds.error(f'"{export_grp}" No geometry found within the group...')
|
|
|
|
# 打开输出文件夹
|
|
folder_path = Descriptor(p=True).replace('/', '\\')
|
|
os.system(f'explorer "{folder_path}"')
|
|
|
|
def export_select_body_command():
|
|
"""导出选中的身体到FBX"""
|
|
# 检查并加载FBX插件
|
|
if not cmds.pluginInfo('fbxmaya', query=True, loaded=True):
|
|
cmds.loadPlugin('fbxmaya')
|
|
|
|
# 检查根关节
|
|
if not cmds.objExists('DHIbody:root'):
|
|
cmds.error('Missing "DHIbody:root" joint...')
|
|
return
|
|
|
|
# 检查选择
|
|
selection = cmds.ls(selection=True)
|
|
if not selection:
|
|
cmds.error('Selection is empty...')
|
|
return
|
|
|
|
# 导出选中物体
|
|
cmds.select(clear=True)
|
|
cmds.select(selection, replace=True)
|
|
cmds.select('DHIbody:root', add=True)
|
|
|
|
path = Descriptor(p=True)
|
|
name = Descriptor(n=True)
|
|
file_path = f"{path}/{name}_lod_body.fbx"
|
|
export_fbx(file_path)
|
|
|
|
# 打开输出文件夹
|
|
folder_path = Descriptor(p=True).replace('/', '\\')
|
|
os.system(f'explorer "{folder_path}"') |