#!/usr/bin/env python # -*- coding: utf-8 -*- """ 版权所有: 清泉时代科技有限公司 联系方式: q.100@qq.com 创建日期: 2024/03/01 """ import os import maya.cmds as cmds import maya.mel as mel def sg_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=sg_export_head_check_command ) cmds.button( label=labels['ExportHeadFBX'], align="center", command=lambda x: sg_export_head_command() ) cmds.setParent('..') cmds.button( label=labels['ExportSelectHeadFBX'], align="center", command=lambda x: sg_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=sg_export_body_check_command ) cmds.button( label=labels['ExportBodyFBX'], align="center", command=lambda x: sg_export_body_command() ) cmds.setParent('..') cmds.button( label=labels['ExportSelectBodyFBX'], align="center", command=lambda x: sg_export_select_body_command() ) # 创建分隔符 cmds.separator(height=10, style="in") # 显示窗口 cmds.showWindow('exportFBXWin') def get_ui_labels(): """获取UI标签""" is_chinese = cmds.SGDescriptor(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 sg_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 sg_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 sg_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 sg_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 # 重命名混合变形 mel.eval('SGRenameBlendShapes') # 获取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 = cmds.SGDescriptor(p=True) name = cmds.SGDescriptor(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) sg_export_fbx(file_path) else: cmds.error(f'"{export_grp}" No geometry found within the group...') # 重置混合变形 mel.eval('SGResetBlendShapes') # 打开输出文件夹 folder_path = cmds.SGDescriptor(p=True).replace('/', '\\') os.system(f'explorer "{folder_path}"') def sg_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 # 重命名混合变形 mel.eval('SGRenameBlendShapes') # 导出选中物体 cmds.select(clear=True) cmds.select(selection, replace=True) cmds.select('DHIhead:root', add=True) path = cmds.SGDescriptor(p=True) name = cmds.SGDescriptor(n=True) file_path = f"{path}/{name}_lod_head.fbx" sg_export_fbx(file_path) # 重置混合变形 mel.eval('SGResetBlendShapes') # 打开输出文件夹 folder_path = cmds.SGDescriptor(p=True).replace('/', '\\') os.system(f'explorer "{folder_path}"') def sg_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 = cmds.SGDescriptor(p=True) name = cmds.SGDescriptor(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) sg_export_fbx(file_path) else: cmds.error(f'"{export_grp}" No geometry found within the group...') # 打开输出文件夹 folder_path = cmds.SGDescriptor(p=True).replace('/', '\\') os.system(f'explorer "{folder_path}"') def sg_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 = cmds.SGDescriptor(p=True) name = cmds.SGDescriptor(n=True) file_path = f"{path}/{name}_lod_body.fbx" sg_export_fbx(file_path) # 打开输出文件夹 folder_path = cmds.SGDescriptor(p=True).replace('/', '\\') os.system(f'explorer "{folder_path}"')