This commit is contained in:
Jeffreytsai1004 2025-02-06 04:46:41 +08:00
parent 3bb8f026c0
commit 5f7c424a35
14 changed files with 340 additions and 341 deletions

View File

@ -2,13 +2,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#===================================== 1. Module Imports ===================================== #===================================== 1. Module Imports =====================================
# Standard library imports
import os
import sys
import webbrowser
import maya.mel as mel
import maya.cmds as cmds
import maya.OpenMayaUI as omui import maya.OpenMayaUI as omui
import maya.cmds as cmds
import maya.mel as mel
import webbrowser
import sys
import os
from scripts.config import data
try: try:
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
@ -29,36 +30,24 @@ except ImportError:
QtCore = QtGui = QtWidgets = None QtCore = QtGui = QtWidgets = None
wrapInstance = None wrapInstance = None
from scripts.config.data import ( # def get_script_path():
TOOL_NAME, TOOL_VERSION, TOOL_AUTHOR, TOOL_LANG, # try:
TOOL_WSCL_NAME, TOOL_HELP_URL, TOOL_PATH, SCRIPTS_PATH, # maya_script = mel.eval('getenv("MAYA_SCRIPT_PATH")')
ICONS_PATH, STYLES_PATH, DNA_FILE_PATH, DNA_IMG_PATH, # if maya_script:
PLUGIN_PATH, PYDNA_PATH, DNACALIB_PATH, BUILDER_PATH, # paths = maya_script.split(os.pathsep)
DNALIB_PATH, UI_PATH, UTILS_PATH, TOOL_MAIN_SCRIPT, # for path in paths:
TOOL_STYLE_FILE, TOOL_ICON, TOOL_COMMAND_ICON, # install_path = os.path.join(path, "Install.py")
TOOL_MOD_FILENAME # if os.path.exists(install_path):
) # return os.path.dirname(install_path)
# except:
def get_script_path(): # pass
try:
maya_script = mel.eval('getenv("MAYA_SCRIPT_PATH")')
if maya_script:
paths = maya_script.split(os.pathsep)
for path in paths:
install_path = os.path.join(path, "Install.py")
if os.path.exists(install_path):
return os.path.dirname(install_path)
except:
pass
try: # try:
return os.path.dirname(os.path.abspath(__file__)) # return os.path.dirname(os.path.abspath(__file__))
except: # except:
return os.getcwd() # return os.getcwd()
TOOL_PATH = get_script_path() TOOL_PATH = data.TOOL_PATH
if TOOL_PATH not in sys.path:
sys.path.insert(0, TOOL_PATH)
#===================================== 3. Utility Functions ===================================== #===================================== 3. Utility Functions =====================================
@ -98,14 +87,14 @@ class InstallDialog(QtWidgets.QDialog):
self.setup_ui() self.setup_ui()
def load_stylesheet(self): def load_stylesheet(self):
with open(TOOL_STYLE_FILE, 'r', encoding='utf-8') as f: with open(data.TOOL_STYLE_FILE, 'r', encoding='utf-8') as f:
style = f.read() style = f.read()
self.setStyleSheet(style) self.setStyleSheet(style)
print(f"已加载样式文件: {TOOL_STYLE_FILE}") print(f"已加载样式文件: {data.TOOL_STYLE_FILE}")
def setup_ui(self): def setup_ui(self):
"""Initialize and setup UI components""" """Initialize and setup UI components"""
self.setWindowTitle(f"{TOOL_NAME} Installation") self.setWindowTitle(f"{data.TOOL_NAME} Installation")
self.setFixedSize(220, 120) self.setFixedSize(220, 120)
self.setup_window_icon() self.setup_window_icon()
self.create_widgets() self.create_widgets()
@ -114,16 +103,16 @@ class InstallDialog(QtWidgets.QDialog):
def setup_window_icon(self): def setup_window_icon(self):
"""Setup window icon if available""" """Setup window icon if available"""
if os.path.exists(TOOL_ICON): if os.path.exists(data.TOOL_ICON):
self.setWindowIcon(QtGui.QIcon(TOOL_ICON)) self.setWindowIcon(QtGui.QIcon(data.TOOL_ICON))
else: else:
print(f"Warning: Icon file not found: {TOOL_ICON}") print(f"Warning: Icon file not found: {data.TOOL_ICON}")
#----------------- 5.1 UI Methods ----------------- #----------------- 5.1 UI Methods -----------------
def create_widgets(self): def create_widgets(self):
self.new_shelf_toggle = QtWidgets.QCheckBox(f"{TOOL_NAME} Installation") self.new_shelf_toggle = QtWidgets.QCheckBox(f"{data.TOOL_NAME} Installation")
self.install_button = SetButton("Install " + TOOL_NAME) self.install_button = SetButton("Install " + data.TOOL_NAME)
self.uninstall_button = SetButton("Uninstall " + TOOL_NAME) self.uninstall_button = SetButton("Uninstall " + data.TOOL_NAME)
def create_layouts(self): def create_layouts(self):
main_layout = QtWidgets.QVBoxLayout(self) main_layout = QtWidgets.QVBoxLayout(self)
@ -133,7 +122,7 @@ class InstallDialog(QtWidgets.QDialog):
header_layout = QtWidgets.QHBoxLayout() header_layout = QtWidgets.QHBoxLayout()
header_layout.setSpacing(5) header_layout.setSpacing(5)
welcome_label = QtWidgets.QLabel("Welcome to " + TOOL_NAME + "!") welcome_label = QtWidgets.QLabel("Welcome to " + data.TOOL_NAME + "!")
welcome_label.setStyleSheet("font-size: 11px; padding: 0px; margin: 0px;") welcome_label.setStyleSheet("font-size: 11px; padding: 0px; margin: 0px;")
header_layout.addWidget(welcome_label) header_layout.addWidget(welcome_label)
header_layout.addStretch() header_layout.addStretch()
@ -179,7 +168,7 @@ class InstallDialog(QtWidgets.QDialog):
#----------------- 5.3 Utility Methods ----------------- #----------------- 5.3 Utility Methods -----------------
def open_help_url(self): def open_help_url(self):
webbrowser.open(TOOL_HELP_URL) webbrowser.open(data.TOOL_HELP_URL)
QtWidgets.QApplication.restoreOverrideCursor() QtWidgets.QApplication.restoreOverrideCursor()
def get_script_path(): def get_script_path():
@ -202,7 +191,7 @@ class InstallDialog(QtWidgets.QDialog):
msg_box = self.create_styled_message_box( msg_box = self.create_styled_message_box(
"Confirm Installation", "Confirm Installation",
f"Are you sure you want to install {TOOL_NAME}?" f"Are you sure you want to install {data.TOOL_NAME}?"
) )
if msg_box.exec_() == QtWidgets.QMessageBox.Yes: if msg_box.exec_() == QtWidgets.QMessageBox.Yes:
try: try:
@ -217,7 +206,7 @@ class InstallDialog(QtWidgets.QDialog):
"""Handle uninstall request""" """Handle uninstall request"""
msg_box = self.create_styled_message_box( msg_box = self.create_styled_message_box(
"Confirm Uninstallation", "Confirm Uninstallation",
f"Are you sure you want to uninstall {TOOL_NAME}?" f"Are you sure you want to uninstall {data.TOOL_NAME}?"
) )
if msg_box.exec_() == QtWidgets.QMessageBox.Yes: if msg_box.exec_() == QtWidgets.QMessageBox.Yes:
@ -234,10 +223,10 @@ class InstallDialog(QtWidgets.QDialog):
def create_mod_file(self): def create_mod_file(self):
"""Create or update the .mod file for Maya""" """Create or update the .mod file for Maya"""
modules_dir = get_maya_modules_dir() modules_dir = get_maya_modules_dir()
mod_content = f"""+ {TOOL_NAME} {TOOL_VERSION} {TOOL_PATH} mod_content = f"""+ {data.TOOL_NAME} {data.TOOL_VERSION} {data.TOOL_PATH}
scripts: {SCRIPTS_PATH} scripts: {data.SCRIPTS_PATH}
""" """
mod_file_path = os.path.join(modules_dir, TOOL_MOD_FILENAME) mod_file_path = os.path.join(modules_dir, data.TOOL_MOD_FILENAME)
self._write_mod_file(mod_file_path, mod_content) self._write_mod_file(mod_file_path, mod_content)
def _write_mod_file(self, file_path, content): def _write_mod_file(self, file_path, content):
@ -253,37 +242,37 @@ class InstallDialog(QtWidgets.QDialog):
def uninstall_mod_file(self): def uninstall_mod_file(self):
modules_dir = get_maya_modules_dir() modules_dir = get_maya_modules_dir()
mod_file_path = os.path.join(modules_dir, TOOL_MOD_FILENAME) mod_file_path = os.path.join(modules_dir, data.TOOL_MOD_FILENAME)
if os.path.exists(mod_file_path): if os.path.exists(mod_file_path):
try: try:
os.remove(mod_file_path) os.remove(mod_file_path)
print(f"{TOOL_NAME}.mod file deleted") print(f"{data.TOOL_NAME}.mod file deleted")
except Exception as e: except Exception as e:
print(f"Error deleting {TOOL_NAME}.mod file: {e}") print(f"Error deleting {data.TOOL_NAME}.mod file: {e}")
def clean_existing_buttons(self): def clean_existing_buttons(self):
if cmds.shelfLayout(TOOL_NAME, exists=True): if cmds.shelfLayout(data.TOOL_NAME, exists=True):
buttons = cmds.shelfLayout(TOOL_NAME, query=True, childArray=True) or [] buttons = cmds.shelfLayout(data.TOOL_NAME, query=True, childArray=True) or []
for btn in buttons: for btn in buttons:
if cmds.shelfButton(btn, query=True, exists=True): if cmds.shelfButton(btn, query=True, exists=True):
label = cmds.shelfButton(btn, query=True, label=True) label = cmds.shelfButton(btn, query=True, label=True)
if label == TOOL_NAME: if label == data.TOOL_NAME:
cmds.deleteUI(btn) cmds.deleteUI(btn)
print(f"Deleted existing {TOOL_NAME} button: {btn}") print(f"Deleted existing {data.TOOL_NAME} button: {btn}")
def install_tool(self): def install_tool(self):
"""Install the tool to Maya""" """Install the tool to Maya"""
if not os.path.exists(SCRIPTS_PATH): if not os.path.exists(data.SCRIPTS_PATH):
print(f"Error: Scripts path does not exist: {SCRIPTS_PATH}") print(f"Error: Scripts path does not exist: {data.SCRIPTS_PATH}")
return return
if not os.path.exists(TOOL_MAIN_SCRIPT): if not os.path.exists(data.TOOL_MAIN_SCRIPT):
print(f"Error: Main script file not found: {TOOL_MAIN_SCRIPT}") print(f"Error: Main script file not found: {data.TOOL_MAIN_SCRIPT}")
return return
# Add scripts path to Python path # Add scripts path to Python path
if SCRIPTS_PATH not in sys.path: if data.SCRIPTS_PATH not in sys.path:
sys.path.insert(0, SCRIPTS_PATH) sys.path.insert(0, data.SCRIPTS_PATH)
# Create shelf and button # Create shelf and button
self._create_shelf_button() self._create_shelf_button()
@ -291,10 +280,10 @@ class InstallDialog(QtWidgets.QDialog):
# Switch to the newly created shelf # Switch to the newly created shelf
try: try:
cmds.shelfTabLayout("ShelfLayout", edit=True, selectTab=TOOL_NAME) cmds.shelfTabLayout("ShelfLayout", edit=True, selectTab=data.TOOL_NAME)
print(f"Switched to {TOOL_NAME} shelf") print(f"Switched to {data.TOOL_NAME} shelf")
except Exception as e: except Exception as e:
print(f"Error switching to {TOOL_NAME} shelf: {e}") print(f"Error switching to {data.TOOL_NAME} shelf: {e}")
self._show_install_success_message() self._show_install_success_message()
@ -303,24 +292,24 @@ class InstallDialog(QtWidgets.QDialog):
shelf_layout = mel.eval('$tmpVar=$gShelfTopLevel') shelf_layout = mel.eval('$tmpVar=$gShelfTopLevel')
# Create shelf if not exists # Create shelf if not exists
if not cmds.shelfLayout(TOOL_NAME, exists=True): if not cmds.shelfLayout(data.TOOL_NAME, exists=True):
cmds.shelfLayout(TOOL_NAME, parent=shelf_layout) cmds.shelfLayout(data.TOOL_NAME, parent=shelf_layout)
# Clean existing buttons # Clean existing buttons
self.clean_existing_buttons() self.clean_existing_buttons()
# Create new button # Create new button
icon_path = TOOL_ICON if os.path.exists(TOOL_ICON) else TOOL_COMMAND_ICON icon_path = data.TOOL_ICON if os.path.exists(data.TOOL_ICON) else data.TOOL_COMMAND_ICON
command = self._get_shelf_button_command() command = self._get_shelf_button_command()
cmds.shelfButton( cmds.shelfButton(
parent=TOOL_NAME, parent=data.TOOL_NAME,
image1=icon_path, image1=icon_path,
label=TOOL_NAME, label=data.TOOL_NAME,
command=command, command=command,
sourceType="python", sourceType="python",
annotation=f"{TOOL_NAME} {TOOL_VERSION}", annotation=f"{data.TOOL_NAME} {data.TOOL_VERSION}",
noDefaultPopup=True, noDefaultPopup=True,
style="iconOnly" style="iconOnly"
) )
@ -330,40 +319,40 @@ class InstallDialog(QtWidgets.QDialog):
return f""" return f"""
import sys import sys
import os import os
TOOL_PATH = r'{TOOL_PATH}' TOOL_PATH = r'{data.TOOL_PATH}'
if TOOL_PATH not in sys.path: if TOOL_PATH not in sys.path:
sys.path.insert(0, TOOL_PATH) sys.path.insert(0, TOOL_PATH)
SCRIPTS_PATH = r'{SCRIPTS_PATH}' SCRIPTS_PATH = r'{data.SCRIPTS_PATH}'
if SCRIPTS_PATH not in sys.path: if SCRIPTS_PATH not in sys.path:
sys.path.insert(0, SCRIPTS_PATH) sys.path.insert(0, SCRIPTS_PATH)
os.chdir(SCRIPTS_PATH) os.chdir(SCRIPTS_PATH)
try: try:
import {TOOL_NAME} import MetaFusion
{TOOL_NAME}.show() MetaFusion.show()
except ImportError as e: except ImportError as e:
print("Error importing {TOOL_NAME}:", str(e)) print("Error importing MetaFusion:", str(e))
print("Scripts path:", {SCRIPTS_PATH}) print(f"Scripts path: {data.SCRIPTS_PATH}")
print("sys.path:", sys.path) print("sys.path:", sys.path)
print("Contents of Scripts folder:", os.listdir({SCRIPTS_PATH})) print(f"Contents of Scripts folder: {os.listdir(data.SCRIPTS_PATH)}")
""" """
def uninstall_tool(self): def uninstall_tool(self):
"""Uninstall the tool from Maya""" """Uninstall the tool from Maya"""
window_name = f"{TOOL_NAME}Window" window_name = f"{data.TOOL_NAME}Window"
dock_name = f"{TOOL_NAME}WindowDock" dock_name = f"{data.TOOL_NAME}WindowDock"
shelf_file = f"shelf_{TOOL_NAME}.mel" shelf_file = f"shelf_{data.TOOL_NAME}.mel"
if cmds.window(window_name, exists=True): if cmds.window(window_name, exists=True):
try: try:
cmds.deleteUI(window_name) cmds.deleteUI(window_name)
except Exception as e: except Exception as e:
print(f"Error closing {TOOL_NAME} window: {e}") print(f"Error closing {data.TOOL_NAME} window: {e}")
if cmds.dockControl(dock_name, exists=True): if cmds.dockControl(dock_name, exists=True):
try: try:
cmds.deleteUI(dock_name) cmds.deleteUI(dock_name)
except Exception as e: except Exception as e:
print(f"Error closing docked {TOOL_NAME} window: {e}") print(f"Error closing docked {data.TOOL_NAME} window: {e}")
self.uninstall_mod_file() self.uninstall_mod_file()
@ -371,17 +360,17 @@ except ImportError as e:
current_shelf = cmds.shelfTabLayout("ShelfLayout", query=True, selectTab=True) current_shelf = cmds.shelfTabLayout("ShelfLayout", query=True, selectTab=True)
# Delete Shelves and Buttons # Delete Shelves and Buttons
if cmds.shelfLayout(TOOL_NAME, exists=True): if cmds.shelfLayout(data.TOOL_NAME, exists=True):
try: try:
cmds.deleteUI(TOOL_NAME, layout=True) cmds.deleteUI(data.TOOL_NAME, layout=True)
except Exception as e: except Exception as e:
print(f"Error deleting {TOOL_NAME} shelf: {e}") print(f"Error deleting {data.TOOL_NAME} shelf: {e}")
self._clean_all_shelf_buttons() self._clean_all_shelf_buttons()
# Remove from Python path # Remove from Python path
if SCRIPTS_PATH in sys.path: if data.SCRIPTS_PATH in sys.path:
sys.path.remove(SCRIPTS_PATH) sys.path.remove(data.SCRIPTS_PATH)
# Deleting Shelf Files # Deleting Shelf Files
shelf_path = os.path.join( shelf_path = os.path.join(
@ -389,7 +378,7 @@ except ImportError as e:
cmds.about(version=True), cmds.about(version=True),
"prefs", "prefs",
"shelves", "shelves",
f"shelf_{TOOL_NAME}.mel" f"shelf_{data.TOOL_NAME}.mel"
) )
if os.path.exists(shelf_path): if os.path.exists(shelf_path):
@ -399,7 +388,7 @@ except ImportError as e:
print(f"Error deleting shelf file: {e}") print(f"Error deleting shelf file: {e}")
# If the current tool shelf is a deleted tool shelf, switch to another tool shelf # If the current tool shelf is a deleted tool shelf, switch to another tool shelf
if current_shelf == TOOL_NAME: if current_shelf == data.TOOL_NAME:
shelves = cmds.shelfTabLayout("ShelfLayout", query=True, childArray=True) shelves = cmds.shelfTabLayout("ShelfLayout", query=True, childArray=True)
if shelves and len(shelves) > 0: if shelves and len(shelves) > 0:
cmds.shelfTabLayout("ShelfLayout", edit=True, selectTab=shelves[0]) cmds.shelfTabLayout("ShelfLayout", edit=True, selectTab=shelves[0])
@ -413,34 +402,34 @@ except ImportError as e:
shelf_buttons = cmds.shelfLayout(shelf, query=True, childArray=True) or [] shelf_buttons = cmds.shelfLayout(shelf, query=True, childArray=True) or []
for btn in shelf_buttons: for btn in shelf_buttons:
if cmds.shelfButton(btn, query=True, exists=True): if cmds.shelfButton(btn, query=True, exists=True):
if cmds.shelfButton(btn, query=True, label=True) == TOOL_NAME: if cmds.shelfButton(btn, query=True, label=True) == data.TOOL_NAME:
cmds.deleteUI(btn) cmds.deleteUI(btn)
def _show_uninstall_success_message(self): def _show_uninstall_success_message(self):
"""Show uninstallation success message""" """Show uninstallation success message"""
msg_box = QtWidgets.QMessageBox() msg_box = QtWidgets.QMessageBox()
msg_box.setWindowTitle("Uninstallation Successful") msg_box.setWindowTitle("Uninstallation Successful")
msg_box.setText(f"{TOOL_NAME} has been successfully uninstalled!") msg_box.setText(f"{data.TOOL_NAME} has been successfully uninstalled!")
msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok) msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok)
msg_box.setWindowIcon(QtGui.QIcon(TOOL_ICON)) msg_box.setWindowIcon(QtGui.QIcon(data.TOOL_ICON))
msg_box.setStyleSheet(self.styleSheet()) msg_box.setStyleSheet(self.styleSheet())
msg_box.exec_() msg_box.exec_()
def _show_install_success_message(self): def _show_install_success_message(self):
msg_box = QtWidgets.QMessageBox() msg_box = QtWidgets.QMessageBox()
msg_box.setWindowTitle("Installation Successful") msg_box.setWindowTitle("Installation Successful")
msg_box.setText(f"{TOOL_NAME} has been successfully installed!") msg_box.setText(f"{data.TOOL_NAME} has been successfully installed!")
msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok) msg_box.setStandardButtons(QtWidgets.QMessageBox.Ok)
msg_box.setWindowIcon(QtGui.QIcon(TOOL_ICON)) msg_box.setWindowIcon(QtGui.QIcon(data.TOOL_ICON))
msg_box.setStyleSheet(self.styleSheet()) msg_box.setStyleSheet(self.styleSheet())
msg_box.exec_() msg_box.exec_()
def _validate_paths(self): def _validate_paths(self):
"""Validate all required paths exist""" """Validate all required paths exist"""
paths = { paths = {
"Root": TOOL_PATH, "Root": data.TOOL_PATH,
"Scripts": SCRIPTS_PATH, "Scripts": data.SCRIPTS_PATH,
"Icons": ICONS_PATH "Icons": data.ICONS_PATH
} }
for name, path in paths.items(): for name, path in paths.items():
@ -463,7 +452,7 @@ except ImportError as e:
def _load_mel_shelf(self): def _load_mel_shelf(self):
"""Load mel shelf file with error handling""" """Load mel shelf file with error handling"""
try: try:
mel.eval(f'loadNewShelf "shelf_{TOOL_NAME}.mel"') mel.eval(f'loadNewShelf "shelf_{data.TOOL_NAME}.mel"')
except Exception as e: except Exception as e:
self._log(f"Error loading shelf file: {e}", error=True) self._log(f"Error loading shelf file: {e}", error=True)

View File

@ -1,18 +1,17 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os #===================================== 1. Module Imports =====================================
import sys
import maya.cmds as cmds
import maya.OpenMayaUI as omui import maya.OpenMayaUI as omui
import traceback import maya.cmds as cmds
import os
import sys
import webbrowser
import maya.mel as mel import maya.mel as mel
import maya.cmds as cmds import webbrowser
import maya.OpenMayaUI as omui import traceback
import sys
import os
from scripts.config import data
try: try:
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance from shiboken2 import wrapInstance
@ -32,16 +31,6 @@ except ImportError:
QtCore = QtGui = QtWidgets = None QtCore = QtGui = QtWidgets = None
wrapInstance = None wrapInstance = None
from scripts.config.data import (
TOOL_NAME, TOOL_VERSION, TOOL_AUTHOR, TOOL_LANG,
TOOL_WSCL_NAME, TOOL_HELP_URL, TOOL_PATH, SCRIPTS_PATH,
ICONS_PATH, STYLES_PATH, DNA_FILE_PATH, DNA_IMG_PATH,
PLUGIN_PATH, PYDNA_PATH, DNACALIB_PATH, BUILDER_PATH,
DNALIB_PATH, UI_PATH, UTILS_PATH, TOOL_MAIN_SCRIPT,
TOOL_STYLE_FILE, TOOL_ICON, TOOL_COMMAND_ICON,
TOOL_MOD_FILENAME
)
# 导入UI模块 # 导入UI模块
from scripts.ui.menu import MenuManager from scripts.ui.menu import MenuManager
from scripts.ui.models import ModelTab from scripts.ui.models import ModelTab
@ -49,6 +38,7 @@ from scripts.ui.rigging import RigTab
from scripts.ui.adjust import AdjustTab from scripts.ui.adjust import AdjustTab
from scripts.ui.define import DefineTab from scripts.ui.define import DefineTab
#===================================== 2. Main Window Class =====================================
class MainWindow(QtWidgets.QMainWindow): class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None): def __init__(self, parent=None):
super(MainWindow, self).__init__(parent) super(MainWindow, self).__init__(parent)
@ -61,16 +51,16 @@ class MainWindow(QtWidgets.QMainWindow):
def setup_paths(self): def setup_paths(self):
"""配置系统路径""" """配置系统路径"""
if PLUGIN_PATH not in sys.path: if data.PLUGIN_PATH not in sys.path:
sys.path.insert(0, PLUGIN_PATH) sys.path.insert(0, data.PLUGIN_PATH)
# 添加PyDNA路径 # 添加PyDNA路径
pydna_bin = os.path.join(PYDNA_PATH, "bin") pydna_bin = os.path.join(data.PYDNA_PATH, "bin")
os.environ["PATH"] = f"{pydna_bin}{os.pathsep}{os.environ['PATH']}" os.environ["PATH"] = f"{pydna_bin}{os.pathsep}{os.environ['PATH']}"
def init_ui(self): def init_ui(self):
"""初始化UI框架""" """初始化UI框架"""
self.setWindowTitle(f"{TOOL_NAME} {TOOL_VERSION}") self.setWindowTitle(f"{data.TOOL_NAME} {data.TOOL_VERSION}")
self.setMinimumSize(1200, 800) self.setMinimumSize(1200, 800)
# 主窗口布局 # 主窗口布局
@ -87,8 +77,8 @@ class MainWindow(QtWidgets.QMainWindow):
def load_styles(self): def load_styles(self):
"""加载样式表""" """加载样式表"""
if os.path.exists(TOOL_STYLE_FILE): if os.path.exists(data.TOOL_STYLE_FILE):
with open(TOOL_STYLE_FILE, "r", encoding="utf-8") as f: with open(data.TOOL_STYLE_FILE, "r", encoding="utf-8") as f:
self.setStyleSheet(f.read()) self.setStyleSheet(f.read())
def create_tab_widget(self): def create_tab_widget(self):
@ -122,12 +112,12 @@ def dock_to_maya():
"""嵌入Maya Dock面板""" """嵌入Maya Dock面板"""
global main_window global main_window
try: try:
if cmds.workspaceControl(TOOL_WSCL_NAME, exists=True): if cmds.workspaceControl(data.TOOL_WSCL_NAME, exists=True):
cmds.deleteUI(TOOL_WSCL_NAME) cmds.deleteUI(data.TOOL_WSCL_NAME)
dock_control = cmds.workspaceControl( dock_control = cmds.workspaceControl(
TOOL_WSCL_NAME, data.TOOL_WSCL_NAME,
label=TOOL_NAME, label=data.TOOL_NAME,
tabToControl=["AttributeEditor", -1], tabToControl=["AttributeEditor", -1],
initialWidth=1400, initialWidth=1400,
minimumWidth=1000, minimumWidth=1000,
@ -157,7 +147,7 @@ def show():
try: try:
if main_window: if main_window:
main_window.close() main_window.close()
cmds.deleteUI(TOOL_WSCL_NAME) cmds.deleteUI(data.TOOL_WSCL_NAME)
except: except:
pass pass

View File

@ -1,11 +1,34 @@
import os #!/usr/bin/env python
from scripts.config import data # -*- coding: utf-8 -*-
from scripts.ui.widgets import (
BaseWidget, BlendShapeList, BlendShapeControls,
BlendShapeTools, IconButton, SliderWithValue
)
QtCore, QtGui, QtWidgets = data.Qt()
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
from scripts.ui.widgets import (BaseWidget, BlendShapeList, BlendShapeControls, BlendShapeTools, IconButton, SliderWithValue)
try:
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
print("从PySide2加载Qt和shiboken2")
except ImportError:
try:
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
print("从PySide6加载Qt和shiboken6")
except ImportError:
try:
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e:
print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Adjust Tab Class =====================================
class AdjustTab(BaseWidget): class AdjustTab(BaseWidget):
"""调整标签页""" """调整标签页"""
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@ -1,10 +1,34 @@
import os #!/usr/bin/env python
from scripts.config import data # -*- coding: utf-8 -*-
from scripts.ui.widgets import (
BaseWidget, IconButton, SearchLineEdit
)
QtCore, QtGui, QtWidgets = data.Qt()
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
from scripts.ui.widgets import ( BaseWidget, IconButton, SearchLineEdit)
try:
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
print("从PySide2加载Qt和shiboken2")
except ImportError:
try:
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
print("从PySide6加载Qt和shiboken6")
except ImportError:
try:
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e:
print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Define Tab Class =====================================
class DefineTab(BaseWidget): class DefineTab(BaseWidget):
"""定义标签页""" """定义标签页"""
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@ -1,8 +1,31 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import os import os
from scripts.config import data from scripts.config import data
from scripts.utils import menu_utils from scripts.utils import menu_utils
QtCore, QtGui, QtWidgets = data.Qt()
try:
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
print("从PySide2加载Qt和shiboken2")
except ImportError:
try:
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
print("从PySide6加载Qt和shiboken6")
except ImportError:
try:
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e:
print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Menu Manager Class =====================================
class MenuManager: class MenuManager:
"""菜单管理器""" """菜单管理器"""
def __init__(self, parent): def __init__(self, parent):

View File

@ -1,10 +1,34 @@
import os #!/usr/bin/env python
from scripts.config import data # -*- coding: utf-8 -*-
from scripts.ui.widgets import (
BaseWidget, LODGroup, IconButton, SearchLineEdit
)
QtCore, QtGui, QtWidgets = data.Qt()
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
from scripts.ui.widgets import (BaseWidget, LODGroup, IconButton, SearchLineEdit)
try:
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
print("从PySide2加载Qt和shiboken2")
except ImportError:
try:
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
print("从PySide6加载Qt和shiboken6")
except ImportError:
try:
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e:
print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Model Tab Class =====================================
class ModelTab(BaseWidget): class ModelTab(BaseWidget):
"""模型标签页""" """模型标签页"""
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@ -1,39 +1,34 @@
import os #!/usr/bin/env python
import sys # -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds import maya.cmds as cmds
from scripts.ui.widgets import ( import maya.mel as mel
BaseWidget, DNABrowser, DescriptionWidget, IconButton, SearchLineEdit import sys
) import os
try:
from PySide import QtCore, QtGui, QtWidgets from scripts.ui.widgets import (BaseWidget, DNABrowser, DescriptionWidget, IconButton, SearchLineEdit)
print(f"从PySide加载Qt")
except ImportError as e:
try:
from PySide2 import QtCore, QtGui, QtWidgets
print(f"从PySide2加载Qt")
except ImportError as e:
try:
from PySide6 import QtCore, QtGui, QtWidgets
print(f"从PySide6加载Qt")
except ImportError as e:
print(f"PySide6加载失败: {str(e)}")
try: try:
from shiboken import wrapInstance from PySide2 import QtCore, QtGui, QtWidgets
print(f"从shiboken加载wrapInstance") from shiboken2 import wrapInstance
except ImportError as e: print("从PySide2加载Qt和shiboken2")
cmds.warning(f"shiboken加载失败: {str(e)}") except ImportError:
try: try:
from shiboken2 import wrapInstance from PySide6 import QtCore, QtGui, QtWidgets
print(f"从shiboken2加载wrapInstance") from shiboken6 import wrapInstance
except ImportError as e: print("从PySide6加载Qt和shiboken6")
cmds.warning(f"shiboken2加载失败: {str(e)}") except ImportError:
try: try:
from shiboken6 import wrapInstance from PySide import QtCore, QtGui, QtWidgets
print(f"从shiboken6加载wrapInstance") from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e: except ImportError as e:
cmds.warning(f"shiboken6加载失败: {str(e)}") print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. Rigging Tab Class =====================================
class RigTab(BaseWidget): class RigTab(BaseWidget):
"""绑定标签页""" """绑定标签页"""
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@ -1,97 +1,34 @@
import os #!/usr/bin/env python
import sys # -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds import maya.cmds as cmds
import maya.mel as mel
import sys
import os
from scripts.config import data
try: try:
from PySide import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
print(f"从PySide加载Qt") from shiboken2 import wrapInstance
except ImportError as e: print("从PySide2加载Qt和shiboken2")
except ImportError:
try: try:
from PySide2 import QtCore, QtGui, QtWidgets from PySide6 import QtCore, QtGui, QtWidgets
print(f"从PySide2加载Qt") from shiboken6 import wrapInstance
except ImportError as e: print("从PySide6加载Qt和shiboken6")
except ImportError:
try: try:
from PySide6 import QtCore, QtGui, QtWidgets from PySide import QtCore, QtGui, QtWidgets
print(f"从PySide6加载Qt") from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e: except ImportError as e:
print(f"PySide6加载失败: {str(e)}") print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
try: wrapInstance = None
from shiboken import wrapInstance
print(f"从shiboken加载wrapInstance")
except ImportError as e:
cmds.warning(f"shiboken加载失败: {str(e)}")
try:
from shiboken2 import wrapInstance
print(f"从shiboken2加载wrapInstance")
except ImportError as e:
cmds.warning(f"shiboken2加载失败: {str(e)}")
try:
from shiboken6 import wrapInstance
print(f"从shiboken6加载wrapInstance")
except ImportError as e:
cmds.warning(f"shiboken6加载失败: {str(e)}")
from scripts.config.data import (
ROOT_PATH,
TOOL_NAME,
TOOL_VERSION,
TOOL_AUTHOR,
TOOL_LANG,
TOOL_WSCL_NAME,
TOOL_HELP_URL,
SCRIPTS_PATH,
ICONS_PATH,
STYLES_PATH,
DNA_FILE_PATH,
DNA_IMG_PATH,
PLUGIN_PATH,
PYDNA_PATH,
DNACALIB_PATH,
BUILDER_PATH,
DNALIB_PATH,
UI_PATH,
UTILS_PATH,
TOOL_MAIN_SCRIPT,
TOOL_STYLE_FILE,
TOOL_ICON,
TOOL_COMMAND_ICON,
TOOL_MOD_FILENAME,
STYLE_FILE
)
if {ROOT_PATH,
SCRIPTS_PATH,
ICONS_PATH,
STYLES_PATH,
DNA_FILE_PATH,
DNA_IMG_PATH,
PLUGIN_PATH,
PYDNA_PATH,
DNACALIB_PATH,
BUILDER_PATH,
DNALIB_PATH,
UI_PATH,
UTILS_PATH
} not in sys.path:
for path in [
ROOT_PATH,
SCRIPTS_PATH,
ICONS_PATH,
STYLES_PATH,
DNA_FILE_PATH,
DNA_IMG_PATH,
PLUGIN_PATH,
PYDNA_PATH,
DNACALIB_PATH,
BUILDER_PATH,
DNALIB_PATH,
UI_PATH,
UTILS_PATH
]:
if path not in sys.path:
sys.path.append(path)
#===================================== 2. Base Widget Class =====================================
class BaseWidget(QtWidgets.QWidget): class BaseWidget(QtWidgets.QWidget):
"""基础控件类""" """基础控件类"""
def __init__(self, parent=None): def __init__(self, parent=None):
@ -122,7 +59,7 @@ class LoadButton(QtWidgets.QPushButton):
def setup_ui(self, text, icon_name): def setup_ui(self, text, icon_name):
if text: if text:
self.setText(text) self.setText(text)
icon_path = os.path.join(ICONS_PATH, icon_name) icon_path = os.path.join(data.ICONS_PATH, icon_name)
if os.path.exists(icon_path): if os.path.exists(icon_path):
self.setIcon(QtGui.QIcon(icon_path)) self.setIcon(QtGui.QIcon(icon_path))
self.setFixedSize(25, 25) self.setFixedSize(25, 25)
@ -238,7 +175,7 @@ class IconButton(QtWidgets.QPushButton):
def setup_ui(self, icon_name, tooltip): def setup_ui(self, icon_name, tooltip):
if icon_name: if icon_name:
icon_path = os.path.join(ICONS_PATH, icon_name) icon_path = os.path.join(data.ICONS_PATH, icon_name)
if os.path.exists(icon_path): if os.path.exists(icon_path):
self.setIcon(QtGui.QIcon(icon_path)) self.setIcon(QtGui.QIcon(icon_path))
if tooltip: if tooltip:
@ -335,8 +272,8 @@ class DNABrowser(QtWidgets.QWidget):
self.model.clear() self.model.clear()
# 从DNA目录加载文件 # 从DNA目录加载文件
dna_path = DNA_FILE_PATH dna_path = data.DNA_FILE_PATH
img_path = DNA_IMG_PATH img_path = data.DNA_IMG_PATH
if os.path.exists(dna_path): if os.path.exists(dna_path):
for file in os.listdir(dna_path): for file in os.listdir(dna_path):
@ -907,10 +844,10 @@ class ExpressionPreviewWidget(QtWidgets.QWidget):
"""切换播放状态""" """切换播放状态"""
if checked: if checked:
self.play_timer.start(33) # ~30fps self.play_timer.start(33) # ~30fps
self.play_btn.setIcon(QtGui.QIcon(os.path.join(ICONS_PATH, "pause.png"))) self.play_btn.setIcon(QtGui.QIcon(os.path.join(data.ICONS_PATH, "pause.png")))
else: else:
self.play_timer.stop() self.play_timer.stop()
self.play_btn.setIcon(QtGui.QIcon(os.path.join(ICONS_PATH, "play.png"))) self.play_btn.setIcon(QtGui.QIcon(os.path.join(data.ICONS_PATH, "play.png")))
def update_time(self): def update_time(self):
"""更新时间""" """更新时间"""

View File

@ -1,6 +1,13 @@
import maya.cmds as cmds #!/usr/bin/env python
from scripts.config import data # -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
#===================================== 2. BlendShape Manager Class =====================================
class BlendShapeManager: class BlendShapeManager:
"""BlendShape管理器""" """BlendShape管理器"""
def __init__(self): def __init__(self):

View File

@ -1,8 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os import os
import json import json
import maya.cmds as cmds
from scripts.config import data from scripts.config import data
try:
from PySide2 import QtCore, QtGui, QtWidgets
from shiboken2 import wrapInstance
print("从PySide2加载Qt和shiboken2")
except ImportError:
try:
from PySide6 import QtCore, QtGui, QtWidgets
from shiboken6 import wrapInstance
print("从PySide6加载Qt和shiboken6")
except ImportError:
try:
from PySide import QtCore, QtGui, QtWidgets
from shiboken import wrapInstance
print("从PySide加载Qt和shiboken")
except ImportError as e:
print(f"Qt加载失败: {str(e)}")
QtCore = QtGui = QtWidgets = None
wrapInstance = None
#===================================== 2. DNA Definition Class =====================================
class DNADefinition: class DNADefinition:
"""DNA定义类""" """DNA定义类"""
def __init__(self): def __init__(self):

View File

@ -1,57 +0,0 @@
import os
import maya.cmds as cmds
def check_installation():
"""检查插件安装状态"""
# 获取当前插件路径
plugin_path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
issues = []
# 检查mod文件
maya_mod_path = os.path.join(os.getenv('MAYA_APP_DIR'), 'modules')
mod_file = os.path.join(maya_mod_path, 'MetaFusion.mod')
if not os.path.exists(mod_file):
issues.append("缺少mod文件")
else:
# 验证mod文件内容
with open(mod_file, 'r') as f:
content = f.read()
if plugin_path not in content:
issues.append("mod文件路径不正确")
# 检查必要目录
required_dirs = [
'ui',
'utils',
'config',
'resources/icons'
]
for dir_path in required_dirs:
if not os.path.exists(os.path.join(plugin_path, dir_path)):
issues.append(f"缺少必要目录: {dir_path}")
# 检查必要文件
required_files = [
'MetaFusion.py',
'ui/__init__.py',
'ui/menu.py',
'ui/models.py',
'ui/rigging.py',
'ui/define.py',
'utils/adjust_utils.py',
'utils/define_utils.py',
'config/data.py'
]
for file_path in required_files:
if not os.path.exists(os.path.join(plugin_path, file_path)):
issues.append(f"缺少必要文件: {file_path}")
# 检查插件加载
if not cmds.pluginInfo('MetaFusion', q=True, loaded=True):
try:
cmds.loadPlugin('MetaFusion')
except:
issues.append("插件无法加载")
return issues

View File

@ -1,8 +1,15 @@
import os #!/usr/bin/env python
# -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds import maya.cmds as cmds
import maya.mel as mel
import sys
import os
from scripts.config import data from scripts.config import data
from scripts.utils import model_utils, rigging_utils, adjust_utils, define_utils from scripts.utils import model_utils, rigging_utils, adjust_utils, define_utils
#===================================== 2. Menu Utils =====================================
def load_dna(): def load_dna():
"""打开DNA文件""" """打开DNA文件"""
file_path = cmds.fileDialog2( file_path = cmds.fileDialog2(

View File

@ -1,9 +1,13 @@
import os #!/usr/bin/env python
import maya.cmds as cmds # -*- coding: utf-8 -*-
from scripts.config import data
import maya.mel as mel
# LOD模型加载功能 #===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
#===================================== 2. Model Utils =====================================
def load_model(lod_index, model_type, file_path): def load_model(lod_index, model_type, file_path):
"""加载模型 """加载模型
Args: Args:

View File

@ -1,6 +1,13 @@
import maya.cmds as cmds #!/usr/bin/env python
from scripts.config import data # -*- coding: utf-8 -*-
#===================================== 1. Module Imports =====================================
import maya.cmds as cmds
import maya.mel as mel
import sys
import os
#===================================== 2. Rigging Utils =====================================
def export_settings(): def export_settings():
"""导出设置""" """导出设置"""
print("导出设置功能待实现") print("导出设置功能待实现")