Update
This commit is contained in:
Jeffreytsai1004 2025-02-04 16:58:34 +08:00
parent a184583eff
commit 0da0b5a1b0
3 changed files with 300 additions and 4 deletions

View File

@ -10,6 +10,7 @@ ROOT_DIR = os.path.dirname(os.path.dirname(__file__))
if ROOT_DIR not in sys.path: if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR) sys.path.insert(0, ROOT_DIR)
from config import data from config import data
from dna_utils import DNAManager
QtCore, QtGui, QtWidgets = data.Qt() QtCore, QtGui, QtWidgets = data.Qt()
#===================================== 2. Global Variables ===================================== #===================================== 2. Global Variables =====================================
@ -123,22 +124,123 @@ class MetaFusionWindow(QtWidgets.QMainWindow):
def setup_model_tab(self): def setup_model_tab(self):
"""设置模型标签页内容""" """设置模型标签页内容"""
layout = QtWidgets.QVBoxLayout(self.model_tab) layout = QtWidgets.QVBoxLayout(self.model_tab)
# 在这里添加模型标签页的具体控件
# 添加模型列表
model_list = QtWidgets.QListWidget()
layout.addWidget(model_list)
# 添加按钮组
button_layout = QtWidgets.QHBoxLayout()
import_btn = QtWidgets.QPushButton("导入模型")
export_btn = QtWidgets.QPushButton("导出模型")
button_layout.addWidget(import_btn)
button_layout.addWidget(export_btn)
layout.addLayout(button_layout)
def setup_rig_tab(self): def setup_rig_tab(self):
"""设置绑定标签页内容""" """设置绑定标签页内容"""
layout = QtWidgets.QVBoxLayout(self.rig_tab) layout = QtWidgets.QVBoxLayout(self.rig_tab)
# 在这里添加绑定标签页的具体控件
# 添加骨骼列表
joint_tree = QtWidgets.QTreeWidget()
joint_tree.setHeaderLabels(["骨骼", "位置"])
layout.addWidget(joint_tree)
# 添加按钮组
button_layout = QtWidgets.QHBoxLayout()
calibrate_btn = QtWidgets.QPushButton("校准骨骼")
save_btn = QtWidgets.QPushButton("保存骨骼")
button_layout.addWidget(calibrate_btn)
button_layout.addWidget(save_btn)
layout.addLayout(button_layout)
def setup_adjust_tab(self): def setup_adjust_tab(self):
"""设置调整标签页内容""" """设置调整标签页内容"""
layout = QtWidgets.QVBoxLayout(self.adjust_tab) layout = QtWidgets.QVBoxLayout(self.adjust_tab)
# 在这里添加调整标签页的具体控件
# 添加BlendShape列表
blend_list = QtWidgets.QListWidget()
layout.addWidget(blend_list)
# 添加滑块组
slider_layout = QtWidgets.QVBoxLayout()
for i in range(5):
slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
slider_layout.addWidget(slider)
layout.addLayout(slider_layout)
# 添加按钮组
button_layout = QtWidgets.QHBoxLayout()
edit_btn = QtWidgets.QPushButton("编辑BlendShape")
save_btn = QtWidgets.QPushButton("保存设置")
button_layout.addWidget(edit_btn)
button_layout.addWidget(save_btn)
layout.addLayout(button_layout)
def setup_define_tab(self): def setup_define_tab(self):
"""设置定义标签页内容""" """设置定义标签页内容"""
layout = QtWidgets.QVBoxLayout(self.define_tab) layout = QtWidgets.QVBoxLayout(self.define_tab)
# 在这里添加定义标签页的具体控件
# 添加DNA编辑区域
self.dna_edit = QtWidgets.QTextEdit()
layout.addWidget(self.dna_edit)
# 添加按钮组
button_layout = QtWidgets.QHBoxLayout()
self.load_btn = QtWidgets.QPushButton("载入DNA")
self.save_btn = QtWidgets.QPushButton("保存DNA")
self.export_btn = QtWidgets.QPushButton("导出FBX")
# 连接信号槽
self.load_btn.clicked.connect(self.on_load_dna)
self.save_btn.clicked.connect(self.on_save_dna)
self.export_btn.clicked.connect(self.on_export_fbx)
button_layout.addWidget(self.load_btn)
button_layout.addWidget(self.save_btn)
button_layout.addWidget(self.export_btn)
layout.addLayout(button_layout)
# 创建DNA管理器
self.dna_manager = DNAManager()
def on_load_dna(self):
"""处理载入DNA事件"""
file_path, _ = QtWidgets.QFileDialog.getOpenFileName(
self, "选择DNA文件", "", "DNA Files (*.dna)")
if file_path:
if self.dna_manager.load_dna(file_path):
self.dna_edit.setText(f"已加载DNA文件: {file_path}")
else:
QtWidgets.QMessageBox.warning(
self, "错误", "DNA文件加载失败")
def on_save_dna(self):
"""处理保存DNA事件"""
file_path, _ = QtWidgets.QFileDialog.getSaveFileName(
self, "保存DNA文件", "", "DNA Files (*.dna)")
if file_path:
if self.dna_manager.save_dna(file_path):
QtWidgets.QMessageBox.information(
self, "成功", "DNA文件保存成功")
else:
QtWidgets.QMessageBox.warning(
self, "错误", "DNA文件保存失败")
def on_export_fbx(self):
"""处理导出FBX事件"""
file_path, _ = QtWidgets.QFileDialog.getSaveFileName(
self, "导出FBX", "", "FBX Files (*.fbx)")
if file_path:
if self.dna_manager.export_fbx(file_path):
QtWidgets.QMessageBox.information(
self, "成功", "FBX导出成功")
else:
QtWidgets.QMessageBox.warning(
self, "错误", "FBX导出失败")
def show(): def show():
"""显示主窗口""" """显示主窗口"""

20
scripts/blend_utils.py Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
class BlendShapeManager:
def __init__(self):
self.current_blend = None
def create_blend_shape(self, base_mesh, target_mesh):
"""创建BlendShape"""
pass
def edit_blend_shape(self, blend_name):
"""编辑BlendShape"""
pass
def save_blend_shape(self, file_path):
"""保存BlendShape设置"""
pass

174
scripts/dna_utils.py Normal file
View File

@ -0,0 +1,174 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import maya.cmds as cmds
import maya.mel as mel
from config import data
# 根据Maya和Python版本获取正确的DNA模块路径
MAYA_VERSION = cmds.about(version=True)
SYSTEM_OS = "win64" if cmds.about(os=True) == "Windows" else "linux"
PYTHON_VERSION = sys.version_info
def load_dna_plugin():
"""加载DNA插件"""
try:
# 加载DNA校准插件
dna_plugin = os.path.join(data.PLUGIN_PATH, "dnacalib.py")
if not cmds.pluginInfo(dna_plugin, query=True, loaded=True):
cmds.loadPlugin(dna_plugin)
# 加载嵌入式插件
embedded_plugin = os.path.join(data.PLUGIN_PATH, "embeddedRL4.mll")
if not cmds.pluginInfo(embedded_plugin, query=True, loaded=True):
cmds.loadPlugin(embedded_plugin)
# 加载RBF插件
rbf_plugin = os.path.join(data.PLUGIN_PATH, f"MayaUERBFPlugin.mll")
if not cmds.pluginInfo(rbf_plugin, query=True, loaded=True):
cmds.loadPlugin(rbf_plugin)
return True
except Exception as e:
cmds.warning(f"加载DNA插件失败: {str(e)}")
return False
def setup_dna_path():
"""设置DNA模块路径"""
# 获取DNA插件路径
if data.PLUGIN_PATH not in sys.path:
sys.path.append(data.PLUGIN_PATH)
# 获取PyDNA路径
if data.PYDNA_PATH not in sys.path:
sys.path.append(data.PYDNA_PATH)
# 添加DLL搜索路径
if SYSTEM_OS == "win64":
os.environ["PATH"] = f"{data.PYDNA_PATH};{os.environ['PATH']}"
# 设置路径并加载插件
setup_dna_path()
if not load_dna_plugin():
cmds.warning("DNA插件加载失败某些功能可能无法使用")
try:
import dna
import dnacalib
except ImportError as e:
cmds.warning(f"无法导入DNA模块: {str(e)}")
cmds.warning(f"Python路径: {sys.path}")
cmds.warning(f"插件路径: {data.PLUGIN_PATH}")
cmds.warning(f"PyDNA路径: {data.PYDNA_PATH}")
# 不抛出异常,让界面仍然可以加载
dna = None
dnacalib = None
class DNAManager:
def __init__(self):
self.current_dna = None
self.reader = None
self.writer = None
def load_dna(self, file_path):
"""载入DNA文件"""
try:
if dna is None:
raise ImportError("DNA模块未正确加载")
# 创建DNA读取器
self.reader = dna.DNAReader()
self.reader.read(file_path)
self.current_dna = self.reader.get_dna()
return True
except Exception as e:
cmds.warning(f"DNA文件加载失败: {str(e)}")
return False
def save_dna(self, file_path):
"""保存DNA文件"""
try:
if not self.current_dna:
raise ValueError("没有DNA数据可保存")
# 创建DNA写入器
self.writer = DNAWriter()
self.writer.set_dna(self.current_dna)
self.writer.write(file_path)
return True
except Exception as e:
cmds.warning(f"DNA文件保存失败: {str(e)}")
return False
def calibrate_joints(self):
"""校准骨骼位置"""
try:
if not self.current_dna:
raise ValueError("请先加载DNA文件")
# 获取骨骼定义
joints = self.current_dna.get_joints()
# 校准每个骨骼
for joint in joints:
# 获取骨骼名称和位置
joint_name = joint.get_name()
neutral_position = joint.get_neutral_position()
# 如果Maya场景中存在该骨骼
if cmds.objExists(joint_name):
# 设置骨骼位置
cmds.xform(joint_name,
worldSpace=True,
translation=neutral_position)
return True
except Exception as e:
cmds.warning(f"骨骼校准失败: {str(e)}")
return False
def export_fbx(self, file_path):
"""导出FBX文件"""
try:
# 选择所有需要导出的对象
all_objects = self.get_export_objects()
cmds.select(all_objects)
# 设置FBX导出选项
mel.eval('FBXExportInputConnections -v true')
mel.eval('FBXExportIncludeChildren -v true')
# 导出FBX
cmds.file(file_path,
force=True,
options="v=0",
type="FBX export",
preserveReferences=True,
exportSelected=True)
return True
except Exception as e:
cmds.warning(f"FBX导出失败: {str(e)}")
return False
def get_export_objects(self):
"""获取需要导出的对象列表"""
# 获取模型、骨骼等对象
objects = []
if self.current_dna:
# 添加骨骼
joints = self.current_dna.get_joints()
for joint in joints:
joint_name = joint.get_name()
if cmds.objExists(joint_name):
objects.append(joint_name)
# 添加蒙皮模型
meshes = self.current_dna.get_meshes()
for mesh in meshes:
mesh_name = mesh.get_name()
if cmds.objExists(mesh_name):
objects.append(mesh_name)
return objects