MetaFusion/scripts/dna_utils.py

208 lines
6.7 KiB
Python
Raw Normal View History

2025-02-04 16:58:34 +08:00
#!/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()
2025-02-04 22:09:11 +08:00
plugin_loaded = load_dna_plugin()
# 全局变量
dna = None
dnacalib = None
2025-02-04 16:58:34 +08:00
try:
2025-02-04 22:09:11 +08:00
# 确保 PYDNA_PATH 在 sys.path 中
if data.PYDNA_PATH not in sys.path:
sys.path.append(data.PYDNA_PATH)
# 导入 DNA 模块
from dna import *
2025-02-04 16:58:34 +08:00
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}")
class DNAManager:
def __init__(self):
self.current_dna = None
self.reader = None
self.writer = None
2025-02-04 22:09:11 +08:00
def is_ready(self):
"""检查DNA模块是否可用"""
return dna is not None and dnacalib is not None
2025-02-04 16:58:34 +08:00
def load_dna(self, file_path):
"""载入DNA文件"""
2025-02-04 22:09:11 +08:00
if not self.is_ready():
cmds.warning("DNA模块未正确加载")
return False
2025-02-04 16:58:34 +08:00
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)
2025-02-04 22:09:11 +08:00
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