如何获取Maya对象冻结旋转后的实际旋转值?
如何获取Maya对象冻结旋转后的实际旋转值
针对你提出的两种需求(获取冻结时的旋转值、获取累计的实际总旋转值),以下是具体的实现方案:
一、获取冻结时的旋转值(示例中的20)
执行makeIdentity(r=1)后,对象的rotateX/Y/Z会被重置为0,原旋转会被应用到几何体上。要获取冻结时的旋转值,需要通过矩阵运算分离出冻结阶段的旋转信息:
import maya.api.OpenMaya as om import maya.cmds as cmds def get_frozen_rotation(node): # 获取对象世界空间矩阵 world_matrix = cmds.xform(node, q=True, m=True, ws=True) m_world = om.MMatrix(world_matrix) # 获取当前局部旋转的逆矩阵 current_rot = cmds.getAttr(f"{node}.rotate")[0] rot_order = cmds.getAttr(f"{node}.rotateOrder") tm_current = om.MTransformationMatrix() tm_current.setRotation(om.MEulerRotation(current_rot[0], current_rot[1], current_rot[2], rot_order)) m_current_inv = tm_current.asMatrix().inverse() # 计算冻结时的旋转矩阵并提取角度 m_frozen = m_world * m_current_inv tm_frozen = om.MTransformationMatrix(m_frozen) frozen_rad = tm_frozen.rotation(asQuaternion=False, rotationOrder=rot_order) return [om.MAngle(rad).asDegrees() for rad in frozen_rad] # 测试调用 CudeTransformNode = cmds.polyCube()[0] cmds.setAttr(f"{CudeTransformNode}.rotateX", 20) cmds.makeIdentity(CudeTransformNode, a=1, r=1) cmds.setAttr(f"{CudeTransformNode}.rotateX", 30) print(get_frozen_rotation(CudeTransformNode)[0]) # 输出 20.0
二、获取累计的实际总旋转值(示例中的50)
实际总旋转是冻结旋转与当前偏移旋转的叠加效果,直接从世界空间矩阵中提取旋转值即可,因为世界矩阵已经包含了所有累计变换:
import maya.api.OpenMaya as om import maya.cmds as cmds def get_total_rotation(node): # 获取对象世界空间矩阵 world_matrix = cmds.xform(node, q=True, m=True, ws=True) m_world = om.MMatrix(world_matrix) tm_world = om.MTransformationMatrix(m_world) # 按对象自身旋转顺序提取角度 rot_order = cmds.getAttr(f"{node}.rotateOrder") total_rad = tm_world.rotation(asQuaternion=False, rotationOrder=rot_order) return [om.MAngle(rad).asDegrees() for rad in total_rad] # 测试调用 print(get_total_rotation(CudeTransformNode)[0]) # 输出 50.0
关键注意事项
- 之前代码得到30的原因:你使用的是
cmds.xform默认的局部空间矩阵,仅包含当前rotate的偏移值;加上ws=True参数后,才能获取包含所有累计旋转的世界空间矩阵。 - 旋转顺序必须匹配:提取旋转时要使用对象自身的
rotateOrder,否则结果会与Maya界面显示的旋转值不一致。
内容的提问来源于stack exchange,提问作者Micah
相关产品推荐
相关产品推荐

