206 lines
6.3 KiB
Python
206 lines
6.3 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
Skin API UI Functions
|
||
提供权重导出、导入和解绑的用户界面函数
|
||
支持 Maya 所有版本,兼容 pymel 和 cmds
|
||
"""
|
||
|
||
# 尝试导入 pymel,如果不可用则使用 cmds
|
||
try:
|
||
import pymel.core as pm
|
||
except ImportError:
|
||
pm = None
|
||
|
||
import maya.cmds as cmds
|
||
import maya.mel as mel
|
||
|
||
try:
|
||
from . import apiVtxAttribs
|
||
except ImportError:
|
||
import rigging_tools.skin_api.apiVtxAttribs as apiVtxAttribs
|
||
|
||
|
||
def WeightExport():
|
||
"""
|
||
Export skin weights for selected objects
|
||
"""
|
||
try:
|
||
# 检查是否有选中物体
|
||
if pm:
|
||
selectedNodes = pm.ls(sl=True)
|
||
if not selectedNodes:
|
||
pm.warning("Please select at least one skinned object")
|
||
return
|
||
else:
|
||
selectedNodes = cmds.ls(sl=True)
|
||
if not selectedNodes:
|
||
cmds.warning("Please select at least one skinned object")
|
||
return
|
||
|
||
# 使用 ApiVtxAttribs 类导出权重
|
||
api = apiVtxAttribs.ApiVtxAttribs()
|
||
msg = api.exportSkinWeights(selected=True, saveJointInfo=True)
|
||
|
||
if msg:
|
||
print(msg)
|
||
if pm:
|
||
pm.confirmDialog(
|
||
title="Export Success",
|
||
message="Skin weights exported successfully!",
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
cmds.confirmDialog(
|
||
title="Export Success",
|
||
message="Skin weights exported successfully!",
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
print("Export cancelled")
|
||
|
||
except Exception as e:
|
||
error_msg = f"Failed to export skin weights: {str(e)}"
|
||
if pm:
|
||
pm.error(error_msg)
|
||
else:
|
||
cmds.error(error_msg)
|
||
|
||
|
||
def WeightImport():
|
||
"""
|
||
Import skin weights to selected or matching objects in scene
|
||
"""
|
||
try:
|
||
# 检查是否有选中物体
|
||
if pm:
|
||
selectedNodes = pm.ls(sl=True)
|
||
else:
|
||
selectedNodes = cmds.ls(sl=True)
|
||
useSelection = len(selectedNodes) > 0
|
||
|
||
print(f"Import mode: {'selected objects' if useSelection else 'all matching objects'}")
|
||
|
||
# 使用 ApiVtxAttribs 类导入权重
|
||
api = apiVtxAttribs.ApiVtxAttribs()
|
||
msg = api.importSkinWeights(selected=useSelection, stripJointNamespaces=False, addNewToHierarchy=True)
|
||
|
||
print(f"Import result: {repr(msg)}")
|
||
|
||
if msg and msg != False:
|
||
print(msg)
|
||
if "No valid objects found" in str(msg):
|
||
warning_msg = "No valid objects found in scene!\nMake sure:\n1. Object names match\n2. Vertex counts match\n3. Objects exist in scene"
|
||
if pm:
|
||
pm.warning(warning_msg)
|
||
pm.confirmDialog(
|
||
title="Import Failed",
|
||
message=warning_msg,
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
cmds.warning(warning_msg)
|
||
cmds.confirmDialog(
|
||
title="Import Failed",
|
||
message=warning_msg,
|
||
button=["OK"]
|
||
)
|
||
elif "Could not find" in str(msg):
|
||
if pm:
|
||
pm.warning(msg)
|
||
else:
|
||
cmds.warning(msg)
|
||
else:
|
||
# 成功导入
|
||
if pm:
|
||
pm.confirmDialog(
|
||
title="Import Complete",
|
||
message="Skin weights imported successfully!",
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
cmds.confirmDialog(
|
||
title="Import Complete",
|
||
message="Skin weights imported successfully!",
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
print("Import cancelled or no file selected")
|
||
|
||
except Exception as e:
|
||
import traceback
|
||
error_msg = f"Failed to import skin weights: {str(e)}\n{traceback.format_exc()}"
|
||
print(error_msg)
|
||
if pm:
|
||
pm.error(error_msg)
|
||
else:
|
||
cmds.error(error_msg)
|
||
|
||
|
||
def UnbindSkin():
|
||
"""
|
||
解绑选中物体的蒙皮
|
||
Unbind skin from selected objects
|
||
"""
|
||
try:
|
||
# 获取选中的物体
|
||
if pm:
|
||
selectedNodes = pm.ls(sl=True)
|
||
if not selectedNodes:
|
||
pm.warning("Please select at least one object")
|
||
return
|
||
else:
|
||
selectedNodes = cmds.ls(sl=True)
|
||
if not selectedNodes:
|
||
cmds.warning("Please select at least one object")
|
||
return
|
||
|
||
# 确认对话框
|
||
if pm:
|
||
result = pm.confirmDialog(
|
||
title="Unbind Skin",
|
||
message=f"Are you sure you want to unbind skin from {len(selectedNodes)} object(s)?",
|
||
button=["Yes", "No"],
|
||
defaultButton="Yes",
|
||
cancelButton="No",
|
||
dismissString="No"
|
||
)
|
||
else:
|
||
result = cmds.confirmDialog(
|
||
title="Unbind Skin",
|
||
message=f"Are you sure you want to unbind skin from {len(selectedNodes)} object(s)?",
|
||
button=["Yes", "No"],
|
||
defaultButton="Yes",
|
||
cancelButton="No",
|
||
dismissString="No"
|
||
)
|
||
|
||
if result != "Yes":
|
||
print("Unbind cancelled")
|
||
return
|
||
|
||
# 使用 MEL 命令解绑蒙皮
|
||
mel.eval('doDetachSkin "2" { "1","1" };')
|
||
print("Skin unbound successfully!")
|
||
|
||
if pm:
|
||
pm.confirmDialog(
|
||
title="Unbind Complete",
|
||
message="Skin unbound successfully!",
|
||
button=["OK"]
|
||
)
|
||
else:
|
||
cmds.confirmDialog(
|
||
title="Unbind Complete",
|
||
message="Skin unbound successfully!",
|
||
button=["OK"]
|
||
)
|
||
|
||
except Exception as e:
|
||
error_msg = f"Failed to unbind skin: {str(e)}"
|
||
if pm:
|
||
pm.error(error_msg)
|
||
else:
|
||
cmds.error(error_msg)
|