Update
This commit is contained in:
261
2023/scripts/animation_tools/mgpicker/USAGE.md
Normal file
261
2023/scripts/animation_tools/mgpicker/USAGE.md
Normal file
@@ -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()
|
||||||
|
```
|
||||||
@@ -21,7 +21,7 @@ def get_maya_version():
|
|||||||
# Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号
|
# Maya 版本格式可能是 "2023" 或 "2023.1" 等,取主版本号
|
||||||
return maya_version.split('.')[0]
|
return maya_version.split('.')[0]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to get Maya version: {e}")
|
print("Failed to get Maya version: " + str(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ def find_compatible_plugin(plugin_dir, maya_version):
|
|||||||
try:
|
try:
|
||||||
maya_ver_int = int(maya_version)
|
maya_ver_int = int(maya_version)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print(f"Invalid Maya version format: {maya_version}")
|
print("Invalid Maya version format: " + str(maya_version))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# 列出所有可用的插件版本
|
# 列出所有可用的插件版本
|
||||||
@@ -68,18 +68,18 @@ def find_compatible_plugin(plugin_dir, maya_version):
|
|||||||
# 首先尝试完全匹配
|
# 首先尝试完全匹配
|
||||||
for ver, plugin_name in available_versions:
|
for ver, plugin_name in available_versions:
|
||||||
if ver == maya_ver_int:
|
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
|
return plugin_name
|
||||||
|
|
||||||
# 如果没有完全匹配,使用小于等于当前版本的最高版本
|
# 如果没有完全匹配,使用小于等于当前版本的最高版本
|
||||||
for ver, plugin_name in available_versions:
|
for ver, plugin_name in available_versions:
|
||||||
if ver <= maya_ver_int:
|
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
|
return plugin_name
|
||||||
|
|
||||||
# 如果当前版本比所有可用版本都旧,使用最旧的版本
|
# 如果当前版本比所有可用版本都旧,使用最旧的版本
|
||||||
oldest_ver, oldest_plugin = available_versions[-1]
|
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
|
return oldest_plugin
|
||||||
|
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ def load_plugin():
|
|||||||
print("Warning: Could not determine Maya version")
|
print("Warning: Could not determine Maya version")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print(f"Detected Maya version: {maya_version}")
|
print("Detected Maya version: " + str(maya_version))
|
||||||
|
|
||||||
# 查找兼容的插件
|
# 查找兼容的插件
|
||||||
mgpicker_path = get_mgpicker_path()
|
mgpicker_path = get_mgpicker_path()
|
||||||
@@ -108,44 +108,99 @@ def load_plugin():
|
|||||||
plugin_name = find_compatible_plugin(plugin_dir, maya_version)
|
plugin_name = find_compatible_plugin(plugin_dir, maya_version)
|
||||||
|
|
||||||
if not plugin_name:
|
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
|
return False
|
||||||
|
|
||||||
# Check if plugin is already loaded
|
# Check if plugin is already loaded
|
||||||
try:
|
try:
|
||||||
if cmds.pluginInfo(plugin_name, query=True, loaded=True):
|
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
|
return True
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
# Plugin not registered yet, will try to load
|
# Plugin not registered yet, will try to load
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Get the plugin path
|
# 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("\\", "/")
|
plugin_path = plugin_path.replace("\\", "/")
|
||||||
|
|
||||||
if not os.path.exists(plugin_path):
|
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
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cmds.loadPlugin(plugin_path)
|
cmds.loadPlugin(plugin_path)
|
||||||
print(f"MGPicker plugin loaded successfully: {plugin_path}")
|
print("MGPicker plugin loaded successfully: " + plugin_path)
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to load MGPicker plugin: {e}")
|
print("Failed to load MGPicker plugin: " + str(e))
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False
|
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
|
Start MG-Picker Studio
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
mode (int): 0 for designer mode, 1 for animator mode (default)
|
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
|
# Load plugin first
|
||||||
if not load_plugin():
|
if not load_plugin():
|
||||||
cmds.warning("Failed to load MGPicker 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")
|
program_path = os.path.join(mgpicker_path, "MGPicker_Program")
|
||||||
|
|
||||||
# Set global variables
|
# 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_ProgramFolder = "MGPicker_Program"')
|
||||||
mel.eval('global string $MGPicker_ScriptEntry = "MG_PickerStudio"')
|
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("\\", "/")
|
main_mel = os.path.join(program_path, "MGPicker_WrittenByMiguel.mel").replace("\\", "/")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mel.eval(f'source "{main_mel}"')
|
mel.eval('source "' + main_mel + '"')
|
||||||
# Open MGPicker window with mode parameter
|
# Open MGPicker window with mode parameter
|
||||||
# mode 0: designer mode, mode 1: animator mode
|
# mode 0: designer mode, mode 1: animator mode
|
||||||
mel.eval(f'MG_PickerStudio {mode}')
|
mel.eval('MG_PickerStudio ' + str(mode))
|
||||||
print(f"MG-Picker Studio started in {'designer' if mode == 0 else 'animator'} mode")
|
print("MG-Picker Studio started in " + ("designer" if mode == 0 else "animator") + " mode")
|
||||||
except Exception as e:
|
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']
|
__all__ = ['start', 'load_plugin']
|
||||||
|
|||||||
Reference in New Issue
Block a user