This commit is contained in:
2025-11-24 22:26:56 +08:00
parent e4c713035b
commit 719058ff01
8 changed files with 310 additions and 33 deletions

View File

@@ -111,26 +111,42 @@ def getSkinClusterInfo(objectName, saveJointInfo=False):
return False
def getSkinJointInformation(influences):
"""
获取骨骼信息(父节点、矩阵、旋转、关节方向)
兼容 PyMEL 和 cmds处理无父节点的情况
"""
jointInformation = {}
for inf in influences:
jointInfo = {}
if pm:
infNode = pm.PyNode(inf)
jointInfo["parent"] = str(infNode.getParent().name())
jointInfo["matrix"] = infNode.getMatrix(worldSpace=True)
jointInfo["rotation"] = infNode.getRotation()
jointInfo["jointOrient"] = infNode.getAttr("jointOrient")
jointInformation[str(infNode)] = copy.deepcopy(jointInfo)
else:
# cmds 版本
infName = str(inf)
parents = cmds.listRelatives(infName, parent=True)
jointInfo["parent"] = parents[0] if parents else ""
jointInfo["matrix"] = cmds.xform(infName, q=True, matrix=True, worldSpace=True)
jointInfo["rotation"] = cmds.xform(infName, q=True, rotation=True)
jointInfo["jointOrient"] = cmds.getAttr(infName + ".jointOrient")[0]
jointInformation[infName] = copy.deepcopy(jointInfo)
try:
if pm:
infNode = pm.PyNode(inf)
# 安全获取父节点,避免 None.name() 错误
parent = infNode.getParent()
jointInfo["parent"] = str(parent.name()) if parent else ""
jointInfo["matrix"] = infNode.getMatrix(worldSpace=True)
jointInfo["rotation"] = infNode.getRotation()
jointInfo["jointOrient"] = infNode.getAttr("jointOrient")
jointInformation[str(infNode)] = copy.deepcopy(jointInfo)
else:
# cmds 版本
infName = str(inf)
parents = cmds.listRelatives(infName, parent=True)
jointInfo["parent"] = parents[0] if parents else ""
jointInfo["matrix"] = cmds.xform(infName, q=True, matrix=True, worldSpace=True)
jointInfo["rotation"] = cmds.xform(infName, q=True, rotation=True)
jointInfo["jointOrient"] = cmds.getAttr(infName + ".jointOrient")[0]
jointInformation[infName] = copy.deepcopy(jointInfo)
except Exception as e:
print(f"Warning: Failed to get joint information for {inf}: {e}")
# 使用默认值
jointInfo["parent"] = ""
jointInfo["matrix"] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
jointInfo["rotation"] = [0, 0, 0]
jointInfo["jointOrient"] = [0, 0, 0]
jointInformation[str(inf)] = copy.deepcopy(jointInfo)
return jointInformation
def getMPlugObjects(MFnSkinCluster):
@@ -350,10 +366,16 @@ def buildSkinWeightsDict(objectList, showLoadingBar=True, saveJointInfo=False):
sourceWeightDict = {}
for object in objectList:
if pm:
objectAsString = pm.PyNode(object).name()
else:
# cmds 版本 - object 已经是字符串
try:
if pm:
# 安全转换为字符串,处理可能的 None 或无效对象
obj_node = pm.PyNode(object) if not isinstance(object, pm.PyNode) else object
objectAsString = str(obj_node.name()) if obj_node else str(object)
else:
# cmds 版本 - object 已经是字符串
objectAsString = str(object)
except Exception as e:
print(f"Warning: Failed to process object {object}: {e}")
objectAsString = str(object)
if showLoadingBar:
@@ -394,7 +416,11 @@ def transferSkinWeights(transferNodes=None, showLoadingBar=True):
if len(transferNodes):
sourceObj = transferNodes[0]
sourceName = sourceObj.name()
# 安全获取名称
try:
sourceName = str(sourceObj.name()) if hasattr(sourceObj, 'name') else str(sourceObj)
except:
sourceName = str(sourceObj)
targetNameList = transferNodes[1:]
loadBarMaxVal = len(targetNameList)
@@ -410,7 +436,11 @@ def transferSkinWeights(transferNodes=None, showLoadingBar=True):
# deep copy because: Mutable datatypes
sourceWeightDictCopy = copy.deepcopy(sourceWeightDict)
targetName = str(tgtObject.name())
# 安全获取名称
try:
targetName = str(tgtObject.name()) if hasattr(tgtObject, 'name') else str(tgtObject)
except:
targetName = str(tgtObject)
barycentrWeightDict = apiUtils.getBarycentricWeights(sourceName, targetName)