2025-02-09 20:24:08 +08:00
|
|
|
|
#!/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
#===================================== 1. Module Imports =====================================
|
|
|
|
|
import maya.OpenMayaUI as omui
|
|
|
|
|
import maya.cmds as cmds
|
|
|
|
|
import maya.mel as mel
|
|
|
|
|
import webbrowser
|
2025-02-09 21:35:41 +08:00
|
|
|
|
import datetime
|
2025-02-09 20:24:08 +08:00
|
|
|
|
import sys
|
|
|
|
|
import os
|
2025-02-10 00:59:57 +08:00
|
|
|
|
|
2025-02-11 00:04:32 +08:00
|
|
|
|
def Qt():
|
|
|
|
|
try:
|
|
|
|
|
from PySide2 import QtCore, QtGui, QtWidgets
|
|
|
|
|
from shiboken2 import wrapInstance
|
|
|
|
|
print("从PySide2加载Qt和shiboken2")
|
|
|
|
|
return QtCore, QtGui, QtWidgets, wrapInstance
|
|
|
|
|
except ImportError:
|
|
|
|
|
try:
|
|
|
|
|
from PySide6 import QtCore, QtGui, QtWidgets
|
|
|
|
|
from shiboken6 import wrapInstance
|
|
|
|
|
print("从PySide6加载Qt和shiboken6")
|
|
|
|
|
return QtCore, QtGui, QtWidgets, wrapInstance
|
|
|
|
|
except ImportError:
|
|
|
|
|
try:
|
|
|
|
|
from PySide import QtCore, QtGui, QtWidgets
|
|
|
|
|
from shiboken import wrapInstance
|
|
|
|
|
print("从PySide加载Qt和shiboken")
|
|
|
|
|
return QtCore, QtGui, QtWidgets, wrapInstance
|
|
|
|
|
except ImportError as e:
|
|
|
|
|
print(f"Qt加载失败: {str(e)}")
|
|
|
|
|
QtCore = QtGui = QtWidgets = None
|
|
|
|
|
wrapInstance = None
|
|
|
|
|
|
|
|
|
|
QtCore, QtGui, QtWidgets, wrapInstance = Qt()
|
|
|
|
|
|
|
|
|
|
if QtCore is None or QtGui is None or QtWidgets is None or wrapInstance is None:
|
|
|
|
|
print(f"Qt加载失败: {QtCore}, {QtGui}, {QtWidgets}, {wrapInstance}")
|
|
|
|
|
|
2025-02-09 23:46:33 +08:00
|
|
|
|
__version__ = "2.1.1"
|
2025-02-10 00:59:57 +08:00
|
|
|
|
|
2025-02-09 21:35:41 +08:00
|
|
|
|
# Base Information
|
|
|
|
|
TOOL_NAME = str("MetaFusion")
|
|
|
|
|
TOOL_VERSION = str("Beta v1.0.0")
|
|
|
|
|
TOOL_AUTHOR = str("CGNICO")
|
|
|
|
|
TOOL_LANG = str('en_US')
|
|
|
|
|
TOOL_WSCL_NAME = str(f"{TOOL_NAME}WorkSpaceControl")
|
|
|
|
|
TOOL_HELP_URL = str(f"https://gitea.cgnico.com/CGNICO/{TOOL_NAME}/wiki")
|
|
|
|
|
TOOL_YEAR = str(datetime.datetime.now().year)
|
|
|
|
|
|
|
|
|
|
# Tool Path
|
|
|
|
|
TOOL_PATH = str(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
2025-02-09 20:24:08 +08:00
|
|
|
|
ROOT_DIR = TOOL_PATH
|
2025-02-09 21:35:41 +08:00
|
|
|
|
ICONS_PATH = str(os.path.join(TOOL_PATH, "icons"))
|
|
|
|
|
SCRIPTS_PATH = str(os.path.join(TOOL_PATH, "scripts"))
|
|
|
|
|
TOOL_STYLE_FILE = str(os.path.join(SCRIPTS_PATH, "ui", "style.qss"))
|
|
|
|
|
# TOOLS_PATH
|
|
|
|
|
DNACALIB_PATH = str(os.path.join(TOOL_PATH, "dnacalib").replace("\\", "/"))
|
|
|
|
|
BUILDER_PATH = str(os.path.join(SCRIPTS_PATH, "builder").replace("\\", "/"))
|
|
|
|
|
DNALIB_PATH = str(os.path.join(SCRIPTS_PATH, "dnalib").replace("\\", "/"))
|
|
|
|
|
UI_PATH = str(os.path.join(SCRIPTS_PATH, "ui").replace("\\", "/"))
|
|
|
|
|
UTILS_PATH = str(os.path.join(SCRIPTS_PATH, "utils").replace("\\", "/"))
|
2025-02-09 23:46:33 +08:00
|
|
|
|
def get_system_os():
|
|
|
|
|
SYSTEM_OS = str(sys.platform)
|
|
|
|
|
"""获取系统平台"""
|
|
|
|
|
if SYSTEM_OS == "win32":
|
|
|
|
|
return "Windows"
|
|
|
|
|
elif SYSTEM_OS == "linux":
|
|
|
|
|
return "Linux"
|
|
|
|
|
elif SYSTEM_OS == "darwin":
|
|
|
|
|
return "macOS"
|
|
|
|
|
else:
|
|
|
|
|
return SYSTEM_OS
|
|
|
|
|
|
|
|
|
|
SYSTEM_OS = get_system_os()
|
|
|
|
|
|
|
|
|
|
# 使用cmds.about()获取Maya版本
|
|
|
|
|
MAYA_VERSION = str(cmds.about(version=True))
|
2025-02-09 21:35:41 +08:00
|
|
|
|
PYTHON_VERSION = str(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
|
2025-02-09 23:46:33 +08:00
|
|
|
|
|
2025-02-09 21:35:41 +08:00
|
|
|
|
def get_python_version():
|
|
|
|
|
"""获取Python版本目录名称"""
|
|
|
|
|
version = sys.version_info
|
|
|
|
|
if version.major == 3:
|
|
|
|
|
if version.minor == 9 and version.micro == 7:
|
|
|
|
|
return "python397"
|
|
|
|
|
elif version.minor == 10 and version.micro == 8:
|
|
|
|
|
return "python3108"
|
|
|
|
|
elif version.minor == 11:
|
|
|
|
|
return "python311"
|
|
|
|
|
return "python3"
|
|
|
|
|
PYTHON_VERSION_DIR = get_python_version()
|
|
|
|
|
PLUGIN_PATH = str(os.path.join(TOOL_PATH, "plugins", SYSTEM_OS, MAYA_VERSION).replace("\\", "/"))
|
|
|
|
|
PYDNA_PATH = str(os.path.join(TOOL_PATH, "plugins", SYSTEM_OS, "pydna", PYTHON_VERSION_DIR).replace("\\", "/"))
|
|
|
|
|
|
|
|
|
|
# 资源路径
|
|
|
|
|
ASSETS_PATH = str(os.path.join(TOOL_PATH, "assets").replace("\\", "/"))
|
|
|
|
|
DNA_PATH = str(os.path.join(ASSETS_PATH, "dna").replace("\\", "/"))
|
|
|
|
|
IMG_PATH = str(os.path.join(ASSETS_PATH, "img").replace("\\", "/"))
|
|
|
|
|
MAYA_PATH = str(os.path.join(ASSETS_PATH, "maya").replace("\\", "/"))
|
|
|
|
|
DNA_VERSION = str("MH.4")
|
|
|
|
|
LOD_LEVELS = range(8)
|
|
|
|
|
DEFAULT_MESH_INDICES = range(54)
|
|
|
|
|
GUI_PATH = str(os.path.join(MAYA_PATH, "gui.ma").replace("\\", "/"))
|
|
|
|
|
ASSEMBLE_SCRIPT = str(os.path.join(MAYA_PATH, "additional_assemble_script.py").replace("\\", "/"))
|
|
|
|
|
SHADER_PATH = str(os.path.join(MAYA_PATH, "shaders").replace("\\", "/"))
|
|
|
|
|
MASKS_PATH = str(os.path.join(MAYA_PATH, "masks").replace("\\", "/"))
|
|
|
|
|
MAPS_PATH = str(os.path.join(MAYA_PATH, "maps").replace("\\", "/"))
|
|
|
|
|
BODY_PATH = str(os.path.join(MAYA_PATH, "body").replace("\\", "/"))
|
|
|
|
|
# FILES
|
|
|
|
|
TOOL_MAIN_SCRIPT = str(os.path.join(SCRIPTS_PATH, f"{TOOL_NAME}.py").replace("\\", "/"))
|
|
|
|
|
TOOL_STYLE_FILE = str(os.path.join(UI_PATH, "style.qss").replace("\\", "/"))
|
|
|
|
|
TOOL_ICON = str(os.path.join(ICONS_PATH, f"{TOOL_NAME}Logo.png").replace("\\", "/"))
|
|
|
|
|
TOOL_COMMAND_ICON = str(os.path.join(ICONS_PATH, "Command.png").replace("\\", "/"))
|
|
|
|
|
TOOL_MOD_FILENAME = str(f"{TOOL_NAME}.mod")
|
|
|
|
|
|
2025-02-09 22:11:50 +08:00
|
|
|
|
# 基础路径配置
|
|
|
|
|
ROOT_PATH = os.path.dirname(os.path.dirname(__file__))
|
|
|
|
|
ASSETS_PATH = os.path.join(ROOT_PATH, "assets")
|
|
|
|
|
ICONS_PATH = os.path.join(ROOT_PATH, "icons")
|
|
|
|
|
PLUGINS_PATH = os.path.join(ROOT_PATH, "plugins")
|
|
|
|
|
|
|
|
|
|
# DNA相关路径
|
|
|
|
|
DNA_PATH = os.path.join(ASSETS_PATH, "dna")
|
|
|
|
|
MH2_PATH = os.path.join(ASSETS_PATH, "MH.2")
|
|
|
|
|
MH4_PATH = os.path.join(ASSETS_PATH, "MH.4")
|
|
|
|
|
|
|
|
|
|
# UI配置
|
|
|
|
|
UI_FONT_FAMILY = "Microsoft YaHei UI"
|
|
|
|
|
UI_FONT_SIZE = 9
|
|
|
|
|
UI_BUTTON_HEIGHT = 24
|
|
|
|
|
UI_LINE_EDIT_HEIGHT = 24
|
|
|
|
|
|
|
|
|
|
# 颜色配置
|
|
|
|
|
UI_COLORS = {
|
|
|
|
|
"primary": "#2D2D30",
|
|
|
|
|
"secondary": "#3E3E42",
|
|
|
|
|
"accent": "#007ACC",
|
|
|
|
|
"text": "#FFFFFF",
|
|
|
|
|
"text_disabled": "#656565",
|
|
|
|
|
"border": "#434346",
|
|
|
|
|
"button_hover": "#404045",
|
|
|
|
|
"button_pressed": "#007ACC"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# LOD配置
|
|
|
|
|
LOD_MESHES = {
|
2025-02-11 00:10:44 +08:00
|
|
|
|
"LOD0": ["*头部", "*牙齿", "牙龈", "*左眼", "*右眼", "虹膜", "睫毛", "眼睑", "软骨", "身体"],
|
2025-02-09 22:11:50 +08:00
|
|
|
|
"LOD1": ["头部", "牙齿", "牙龈", "左眼", "右眼", "虹膜", "睫毛", "眼睑", "软骨", "身体"],
|
|
|
|
|
"LOD2": ["头部", "牙齿", "牙龈", "左眼", "右眼", "虹膜", "睫毛", "眼睑", "身体"],
|
|
|
|
|
"LOD3": ["头部", "牙齿", "左眼", "右眼", "虹膜", "睫毛", "眼睑", "身体"],
|
|
|
|
|
"LOD4": ["头部", "牙齿", "左眼", "右眼", "虹膜"],
|
|
|
|
|
"LOD5": ["头部", "牙齿", "左眼", "右眼"],
|
|
|
|
|
"LOD6": ["头部", "牙齿", "左眼", "右眼"],
|
|
|
|
|
"LOD7": ["头部", "牙齿", "左眼", "右眼"]
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-09 21:35:41 +08:00
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
variables_path = [
|
|
|
|
|
TOOL_PATH,
|
|
|
|
|
ICONS_PATH,
|
|
|
|
|
SCRIPTS_PATH,
|
|
|
|
|
TOOL_STYLE_FILE,
|
|
|
|
|
DNACALIB_PATH,
|
|
|
|
|
BUILDER_PATH,
|
|
|
|
|
DNALIB_PATH,
|
|
|
|
|
UI_PATH,
|
|
|
|
|
UTILS_PATH,
|
|
|
|
|
PLUGIN_PATH,
|
|
|
|
|
PYDNA_PATH,
|
|
|
|
|
ASSETS_PATH,
|
|
|
|
|
DNA_PATH,
|
|
|
|
|
IMG_PATH,
|
|
|
|
|
MAYA_PATH,
|
|
|
|
|
GUI_PATH,
|
|
|
|
|
ASSEMBLE_SCRIPT,
|
|
|
|
|
SHADER_PATH,
|
|
|
|
|
MASKS_PATH,
|
|
|
|
|
MAPS_PATH,
|
|
|
|
|
BODY_PATH
|
|
|
|
|
]
|
|
|
|
|
for i in variables_path:
|
|
|
|
|
if not i in sys.path:
|
|
|
|
|
sys.path.append(i)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("============================================")
|
|
|
|
|
print(f"TOOL_PATH: {TOOL_PATH}")
|
|
|
|
|
print(f"ICONS_PATH: {ICONS_PATH}")
|
|
|
|
|
print(f"SCRIPTS_PATH: {SCRIPTS_PATH}")
|
|
|
|
|
print(f"TOOL_STYLE_FILE: {TOOL_STYLE_FILE}")
|
|
|
|
|
print(f"DNACALIB_PATH: {DNACALIB_PATH}")
|
|
|
|
|
print(f"BUILDER_PATH: {BUILDER_PATH}")
|
|
|
|
|
print(f"DNALIB_PATH: {DNALIB_PATH}")
|
|
|
|
|
print(f"UI_PATH: {UI_PATH}")
|
|
|
|
|
print(f"UTILS_PATH: {UTILS_PATH}")
|
|
|
|
|
print(f"PLUGIN_PATH: {PLUGIN_PATH}")
|
|
|
|
|
print(f"PYDNA_PATH: {PYDNA_PATH}")
|
|
|
|
|
print(f"ASSETS_PATH: {ASSETS_PATH}")
|
|
|
|
|
print(f"DNA_PATH: {DNA_PATH}")
|
|
|
|
|
print(f"IMG_PATH: {IMG_PATH}")
|
|
|
|
|
print(f"MAYA_PATH: {MAYA_PATH}")
|
|
|
|
|
print(f"GUI_PATH: {GUI_PATH}")
|
|
|
|
|
print(f"ASSEMBLE_SCRIPT: {ASSEMBLE_SCRIPT}")
|
|
|
|
|
print(f"SHADER_PATH: {SHADER_PATH}")
|
|
|
|
|
print(f"MASKS_PATH: {MASKS_PATH}")
|
|
|
|
|
print(f"MAPS_PATH: {MAPS_PATH}")
|
|
|
|
|
print(f"BODY_PATH: {BODY_PATH}")
|
|
|
|
|
print(f"TOOL_MAIN_SCRIPT: {TOOL_MAIN_SCRIPT}")
|
|
|
|
|
print(f"TOOL_STYLE_FILE: {TOOL_STYLE_FILE}")
|
|
|
|
|
print(f"TOOL_ICON: {TOOL_ICON}")
|
|
|
|
|
print(f"TOOL_COMMAND_ICON: {TOOL_COMMAND_ICON}")
|
|
|
|
|
print(f"TOOL_MOD_FILENAME: {TOOL_MOD_FILENAME}")
|
|
|
|
|
print("============================================")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|