MetaFusion/scripts/dna_utils.py
2025-02-05 02:10:47 +08:00

175 lines
5.7 KiB
Python

#!/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 = data.MAYA_VERSION
PYDNA_PATH = data.PYDNA_PATH
PLUGIN_PATH = data.PLUGIN_PATH
def load_dna_plugin():
"""安全加载插件"""
plugins = [
("dnacalib.py", "dnacalib"),
("embeddedRL4.mll", "embeddedRL4"),
("MayaUERBFPlugin.mll", "MayaUERBFPlugin")
]
for file_name, plugin_name in plugins:
try:
plugin_path = os.path.join(data.PLUGIN_PATH, file_name)
if not os.path.exists(plugin_path):
cmds.warning(f"⚠️ 插件文件缺失: {file_name}")
continue
if cmds.pluginInfo(plugin_name, q=True, loaded=True):
print(f"✅ 已加载: {plugin_name}")
continue
cmds.loadPlugin(plugin_path)
print(f"✔️ 成功加载: {plugin_name}")
except Exception as e:
cmds.warning(f"❌ 加载失败 {plugin_name}: {str(e)}")
class DNAManager:
def __init__(self):
self.current_dna = None
self.reader = None
self.writer = None
def is_ready(self):
"""检查DNA模块是否可用"""
return dna is not None and dnacalib is not None
def load_dna(self, file_path):
"""载入DNA文件"""
if not self.is_ready():
cmds.warning("DNA模块未正确加载")
return False
try:
# 创建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
def import_settings(self, file_path):
"""导入 DNA 设置"""
try:
if not self.is_ready():
raise ImportError("DNA模块未正确加载")
# TODO: 实现导入设置逻辑
return True
except Exception as e:
cmds.warning(f"导入设置失败: {str(e)}")
return False
def export_settings(self, file_path):
"""导出 DNA 设置"""
try:
if not self.is_ready():
raise ImportError("DNA模块未正确加载")
# TODO: 实现导出设置逻辑
return True
except Exception as e:
cmds.warning(f"导出设置失败: {str(e)}")
return False