diff --git a/config/data.py b/config/data.py index 22ae13c..e816919 100644 --- a/config/data.py +++ b/config/data.py @@ -8,20 +8,20 @@ import maya.cmds as cmds def Qt(): try: from PySide2 import QtCore, QtGui, QtWidgets - print("成功加载PySide2") + print("加载PySide2") return QtCore, QtGui, QtWidgets except ImportError as e: print(f"PySide2加载失败: {str(e)}") try: from PySide import QtCore, QtGui QtWidgets = QtGui - print("成功加载PySide") + print("加载PySide") return QtCore, QtGui, QtWidgets except ImportError as e: cmds.warning(f"PySide加载失败: {str(e)}") try: from PySide6 import QtCore, QtGui, QtWidgets - print("成功加载PySide6") + print("加载PySide6") return QtCore, QtGui, QtWidgets except ImportError as e: cmds.warning(f"PySide加载失败: {str(e)}") diff --git a/scripts/MetaFusion.py b/scripts/MetaFusion.py index 95d394a..1682588 100644 --- a/scripts/MetaFusion.py +++ b/scripts/MetaFusion.py @@ -36,63 +36,135 @@ BUILDER_PATH = data.BUILDER_PATH main_window = None -class MetaFusionWindow(QtWidgets.QMainWindow): +class ModelTab(QtWidgets.QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + layout = QtWidgets.QVBoxLayout(self) + + # LOD导航栏 + self.lod_tabs = QtWidgets.QTabWidget() + for i in range(1, 7): + tab = QtWidgets.QWidget() + self.lod_tabs.addTab(tab, f"LOD{i-1}") + layout.addWidget(self.lod_tabs) + + # 模型操作工具栏 + tool_bar = QtWidgets.QHBoxLayout() + self.add_button(tool_bar, "导入模型", "import.png", self.import_model) + self.add_button(tool_bar, "导出模型", "export.png", self.export_model) + layout.addLayout(tool_bar) + + def add_button(self, layout, text, icon, callback): + btn = QtWidgets.QPushButton(QtGui.QIcon(os.path.join(data.ICONS_PATH, icon)), text) + btn.clicked.connect(callback) + layout.addWidget(btn) + + def import_model(self): pass + def export_model(self): pass + +class RigTab(QtWidgets.QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal) + + # 左侧控制器列表 + left_panel = QtWidgets.QWidget() + left_layout = QtWidgets.QVBoxLayout(left_panel) + self.controller_list = QtWidgets.QListWidget() + left_layout.addWidget(self.controller_list) + + # 右侧视口区域 + right_panel = QtWidgets.QWidget() + right_layout = QtWidgets.QVBoxLayout(right_panel) + self.viewport_label = QtWidgets.QLabel("3D视口区域") + right_layout.addWidget(self.viewport_label) + + splitter.addWidget(left_panel) + splitter.addWidget(right_panel) + + main_layout = QtWidgets.QHBoxLayout(self) + main_layout.addWidget(splitter) + +class AdjustTab(QtWidgets.QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(QtWidgets.QLabel("调整功能开发中...")) + +class DefineTab(QtWidgets.QWidget): + def __init__(self): + super().__init__() + self.init_ui() + + def init_ui(self): + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(QtWidgets.QLabel("定义功能开发中...")) + +class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): - try: - super(MetaFusionWindow, self).__init__(parent) - self.setWindowTitle("MetaFusion") - self.resize(800, 600) - - # 设置窗口标志 - if parent is None: - # 独立窗口模式 - self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint) - else: - # 嵌入模式 - self.setWindowFlags(QtCore.Qt.Widget) - - # 加载样式表 - self.load_stylesheet() - - # 创建UI - self.setup_ui() - except Exception as e: - cmds.warning(f"窗口初始化失败: {str(e)}") - self.safe_shutdown() + super(MainWindow, self).__init__(parent) + self.setup_core_components() - def load_stylesheet(self): - """加载QSS样式表""" - style_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), "resources", "styles", "style.qss") - if os.path.exists(style_file): - with open(style_file, 'r', encoding='utf-8') as f: - self.setStyleSheet(f.read()) - - def setup_ui(self): - """设置UI结构""" - # 创建中心部件 - central_widget = QtWidgets.QWidget() - self.setCentralWidget(central_widget) + def setup_core_components(self): + """初始化核心组件""" + self.setup_paths() + self.init_ui() + self.setup_connections() - # 创建主布局 - main_layout = QtWidgets.QVBoxLayout(central_widget) + def setup_paths(self): + """配置系统路径""" + # 添加插件路径 + if data.PLUGIN_PATH not in sys.path: + sys.path.insert(0, data.PLUGIN_PATH) - # 创建菜单栏 + # 添加PyDNA二进制路径到环境变量 + pydna_bin = os.path.join(data.PYDNA_PATH, "bin") + os.environ["PATH"] = f"{pydna_bin}{os.pathsep}{os.environ['PATH']}" + + def init_ui(self): + """初始化UI框架""" + self.setWindowTitle(f"{data.TOOL_NAME} {data.TOOL_VERSION}") + self.setMinimumSize(1200, 800) + + # 主窗口布局 + main_widget = QtWidgets.QWidget() + self.setCentralWidget(main_widget) + main_layout = QtWidgets.QVBoxLayout(main_widget) + + # 创建核心组件 self.create_menu_bar() + self.create_toolbar() + self.create_tab_widget() - # 创建工具栏 - self.create_tool_bar() - - # 创建标签页 - self.create_tabs() - + # 加载样式 + self.load_styles() + + def load_styles(self): + """加载样式表""" + style_path = os.path.join(data.STYLES_PATH, "style.qss") + if os.path.exists(style_path): + with open(style_path, "r", encoding="utf-8") as f: + self.setStyleSheet(f.read()) + def create_menu_bar(self): """创建菜单栏""" menubar = self.menuBar() # 文件菜单 file_menu = menubar.addMenu("文件") - self.add_menu_action(file_menu, "打开DNA", "open.png", self.on_open_dna) - self.add_menu_action(file_menu, "保存DNA", "save.png", self.on_save_dna) + self.add_menu_action(file_menu, "打开DNA", + lambda: self.load_dna(), "open.png") + self.add_menu_action(file_menu, "保存DNA", + lambda: self.save_dna(), "save.png") self.add_menu_action(file_menu, "加载当前项目的DNA", "open.png", self.on_load_project_dna) self.add_menu_action(file_menu, "修改混合目标名称", "rename.png", self.on_rename_blend_target) self.add_menu_action(file_menu, "重置混合目标名称", "resetname.png", self.on_reset_blend_target) @@ -141,14 +213,15 @@ class MetaFusionWindow(QtWidgets.QMainWindow): self.add_menu_action(help_menu, "帮助文档", "help.png", self.show_help_document) self.add_menu_action(help_menu, "关于", "warning.png", self.show_about_dialog) - def add_menu_action(self, menu, text, icon, callback): + def add_menu_action(self, menu, text, callback, icon=None): """通用菜单项添加方法""" - action = QtWidgets.QAction(QtGui.QIcon(os.path.join(ICONS_PATH, icon)), text, self) + action = QtWidgets.QAction(text, self) + if icon: + action.setIcon(QtGui.QIcon(os.path.join(data.ICONS_PATH, icon))) action.triggered.connect(callback) menu.addAction(action) - return action - def create_tool_bar(self): + def create_toolbar(self): """创建工具栏""" toolbar = self.addToolBar("主工具栏") toolbar.setMovable(False) @@ -157,29 +230,33 @@ class MetaFusionWindow(QtWidgets.QMainWindow): toolbar.addAction(QtGui.QIcon(os.path.join(ICONS_PATH, "save.png")), "保存DNA") toolbar.addAction(QtGui.QIcon(os.path.join(ICONS_PATH, "open.png")), "加载当前项目DNA") - def create_tabs(self): - """创建标签页""" + def create_tab_widget(self): + """创建主标签页""" self.tab_widget = QtWidgets.QTabWidget() self.centralWidget().layout().addWidget(self.tab_widget) - - # 创建四个主要标签页 - self.model_tab = QtWidgets.QWidget() - self.rig_tab = QtWidgets.QWidget() - self.adjust_tab = QtWidgets.QWidget() - self.define_tab = QtWidgets.QWidget() - - # 添加标签页到标签页控件 + + # 初始化各标签页 + self.model_tab = ModelTab() + self.rig_tab = RigTab() + self.adjust_tab = AdjustTab() + self.define_tab = DefineTab() + + # 添加标签页 self.tab_widget.addTab(self.model_tab, "模型") self.tab_widget.addTab(self.rig_tab, "绑定") self.tab_widget.addTab(self.adjust_tab, "调整") self.tab_widget.addTab(self.define_tab, "定义") - # 设置各个标签页的内容 - self.setup_model_tab() - self.setup_rig_tab() - self.setup_adjust_tab() - self.setup_define_tab() + def setup_connections(self): + """建立信号连接""" + # 示例:连接标签页切换信号 + self.tab_widget.currentChanged.connect(self.on_tab_changed) + def on_tab_changed(self, index): + """标签页切换回调""" + current_tab = self.tab_widget.widget(index) + print(f"切换到标签页: {current_tab.objectName()}") + def setup_model_tab(self): """设置模型标签页内容""" layout = QtWidgets.QVBoxLayout(self.model_tab) @@ -411,12 +488,12 @@ def dock_to_maya(): """将窗口嵌入到 Maya 的 Dock 面板""" try: # 先清理可能存在的旧控件 - if cmds.workspaceControl("MetaFusionDock", exists=True): - cmds.deleteUI("MetaFusionDock") + if cmds.workspaceControl(TOOL_WSCL_NAME, exists=True): + cmds.deleteUI(TOOL_WSCL_NAME) # 创建新的Dock控件 dock_control = cmds.workspaceControl( - "MetaFusionDock", + TOOL_WSCL_NAME, label=TOOL_NAME, tabToControl=["AttributeEditor", -1], initialWidth=1400, @@ -433,7 +510,7 @@ def dock_to_maya(): # 获取Maya主窗口并创建实例 maya_main_window = get_maya_window() - main_window = MetaFusionWindow(parent=maya_main_window) + main_window = MainWindow(parent=maya_main_window) # 嵌入到Dock maya_dock_widget = wrapInstance(int(maya_dock_ptr), QtWidgets.QWidget) @@ -454,7 +531,7 @@ def show(): # 清理旧实例 if main_window: main_window.close() - cmds.deleteUI("MetaFusionDock") + cmds.deleteUI(TOOL_WSCL_NAME) except: pass @@ -464,7 +541,7 @@ def show(): # 备用方案:独立窗口模式 if not main_window: cmds.warning("Dock 模式失败,使用独立窗口模式") - main_window = MetaFusionWindow() + main_window = MainWindow() main_window.show() return main_window diff --git a/scripts/dna_utils.py b/scripts/dna_utils.py index 32e07f4..23bb7c1 100644 --- a/scripts/dna_utils.py +++ b/scripts/dna_utils.py @@ -8,9 +8,9 @@ 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 +MAYA_VERSION = data.MAYA_VERSION +PYDNA_PATH = data.PYDNA_PATH +PLUGIN_PATH = data.PLUGIN_PATH def load_dna_plugin(): """安全加载插件""" @@ -36,53 +36,7 @@ def load_dna_plugin(): except Exception as e: cmds.warning(f"❌ 加载失败 {plugin_name}: {str(e)}") - # 不要退出,继续尝试加载其他插件 -def setup_dna_path(): - """增强路径设置""" - try: - # 添加二进制路径到系统PATH - bin_path = os.path.join(data.PYDNA_PATH, "bin") - os.environ['PATH'] = f"{bin_path}{os.pathsep}{os.environ['PATH']}" - print(f"已添加二进制路径: {bin_path}") - - # 确保Python能搜索到必要路径 - required_paths = [ - data.PLUGIN_PATH, - data.PYDNA_PATH, - os.path.join(data.PYDNA_PATH, "bin") - ] - - for path in required_paths: - if path not in sys.path: - sys.path.insert(0, path) - print(f"已添加路径: {path}") - - except Exception as e: - cmds.warning(f"路径设置失败: {str(e)}") - -# 设置路径并加载插件 -setup_dna_path() -plugin_loaded = load_dna_plugin() - -# 全局变量 -dna = None -dnacalib = None - -try: - # 在导入前添加二进制模块路径 - PYBIN_PATH = os.path.join(data.PYDNA_PATH, "bin") - if PYBIN_PATH not in sys.path: - sys.path.insert(0, PYBIN_PATH) - - # 然后导入 DNA 模块 - from dna import * - 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):