相同的 python 代码在不同的 Maya 上运行不同(2012 - 2015)

Same python code works differently on differently Maya (2012 - 2015)

这个简单的代码

import maya.cmds as cmd

circle1 = cmd.circle(nr=(0, 0, 1), c=(0, -1.1, 0), ch=1)
circle2 = cmd.duplicate(circle1[0], ic=1)
circle3 = cmd.duplicate(circle1[0], ic=1)
cmd.setAttr(circle2[0] + '.rotateZ', 120)
cmd.setAttr(circle3[0] + '.rotateZ', -120)

allCurves = circle1[0], circle2[0], circle3[0]
cmd.select(allCurves)
cmd.makeIdentity(apply=True, t=1, r=1, s=1, n=0)

在 Maya 2012 中完美运行,给我这样的结果:

相反,在 Maya 2015 中,相同代码的结果是这样的:

所有的圆都移动到原点。

似乎命令 cmd.makeIdentity 的工作方式不同,但阅读 maya 文档命令是相同的。构建历史设置也相同。我不明白玛雅在背后做了什么。

为什么这行代码的工作方式不同?

重复输入连接有问题。 以前,有一个错误。可能...不确定。

工作代码:

import maya.cmds as cmd

circle1 = cmd.circle(nr=(0, 0, 1), c=(0, -1.1, 0), ch=1)
circle2 = cmd.duplicate(circle1[0], ic=0) #InputConnections=0
circle3 = cmd.duplicate(circle1[0], ic=0) #InputConnections=0
cmd.setAttr(circle2[0] + '.rotateZ', 120)
cmd.setAttr(circle3[0] + '.rotateZ', -120)

allCurves = circle1[0], circle2[0], circle3[0]
cmd.select(allCurves)
cmd.makeIdentity(apply=True, t=1, r=1, s=1, n=0)

如果您将 makeIdentity 向上移动到链中,它可以直观地工作:

circle1 = cmds.circle(nr=(0, 0, 1), c=(0, -1.1, 0), ch=1)
circle2 = cmds.duplicate(circle1[0], ic=1)
circle3 = cmds.duplicate(circle1[0], ic=1)
cmds.makeIdentity(apply=True, t=1, r=1, s=1, n=0)
cmds.setAttr(circle2[0] + '.rotateZ', 120)
cmds.setAttr(circle3[0] + '.rotateZ', -120)

真正的问题是 MakeIdentity 更改了几何图形以允许在保留相同外观的同时将拥有的变换清零;如果您共享形状 (ic=True),那么当您在多个对象上调用它时,结果是随机的。检查您的历史记录,您应该在圆形上看到多个 'transformGeometry' 个节点,每个节点都试图影响几何形状。

如果您想要在本地全部清零的实例,添加另一个转换可能更容易。

真正的问题是新 Maya (2015) 在节点共享 history/connections/nodes 时执行 makeIdentity 准备的方式可能存在错误(在本例中 makeNurbCircle 节点)。它似乎正在创建临时 transformGeometry 节点来补偿链中错误顺序的待冻结转换。在 Maya 2012 中情况并非如此,当时的顺序似乎是正确的。如果您查看下面的比较,您就会明白为什么。

左边是2012;右边是 2015 年:

无论哪种方式,如果您想保留此共享历史记录并出于任何原因以这种方式进行冻结转换,您可能必须手动执行 makeIdentity 尝试执行的操作,但以您想要的更简洁的方式到;即在手动冻结转换之前以正确的顺序正确连接 transformGeometry 节点(使用 xform)。

这是我刚刚想到的事情:(我会在以后有时间时用评论和解释更新答案)

import maya.cmds as cmds


def makeIdentityCurvesWithSharedHistory(curves=[]):
    for curve in curves:
        curveShape = cmds.listRelatives(curve, shapes=True)[0]    
        makeCircle = cmds.listConnections(curveShape, type='makeNurbCircle')[0]
        transformation = cmds.xform(curve, q=True, matrix=True)    
        transformGeoNode = cmds.createNode('transformGeometry')
        cmds.setAttr('%s.transform' % transformGeoNode, transformation, type='matrix')
        cmds.connectAttr('%s.outputCurve' % makeCircle, '%s.inputGeometry' % transformGeoNode)
        cmds.connectAttr('%s.outputGeometry' % transformGeoNode, '%s.create' % curveShape, force=True)
        cmds.xform(curve, matrix=[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0])


circle1 = cmd.circle(nr=(0, 0, 1), c=(0, -1.1, 0), ch=1)
circle2 = cmd.duplicate(circle1[0], ic=1)
circle3 = cmd.duplicate(circle1[0], ic=1)
cmd.setAttr(circle2[0] + '.rotateZ', 120)
cmd.setAttr(circle3[0] + '.rotateZ', -120)

allCurves = circle1[0], circle2[0], circle3[0]
makeIdentityCurvesWithSharedHistory(allCurves)

如果使用上面的代码:

免责声明:理论上,这应该适用于任何版本的 Maya;但我只在 Maya 2015 上测试过它。