Update
This commit is contained in:
@@ -1,321 +0,0 @@
|
||||
# Maya 工具架按钮命令
|
||||
|
||||
所有工具的标准启动命令,**不需要使用绝对路径**。
|
||||
|
||||
## 📋 前提条件
|
||||
|
||||
确保 `animation_tools` 在 Maya 的 Python 路径中。通常通过以下方式之一:
|
||||
|
||||
1. **userSetup.py** (推荐)
|
||||
```python
|
||||
import sys
|
||||
import os
|
||||
scripts_path = r'h:\Workspace\Raw\Tools\Plugins\Maya\2023\scripts'
|
||||
if scripts_path not in sys.path:
|
||||
sys.path.insert(0, scripts_path)
|
||||
```
|
||||
|
||||
2. **Maya.env**
|
||||
```
|
||||
PYTHONPATH=h:\Workspace\Raw\Tools\Plugins\Maya\2023\scripts
|
||||
```
|
||||
|
||||
## 🔧 工具架按钮命令
|
||||
|
||||
### 1. Studio Library
|
||||
|
||||
**Python 命令:**
|
||||
```python
|
||||
import animation_tools.studiolibrary as studiolib
|
||||
studiolib.show()
|
||||
```
|
||||
|
||||
**MEL 命令:**
|
||||
```mel
|
||||
python("import animation_tools.studiolibrary as studiolib; studiolib.show()");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. DreamWall Picker
|
||||
|
||||
**Python 命令:**
|
||||
```python
|
||||
import animation_tools.dwpicker as dwpicker
|
||||
dwpicker.show()
|
||||
```
|
||||
|
||||
**MEL 命令:**
|
||||
```mel
|
||||
python("import animation_tools.dwpicker as dwpicker; dwpicker.show()");
|
||||
```
|
||||
|
||||
**切换显示/隐藏:**
|
||||
```python
|
||||
import animation_tools.dwpicker as dwpicker
|
||||
dwpicker.toggle()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. MG-Picker Studio
|
||||
|
||||
**Python 命令(Animator 模式):**
|
||||
```python
|
||||
import animation_tools.mgpicker as mgpicker
|
||||
mgpicker.start()
|
||||
```
|
||||
|
||||
**Python 命令(Designer 模式):**
|
||||
```python
|
||||
import animation_tools.mgpicker as mgpicker
|
||||
mgpicker.start(mode=0)
|
||||
```
|
||||
|
||||
**MEL 命令:**
|
||||
```mel
|
||||
python("import animation_tools.mgpicker as mgpicker; mgpicker.start()");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. IK/FK Switcher
|
||||
|
||||
**Python 命令:**
|
||||
```python
|
||||
import animation_tools.ik_fk_switcher as ikfk
|
||||
ikfk.show()
|
||||
```
|
||||
|
||||
**MEL 命令:**
|
||||
```mel
|
||||
python("import animation_tools.ik_fk_switcher as ikfk; ikfk.show()");
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 创建工具架按钮步骤
|
||||
|
||||
### 方法 1:通过 Maya UI
|
||||
|
||||
1. 打开 **Script Editor**(脚本编辑器)
|
||||
2. 在 **Python** 标签页输入命令
|
||||
3. 选中代码
|
||||
4. **鼠标中键拖拽** 到工具架
|
||||
5. 右键点击按钮 → **Edit** → 设置图标和标签
|
||||
|
||||
### 方法 2:通过 MEL 命令
|
||||
|
||||
```mel
|
||||
// Studio Library
|
||||
shelfButton
|
||||
-command "python(\"import animation_tools.studiolibrary as studiolib; studiolib.show()\")"
|
||||
-annotation "Studio Library"
|
||||
-label "StudioLib"
|
||||
-image "commandButton.png"
|
||||
-imageOverlayLabel "SL";
|
||||
|
||||
// DreamWall Picker
|
||||
shelfButton
|
||||
-command "python(\"import animation_tools.dwpicker as dwpicker; dwpicker.show()\")"
|
||||
-annotation "DreamWall Picker"
|
||||
-label "DWPicker"
|
||||
-image "commandButton.png"
|
||||
-imageOverlayLabel "DW";
|
||||
|
||||
// MG-Picker
|
||||
shelfButton
|
||||
-command "python(\"import animation_tools.mgpicker as mgpicker; mgpicker.start()\")"
|
||||
-annotation "MG-Picker Studio"
|
||||
-label "MGPicker"
|
||||
-image "commandButton.png"
|
||||
-imageOverlayLabel "MG";
|
||||
|
||||
// IK/FK Switcher
|
||||
shelfButton
|
||||
-command "python(\"import animation_tools.ik_fk_switcher as ikfk; ikfk.show()\")"
|
||||
-annotation "IK/FK Switcher"
|
||||
-label "IK/FK"
|
||||
-image "commandButton.png"
|
||||
-imageOverlayLabel "IK";
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 推荐的按钮图标
|
||||
|
||||
### Studio Library
|
||||
- **图标**: `UVEditorSnapshot.png` 或 `folder-open.png`
|
||||
- **标签**: `SL` 或 `Studio`
|
||||
|
||||
### DreamWall Picker
|
||||
- **图标**: `pickHandlesComp.png` 或 `pickOtherComp.png`
|
||||
- **标签**: `DW` 或 `Picker`
|
||||
|
||||
### MG-Picker
|
||||
- **图标**: `pickWalkUp.png` 或 `selectByHierarchy.png`
|
||||
- **标签**: `MG` 或 `MGPick`
|
||||
|
||||
### IK/FK Switcher
|
||||
- **图标**: `ikSCsolver.png` 或 `kinHandle.png`
|
||||
- **标签**: `IK` 或 `Switch`
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 常见问题
|
||||
|
||||
### 问题 1: ModuleNotFoundError: No module named 'animation_tools'
|
||||
|
||||
**原因**: `animation_tools` 不在 Python 路径中
|
||||
|
||||
**解决方案**:
|
||||
1. 检查 `userSetup.py` 是否正确设置
|
||||
2. 或在按钮命令前添加路径:
|
||||
```python
|
||||
import sys
|
||||
scripts_path = r'h:\Workspace\Raw\Tools\Plugins\Maya\2023\scripts'
|
||||
if scripts_path not in sys.path:
|
||||
sys.path.insert(0, scripts_path)
|
||||
|
||||
import animation_tools.studiolibrary as studiolib
|
||||
studiolib.show()
|
||||
```
|
||||
|
||||
### 问题 2: 工具重复打开
|
||||
|
||||
**原因**: 没有使用正确的启动命令
|
||||
|
||||
**解决方案**: 使用本文档中的标准命令,所有工具都有窗口管理机制
|
||||
|
||||
### 问题 3: 版本不兼容
|
||||
|
||||
**原因**: 使用了错误的 Maya 版本目录
|
||||
|
||||
**解决方案**:
|
||||
- Maya 2023 使用: `Maya\2023\scripts`
|
||||
- Maya 2024 使用: `Maya\2024\scripts`
|
||||
- Maya 2025 使用: `Maya\2025\scripts`
|
||||
|
||||
---
|
||||
|
||||
## 📦 完整的 userSetup.py 示例
|
||||
|
||||
创建或编辑: `Documents/maya/scripts/userSetup.py`
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Maya User Setup
|
||||
自动加载动画工具路径
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import maya.cmds as cmds
|
||||
|
||||
def setup_animation_tools():
|
||||
"""设置动画工具路径"""
|
||||
# 获取 Maya 版本
|
||||
maya_version = cmds.about(version=True).split('.')[0]
|
||||
|
||||
# 构建路径
|
||||
base_path = r'h:\Workspace\Raw\Tools\Plugins\Maya'
|
||||
scripts_path = os.path.join(base_path, maya_version, 'scripts')
|
||||
|
||||
# 添加到 Python 路径
|
||||
if os.path.exists(scripts_path):
|
||||
if scripts_path not in sys.path:
|
||||
sys.path.insert(0, scripts_path)
|
||||
print("Animation tools loaded from: " + scripts_path)
|
||||
else:
|
||||
print("Warning: Animation tools path not found: " + scripts_path)
|
||||
|
||||
# 在 Maya 启动时执行
|
||||
if __name__ == '__main__':
|
||||
cmds.evalDeferred(setup_animation_tools)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 验证安装
|
||||
|
||||
在 Maya Script Editor 中运行:
|
||||
|
||||
```python
|
||||
import sys
|
||||
print("Python paths:")
|
||||
for path in sys.path[:5]:
|
||||
print(" -", path)
|
||||
|
||||
print("\nTesting imports:")
|
||||
try:
|
||||
import animation_tools.studiolibrary
|
||||
print(" ✓ Studio Library")
|
||||
except ImportError as e:
|
||||
print(" ✗ Studio Library:", e)
|
||||
|
||||
try:
|
||||
import animation_tools.dwpicker
|
||||
print(" ✓ DreamWall Picker")
|
||||
except ImportError as e:
|
||||
print(" ✗ DreamWall Picker:", e)
|
||||
|
||||
try:
|
||||
import animation_tools.mgpicker
|
||||
print(" ✓ MG-Picker")
|
||||
except ImportError as e:
|
||||
print(" ✗ MG-Picker:", e)
|
||||
|
||||
try:
|
||||
import animation_tools.ik_fk_switcher
|
||||
print(" ✓ IK/FK Switcher")
|
||||
except ImportError as e:
|
||||
print(" ✗ IK/FK Switcher:", e)
|
||||
```
|
||||
|
||||
预期输出:
|
||||
```
|
||||
Python paths:
|
||||
- h:\Workspace\Raw\Tools\Plugins\Maya\2023\scripts
|
||||
- ...
|
||||
|
||||
Testing imports:
|
||||
✓ Studio Library
|
||||
✓ DreamWall Picker
|
||||
✓ MG-Picker
|
||||
✓ IK/FK Switcher
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 快速启动所有工具
|
||||
|
||||
```python
|
||||
# 一键启动所有动画工具
|
||||
import animation_tools.studiolibrary as studiolib
|
||||
import animation_tools.dwpicker as dwpicker
|
||||
import animation_tools.mgpicker as mgpicker
|
||||
import animation_tools.ik_fk_switcher as ikfk
|
||||
|
||||
studiolib.show()
|
||||
dwpicker.show()
|
||||
mgpicker.start()
|
||||
ikfk.show()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📞 支持
|
||||
|
||||
如果遇到问题:
|
||||
|
||||
1. 检查 Python 路径是否正确
|
||||
2. 检查 Maya 版本是否匹配
|
||||
3. 查看 Script Editor 的完整错误信息
|
||||
4. 确认所有文件都在正确的位置
|
||||
|
||||
---
|
||||
|
||||
**所有工具现在都支持无绝对路径启动!** ✨
|
||||
@@ -14,7 +14,7 @@ import maya.cmds as cmds
|
||||
import maya.mel as mel
|
||||
import maya.OpenMaya as om
|
||||
#from math import isclose
|
||||
# from sys import exit # 已移除,避免 SystemExit 错误
|
||||
# from sys import exit # Removed to avoid SystemExit error
|
||||
|
||||
##################################################################################################################################################################################################################
|
||||
|
||||
@@ -71,8 +71,10 @@ def documentation():
|
||||
def assist_message(message, time, to_exit=True): # ---------- DONE
|
||||
#POPS UP A MESSAGE ON THE USER'S SCREEN TO INFORM THEM OF SOMETHING
|
||||
cmds.inViewMessage(amg="<hl>" + message + "<hl>", pos='midCenter', fade=True, fst=time, ck=True)
|
||||
# Also display warning in Script Editor
|
||||
cmds.warning(message)
|
||||
if to_exit:
|
||||
return # 不使用 exit(),避免 SystemExit 错误
|
||||
return # Do not use exit() to avoid SystemExit error
|
||||
|
||||
def get_constraint_attribute(constraint_type):
|
||||
#SETS A KEY ON THE START AND END OF THE TIMELINE, SO THAT WE ENSURE THERE'S A BLEND NODE ALL THE TIME. IF THERE'S NO KEY BEFORE ADDING THE SETUP, THE SCRIPT WON'T APPLY A SWITCH ON THE BLEND NODE
|
||||
@@ -736,9 +738,9 @@ def delete_setup():
|
||||
try:
|
||||
_delete_setup_impl()
|
||||
except Exception as e:
|
||||
# 捕获所有错误,避免 SystemExit
|
||||
# Catch all errors to avoid SystemExit
|
||||
if "SystemExit" not in str(type(e)):
|
||||
cmds.warning("Delete setup failed: " + str(e)) # ✓ 使用字符串拼接
|
||||
cmds.warning("Delete setup failed: " + str(e)) # Using string concatenation for Python 2.7 compatibility
|
||||
|
||||
def _delete_setup_impl():
|
||||
clear_keys = cmds.checkBoxGrp("remove_unnecessary_keys", q=True, v1=True)
|
||||
@@ -851,7 +853,7 @@ import maya.cmds as cmds
|
||||
import maya.mel as mel
|
||||
import maya.OpenMaya as om
|
||||
|
||||
# from sys import exit # 已移除,避免 SystemExit 错误
|
||||
# from sys import exit # Removed to avoid SystemExit error
|
||||
|
||||
bake_interval = """ + str(cmds.intFieldGrp("BakeInterval_IntField", q=True, v1=True)) + """
|
||||
apply_key_reducer = """ + str(cmds.checkBoxGrp("ApplyKeyReducer_CheckBox", q=True, v1=True)) + """
|
||||
@@ -912,9 +914,10 @@ def set_form_layout_coordinates(form_layout, name, top_coordinates, left_coordin
|
||||
def assist_message(message, time, to_exit=True): # ---------- DONE
|
||||
#POPS UP A MESSAGE ON THE USER'S SCREEN TO INFORM THEM OF SOMETHING
|
||||
cmds.inViewMessage(amg="<hl>" + message + "<hl>", pos='midCenter', fade=True, fst=time, ck=True)
|
||||
# 不再使用 exit(),因为它会在 Maya 中产生 SystemExit 错误
|
||||
# 调用者应该检查返回值并决定是否继续执行
|
||||
return not to_exit # 返回 False 表示应该停止,True 表示可以继续
|
||||
# Also display warning in Script Editor
|
||||
cmds.warning(message)
|
||||
if to_exit:
|
||||
return # Do not use exit() to avoid SystemExit error
|
||||
|
||||
def get_constraint_attribute(constraint_type):
|
||||
#SETS A KEY ON THE START AND END OF THE TIMELINE, SO THAT WE ENSURE THERE'S A BLEND NODE ALL THE TIME. IF THERE'S NO KEY BEFORE ADDING THE SETUP, THE SCRIPT WON'T APPLY A SWITCH ON THE BLEND NODE
|
||||
@@ -1127,6 +1130,7 @@ def get_original_fk_controls(): # ---------- DONE
|
||||
fk_ctrls = cmds.ls(sl=True)
|
||||
if len(fk_ctrls) != 3:
|
||||
assist_message("Incorrect number of controls selected. To apply an IK setup, you need to select 3 FK controls, in order of parent to child.", 4000)
|
||||
return None
|
||||
cmds.select(cl=True)
|
||||
return fk_ctrls
|
||||
|
||||
@@ -1338,6 +1342,7 @@ def get_original_ik_controls():
|
||||
ik_ctrls = cmds.ls(sl=True)
|
||||
if len(ik_ctrls) != 2:
|
||||
assist_message("Incorrect number of controls selected. To apply an FK setup, you need to select the Pole Vector first and then the IK Control, in order.", 4000)
|
||||
return None
|
||||
cmds.select(cl=True)
|
||||
return ik_ctrls
|
||||
|
||||
@@ -1668,7 +1673,7 @@ def extraOptions():
|
||||
cmds.showWindow("Extra_Options")
|
||||
|
||||
|
||||
# 导出主要函数,使其可以从外部调用
|
||||
# Export main functions for external use
|
||||
__all__ = [
|
||||
'fk_to_ik',
|
||||
'ik_to_fk',
|
||||
@@ -1676,14 +1681,15 @@ __all__ = [
|
||||
'documentation',
|
||||
'extraOptions',
|
||||
'user_interface',
|
||||
'show',
|
||||
]
|
||||
|
||||
|
||||
def show():
|
||||
"""
|
||||
便捷函数:启动 IK/FK Switcher UI
|
||||
Convenience function: Launch IK/FK Switcher UI
|
||||
|
||||
使用方法:
|
||||
Usage:
|
||||
import animation_tools.ik_fk_switcher as ikfk
|
||||
ikfk.show()
|
||||
"""
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
|
||||
"""
|
||||
Studio Library Wrapper Module
|
||||
用于简化 Studio Library 的导入和使用
|
||||
支持 Maya 2017-2026+ 所有版本
|
||||
Simplify Studio Library import and usage
|
||||
Support Maya 2017-2026+ all versions
|
||||
|
||||
使用方法:
|
||||
Usage:
|
||||
import animation_tools.studiolibrary
|
||||
animation_tools.studiolibrary.show()
|
||||
"""
|
||||
@@ -14,36 +14,53 @@ Studio Library Wrapper Module
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 获取当前目录
|
||||
# Get current directory
|
||||
_current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# 全局变量用于存储导入的模块
|
||||
# Global variable to store imported module
|
||||
_studiolibrary_module = None
|
||||
__version__ = "2.20.2"
|
||||
|
||||
def _ensure_studiolibrary_loaded():
|
||||
"""确保 studiolibrary 模块已加载"""
|
||||
"""Ensure studiolibrary module is loaded"""
|
||||
global _studiolibrary_module
|
||||
|
||||
if _studiolibrary_module is not None:
|
||||
return _studiolibrary_module
|
||||
|
||||
# 添加所有必要的路径
|
||||
# Add all necessary paths
|
||||
_inner_studiolibrary = os.path.join(_current_dir, 'studiolibrary')
|
||||
for _subdir in ['studiolibrary', 'studiolibrarymaya', 'mutils', 'studioqt', 'studiovendor']:
|
||||
for _subdir in ['studiolibrarymaya', 'mutils', 'studioqt', 'studiovendor']:
|
||||
_subdir_path = os.path.join(_current_dir, _subdir)
|
||||
if _subdir_path not in sys.path:
|
||||
sys.path.insert(0, _subdir_path)
|
||||
|
||||
# 导入 studiolibrary
|
||||
import studiolibrary
|
||||
_studiolibrary_module = studiolibrary
|
||||
# Import from inner studiolibrary by temporarily manipulating sys.path
|
||||
# Remove current directory to avoid circular import
|
||||
_saved_path = sys.path[:]
|
||||
if _current_dir in sys.path:
|
||||
sys.path.remove(_current_dir)
|
||||
|
||||
# Add inner studiolibrary to the front
|
||||
if _inner_studiolibrary not in sys.path:
|
||||
sys.path.insert(0, _inner_studiolibrary)
|
||||
|
||||
try:
|
||||
import studiolibrary
|
||||
_studiolibrary_module = studiolibrary
|
||||
finally:
|
||||
# Restore sys.path
|
||||
sys.path = _saved_path
|
||||
# But keep the inner studiolibrary path
|
||||
if _inner_studiolibrary not in sys.path:
|
||||
sys.path.insert(0, _inner_studiolibrary)
|
||||
|
||||
return _studiolibrary_module
|
||||
|
||||
def version():
|
||||
return __version__
|
||||
|
||||
# 导出所有公共接口
|
||||
# Export all public interfaces
|
||||
__all__ = [
|
||||
'__version__',
|
||||
'version',
|
||||
@@ -54,14 +71,14 @@ __all__ = [
|
||||
|
||||
def show(*args, **kwargs):
|
||||
"""
|
||||
便捷函数:启动 Studio Library
|
||||
Convenience function: Launch Studio Library
|
||||
|
||||
Args:
|
||||
*args: 传递给 main() 的位置参数
|
||||
**kwargs: 传递给 main() 的关键字参数
|
||||
*args: Positional arguments passed to main()
|
||||
**kwargs: Keyword arguments passed to main()
|
||||
|
||||
Returns:
|
||||
LibraryWindow: Studio Library 窗口实例
|
||||
LibraryWindow: Studio Library window instance
|
||||
|
||||
Example:
|
||||
>>> import animation_tools.studiolibrary
|
||||
@@ -72,14 +89,14 @@ def show(*args, **kwargs):
|
||||
|
||||
def main(*args, **kwargs):
|
||||
"""
|
||||
启动 Studio Library 主窗口
|
||||
Launch Studio Library main window
|
||||
|
||||
Args:
|
||||
*args: 传递给 main() 的位置参数
|
||||
**kwargs: 传递给 main() 的关键字参数
|
||||
*args: Positional arguments passed to main()
|
||||
**kwargs: Keyword arguments passed to main()
|
||||
|
||||
Returns:
|
||||
LibraryWindow: Studio Library 窗口实例
|
||||
LibraryWindow: Studio Library window instance
|
||||
"""
|
||||
lib = _ensure_studiolibrary_loaded()
|
||||
return lib.main(*args, **kwargs)
|
||||
@@ -87,10 +104,10 @@ def main(*args, **kwargs):
|
||||
|
||||
def isMaya():
|
||||
"""
|
||||
检查是否在 Maya 环境中运行
|
||||
Check if running in Maya environment
|
||||
|
||||
Returns:
|
||||
bool: 如果在 Maya 中返回 True,否则返回 False
|
||||
bool: True if in Maya, False otherwise
|
||||
"""
|
||||
try:
|
||||
import maya.cmds
|
||||
|
||||
@@ -174,7 +174,7 @@ global proc shelf_Nexus_Animation () {
|
||||
-style "iconOnly"
|
||||
-marginWidth 0
|
||||
-marginHeight 1
|
||||
-command "import sys\nimport os\nstudiolibrary_path = r'h:\\Workspace\\Raw\\Tools\\Plugins\\Maya\\2023\\scripts\\animation_tools\\studiolibrary'\nif studiolibrary_path not in sys.path:\n sys.path.insert(0, studiolibrary_path)\nimport studiolibrary\nstudiolibrary.main()"
|
||||
-command "import animation_tools.studiolibrary as studiolib\nstudiolib.show()"
|
||||
-sourceType "python"
|
||||
-commandRepeatable 1
|
||||
-flat 1
|
||||
|
||||
Reference in New Issue
Block a user