【问题标题】:Same python code works differently on differently Maya (2012 - 2015)相同的 python 代码在不同的 Maya 上的工作方式不同(2012 - 2015)
【发布时间】:2015-06-19 09:42:01
【问题描述】:

这个简单的代码

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 文档命令是相同的。构建历史设置也相同。我不明白 Maya 在幕后做了什么。

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

【问题讨论】:

    标签: python maya maya-api


    【解决方案1】:

    真正的问题是由于新 Maya (2015) 在节点具有共享历史/连接/节点(在本例中为 makeNurbCircle 节点)时为 makeIdentity 执行准备的方式中可能存在错误。它似乎正在创建临时transformGeometry 节点以补偿链中错误顺序的待冻结变换。在 Maya 2012 中情况并非如此,当时的顺序似乎是正确的。如果您查看下面的比较,您就会明白原因。

    左边是 2012 年;右边是 2015 年:

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

    这是我刚刚开始做的事情:(我会在稍后找到时间时用 cmets 和解释更新答案)

    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 上测试过。

    【讨论】:

      【解决方案2】:

      如果您将 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”节点,每个节点都试图影响几何形状。

      如果您希望实例在本地全部归零,那么添加另一个转换可能更容易。

      【讨论】:

        【解决方案3】:

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

        工作代码:

        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)
        

        【讨论】:

        • 不幸的是,我需要ic=True,因为代码示例是整个工具的一部分。我也尝试使用ic=0 并稍后连接输入,但问题再次出现。
        猜你喜欢
        • 2017-02-10
        • 1970-01-01
        • 1970-01-01
        • 2017-09-08
        • 1970-01-01
        • 2016-11-08
        • 2012-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多