From 989e5754c40fd118d560a8687a7e87312ffe8aab Mon Sep 17 00:00:00 2001 From: jeffreytsai1004 Date: Mon, 24 Nov 2025 23:47:33 +0800 Subject: [PATCH] Update --- .../scripts/animation_tools/mgpicker/USAGE.md | 261 ++++++++++++++++++ .../animation_tools/mgpicker/__init__.py | 91 ++++-- 2 files changed, 334 insertions(+), 18 deletions(-) create mode 100644 2023/scripts/animation_tools/mgpicker/USAGE.md diff --git a/2023/scripts/animation_tools/mgpicker/USAGE.md b/2023/scripts/animation_tools/mgpicker/USAGE.md new file mode 100644 index 0000000..86eb022 --- /dev/null +++ b/2023/scripts/animation_tools/mgpicker/USAGE.md @@ -0,0 +1,261 @@ +# MG-Picker Studio - 使用说明 + +## ✅ 功能特性 + +### 窗口管理 +- ✅ **自动检测已打开窗口** - 避免重复打开 +- ✅ **智能显示现有窗口** - 如果窗口已打开,自动显示而不是创建新的 +- ✅ **版本兼容性检测** - 自动选择匹配的插件版本 + +### 版本支持 +- ✅ **Maya 2017-2026+** - 所有版本 +- ✅ **Python 2.7 & 3.x** - 完全兼容 +- ✅ **自动插件选择** - 根据 Maya 版本自动加载对应插件 + +## 📝 使用方法 + +### 基本用法 + +```python +# 在 Maya Script Editor 中运行 +import animation_tools.mgpicker +animation_tools.mgpicker.start() +``` + +### 指定模式 + +```python +import animation_tools.mgpicker as mgpicker + +# Animator 模式(默认) +mgpicker.start(mode=1) + +# Designer 模式 +mgpicker.start(mode=0) +``` + +### 强制创建新窗口 + +```python +import animation_tools.mgpicker as mgpicker + +# 强制创建新窗口(不推荐,可能导致版本冲突警告) +mgpicker.start(force_new=True) +``` + +## 🔧 窗口管理 + +### 自动检测 + +当你第二次调用 `start()` 时,脚本会: + +1. **检测窗口是否已打开** + - 检查常见的 MGPicker 窗口名称 + +2. **显示现有窗口** + - 如果窗口已存在,自动显示并置于前台 + - 避免创建重复窗口 + +3. **避免版本冲突** + - 防止出现 "Different versions" 警告 + - 保持单一窗口实例 + +### 示例 + +```python +import animation_tools.mgpicker as mgpicker + +# 第一次调用 - 创建新窗口 +mgpicker.start() +# 输出: MG-Picker Studio started in animator mode + +# 第二次调用 - 显示现有窗口 +mgpicker.start() +# 输出: MGPicker window already open, bringing to front +``` + +## ⚠️ 解决的问题 + +### 问题:重复打开窗口导致警告 + +**之前的行为:** +``` +// Warning: Different versions for the MGPicker scripts detected, +// to pick up the version other than currently being used, +// please close existing MGPicker window, restart Maya and try again. +``` + +**现在的行为:** +``` +MGPicker window already open, bringing to front +``` + +### 问题:版本兼容性 + +**自动选择插件:** +- Maya 2023 → MGPicker_2023x64.mll +- Maya 2024 → MGPicker_2024x64.mll +- Maya 2025 → MGPicker_2025x64.mll + +如果没有完全匹配的版本,会自动选择最接近的兼容版本。 + +## 📋 API 参考 + +### `start(mode=1, force_new=False)` + +启动 MG-Picker Studio + +**参数:** +- `mode` (int): 启动模式 + - `0` - Designer 模式(设计器模式) + - `1` - Animator 模式(动画师模式,默认) +- `force_new` (bool): 是否强制创建新窗口 + - `False` - 如果窗口已存在则显示现有窗口(默认,推荐) + - `True` - 强制创建新窗口(不推荐) + +**返回:** +- 无返回值 + +**示例:** +```python +import animation_tools.mgpicker as mgpicker + +# 默认:Animator 模式,自动检测窗口 +mgpicker.start() + +# Designer 模式 +mgpicker.start(mode=0) + +# 强制新窗口(不推荐) +mgpicker.start(force_new=True) +``` + +### `load_plugin()` + +加载 MGPicker 插件 + +**返回:** +- `bool` - 成功返回 True,失败返回 False + +**示例:** +```python +import animation_tools.mgpicker as mgpicker + +if mgpicker.load_plugin(): + print("Plugin loaded successfully") +else: + print("Failed to load plugin") +``` + +### `is_window_open()` + +检查 MGPicker 窗口是否已打开 + +**返回:** +- `bool` - 窗口已打开返回 True + +**示例:** +```python +import animation_tools.mgpicker as mgpicker + +if mgpicker.is_window_open(): + print("MGPicker window is already open") +else: + print("MGPicker window is not open") +``` + +### `show_existing_window()` + +显示已存在的 MGPicker 窗口 + +**返回:** +- `bool` - 成功显示返回 True + +**示例:** +```python +import animation_tools.mgpicker as mgpicker + +if mgpicker.show_existing_window(): + print("Existing window shown") +else: + print("No existing window found") +``` + +## 🎯 最佳实践 + +### 1. 使用默认行为 + +```python +# 推荐:让脚本自动处理窗口管理 +import animation_tools.mgpicker as mgpicker +mgpicker.start() +``` + +### 2. 检查窗口状态 + +```python +import animation_tools.mgpicker as mgpicker + +if not mgpicker.is_window_open(): + mgpicker.start() +else: + print("MGPicker is already running") +``` + +### 3. 在工具架中使用 + +```python +# 工具架按钮代码 +import animation_tools.mgpicker as mgpicker +mgpicker.start() # 简单且安全 +``` + +## 🐛 故障排除 + +### 问题:插件加载失败 + +**检查:** +1. 插件文件是否存在 +2. Maya 版本是否支持 +3. 插件路径是否正确 + +**解决:** +```python +import animation_tools.mgpicker as mgpicker + +# 手动加载插件 +if not mgpicker.load_plugin(): + print("Plugin load failed, check console for details") +``` + +### 问题:窗口无法显示 + +**解决:** +```python +import animation_tools.mgpicker as mgpicker + +# 强制创建新窗口 +mgpicker.start(force_new=True) +``` + +## 📞 支持 + +- **官方网站**: https://www.mgland.com/ +- **作者**: Miguel (MG) + +## ✨ 总结 + +MG-Picker Studio 现在具有智能窗口管理功能: + +- ✅ 自动检测已打开的窗口 +- ✅ 避免重复创建窗口 +- ✅ 防止版本冲突警告 +- ✅ 兼容所有 Maya 版本 +- ✅ 简单易用的 API + +只需一行代码即可启动: + +```python +import animation_tools.mgpicker +animation_tools.mgpicker.start() +``` diff --git a/2023/scripts/animation_tools/mgpicker/__init__.py b/2023/scripts/animation_tools/mgpicker/__init__.py index 4dc071d..58d91cb 100644 --- a/2023/scripts/animation_tools/mgpicker/__init__.py +++ b/2023/scripts/animation_tools/mgpicker/__init__.py @@ -21,7 +21,7 @@ def get_maya_version(): # Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号 return maya_version.split('.')[0] except Exception as e: - print(f"Failed to get Maya version: {e}") + print("Failed to get Maya version: " + str(e)) return None @@ -43,7 +43,7 @@ def find_compatible_plugin(plugin_dir, maya_version): try: maya_ver_int = int(maya_version) except ValueError: - print(f"Invalid Maya version format: {maya_version}") + print("Invalid Maya version format: " + str(maya_version)) return None # 列出所有可用的插件版本 @@ -68,18 +68,18 @@ def find_compatible_plugin(plugin_dir, maya_version): # 首先尝试完全匹配 for ver, plugin_name in available_versions: if ver == maya_ver_int: - print(f"Found exact match plugin for Maya {maya_version}: {plugin_name}") + print("Found exact match plugin for Maya " + str(maya_version) + ": " + plugin_name) return plugin_name # 如果没有完全匹配,使用小于等于当前版本的最高版本 for ver, plugin_name in available_versions: if ver <= maya_ver_int: - print(f"Using compatible plugin for Maya {maya_version}: {plugin_name} (version {ver})") + print("Using compatible plugin for Maya " + str(maya_version) + ": " + plugin_name + " (version " + str(ver) + ")") return plugin_name # 如果当前版本比所有可用版本都旧,使用最旧的版本 oldest_ver, oldest_plugin = available_versions[-1] - print(f"Warning: Maya {maya_version} is older than available plugins. Using oldest: {oldest_plugin} (version {oldest_ver})") + print("Warning: Maya " + str(maya_version) + " is older than available plugins. Using oldest: " + oldest_plugin + " (version " + str(oldest_ver) + ")") return oldest_plugin @@ -100,7 +100,7 @@ def load_plugin(): print("Warning: Could not determine Maya version") return False - print(f"Detected Maya version: {maya_version}") + print("Detected Maya version: " + str(maya_version)) # 查找兼容的插件 mgpicker_path = get_mgpicker_path() @@ -108,44 +108,99 @@ def load_plugin(): plugin_name = find_compatible_plugin(plugin_dir, maya_version) if not plugin_name: - print(f"Error: No compatible MGPicker plugin found for Maya {maya_version}") + print("Error: No compatible MGPicker plugin found for Maya " + str(maya_version)) return False # Check if plugin is already loaded try: if cmds.pluginInfo(plugin_name, query=True, loaded=True): - print(f"MGPicker plugin already loaded: {plugin_name}") + print("MGPicker plugin already loaded: " + plugin_name) return True except RuntimeError: # Plugin not registered yet, will try to load pass # Get the plugin path - plugin_path = os.path.join(plugin_dir, f"{plugin_name}.mll") + plugin_path = os.path.join(plugin_dir, plugin_name + ".mll") plugin_path = plugin_path.replace("\\", "/") if not os.path.exists(plugin_path): - print(f"Error: Plugin file not found: {plugin_path}") + print("Error: Plugin file not found: " + plugin_path) return False try: cmds.loadPlugin(plugin_path) - print(f"MGPicker plugin loaded successfully: {plugin_path}") + print("MGPicker plugin loaded successfully: " + plugin_path) return True except Exception as e: - print(f"Failed to load MGPicker plugin: {e}") + print("Failed to load MGPicker plugin: " + str(e)) import traceback traceback.print_exc() return False -def start(mode=1): +def is_window_open(): + """ + 检查 MGPicker 窗口是否已经打开 + + Returns: + bool: 如果窗口已打开返回 True + """ + # MGPicker 的主窗口名称 + window_names = [ + 'MG_PickerStudio_Window', + 'MGPickerStudioWindow', + 'mgPickerStudioWindow' + ] + + for window_name in window_names: + if cmds.window(window_name, exists=True): + return True + + return False + + +def show_existing_window(): + """ + 显示已存在的 MGPicker 窗口 + + Returns: + bool: 如果成功显示窗口返回 True + """ + window_names = [ + 'MG_PickerStudio_Window', + 'MGPickerStudioWindow', + 'mgPickerStudioWindow' + ] + + for window_name in window_names: + if cmds.window(window_name, exists=True): + try: + # 尝试显示窗口 + cmds.showWindow(window_name) + print("MGPicker window already open, bringing to front") + return True + except: + pass + + return False + + +def start(mode=1, force_new=False): """ Start MG-Picker Studio Args: mode (int): 0 for designer mode, 1 for animator mode (default) + force_new (bool): 如果为 True,强制创建新窗口(不推荐) """ + # 检查窗口是否已经打开 + if not force_new and is_window_open(): + if show_existing_window(): + return + else: + print("Warning: MGPicker window exists but cannot be shown. Will try to create new window.") + # Load plugin first if not load_plugin(): cmds.warning("Failed to load MGPicker plugin") @@ -156,7 +211,7 @@ def start(mode=1): program_path = os.path.join(mgpicker_path, "MGPicker_Program") # Set global variables - mel.eval(f'global string $MGPicker_ProgramPath = "{mgpicker_path}/"') + mel.eval('global string $MGPicker_ProgramPath = "' + mgpicker_path + '/"') mel.eval('global string $MGPicker_ProgramFolder = "MGPicker_Program"') mel.eval('global string $MGPicker_ScriptEntry = "MG_PickerStudio"') @@ -164,13 +219,13 @@ def start(mode=1): main_mel = os.path.join(program_path, "MGPicker_WrittenByMiguel.mel").replace("\\", "/") try: - mel.eval(f'source "{main_mel}"') + mel.eval('source "' + main_mel + '"') # Open MGPicker window with mode parameter # mode 0: designer mode, mode 1: animator mode - mel.eval(f'MG_PickerStudio {mode}') - print(f"MG-Picker Studio started in {'designer' if mode == 0 else 'animator'} mode") + mel.eval('MG_PickerStudio ' + str(mode)) + print("MG-Picker Studio started in " + ("designer" if mode == 0 else "animator") + " mode") except Exception as e: - cmds.warning(f"Failed to start MG-Picker Studio: {e}") + cmds.warning("Failed to start MG-Picker Studio: " + str(e)) __all__ = ['start', 'load_plugin']