python 忽略 maya 中的两个条件之一

python ignoring one of the 2 conditions in maya

我是 python(20 天)的新手,但我已经在 Maya 中创建了一些东西,例如拾取器、ik-fk 捕捉器,以及其他一些东西。现在我正在尝试创建一个按钮来镜像姿势。

问题是我必须为我的 if 循环提供 2 个条件,但 maya 忽略了第二个条件

import maya.cmds as cmds

cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]



for i in range(len (attr) ):

    for x in range(len (targetOBJ) ):
        if (cmds.attributeQuery(attr[i], node = targetOBJ[x], exists = True) \
        and cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)): 
            newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
            cmds.setAttr(baseOBJ[x] + '.' + attr[i], newValue)
        else:
            pass

错误是: 错误:RuntimeError: file <maya console> line 17: setAttr: The attribute 'arm_lf_FK_ctrl1.translateX' is locked or connected and cannot be modified. #

但在 if 循环中我写了:cmds.getAttr(targetOBJ[x] + '.' + attr[i], lock = False)

有什么提示吗?

编辑解决方案:

这里是固定的代码

import maya.cmds as cmds

cmds.select('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
baseOBJ = cmds.ls(sl=True)
cmds.select('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
targetOBJ = cmds.ls(sl=True)
attr = ['translateX', 'translateY', 'translateZ', 'rotateX', 'rotateY', 'rotateZ', 'IK' ]



    for i in range(len (attr) ):

        for x in range(len (baseOBJ) ):
            if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
            and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)): 
                newValue = cmds.getAttr(baseOBJ[x] + '.' + attr[i])
                cmds.setAttr(targetOBJ[x] + '.' + attr[i], newValue)
            else:
                pass

我不了解 maya,但看起来问题发生在第一个条件本身,因此第二个被忽略了。此外,异常说明了 运行ning setAttr 时的问题。当您 运行 一个 attributeQueryexists = True[ 时将调用此函数=18=],这实际上意味着如果属性不存在,您将最终添加该属性。

您需要指定

cmds.getAttr(item + attribute, lock=True)

即使您正在检查您希望被锁定的属性:'lock = true' 表示 'tell me the lock state', 而不是 'tell me if lock is true'。

您可以使用三个常见的 python 技巧(并且不添加额外的选择,这只会复制您传入的列表)更简单地完成此操作

第一种是使用 foreach 循环——直接从列表中获取值——而不是使用数组索引。这是在 python 中进行循环的标准方法。所以而不是

for index in range(len(list_of_things)):
    do_something(list_of_things[index])

你就这样

for item in list_of_things:
   do_something(item)

第二种是使用 zip() 来匹配列表并成对循环它们:这使得编写在保持值同步时清晰读取的循环变得容易得多。

最后一件事是使用 try...except 并允许某些类型的错误发生而不是预先检查。这是一个常见的 python 技巧,因为异常并不昂贵,而且生成的代码通常更具可读性。

将这些放在一起,您可以像这样执行相同的代码:

sources = ('arm_lf_FK_ctrl1', 'arm_lf_FK_ctrl2', 'arm_lf_FK_ctrl3')
targets  = ('arm_rt_FK_ctrl1', 'arm_rt_FK_ctrl2', 'arm_rt_FK_ctrl3')
attr = ('.translateX', '.translateY', '.translateZ', '.rotateX', '.rotateY', '.rotateZ', '.IK' )

for source, target in zip(sources, targets):
    for attrib in attr:
        try:
            val = cmds.getAttr(source + attrib)
            cmds.setAttr(target + attrib, val)
        except Exception as e:
            print 'skipped', source + attrib, target + attrib

在这种情况下,如果您将错误的对象、错误的属性传递给 Maya,或者您尝试设置锁定的属性,Maya 将抛出 RuntimeError。你真的需要比我在这里更小心地检查,这取决于当系统试图做一些不可能的事情时你想做什么。

让您的生活更轻松的最后一个技巧是将您的条件检查与逻辑分开。而不是

 if (cmds.attributeQuery(attr[i], node = baseOBJ[x], exists = True) \
        and cmds.getAttr(baseOBJ[x] + '.' + attr[i], lock = False)): 

您可能会发现长 运行 做起来更容易:

  exists, locked = False
  try:
      exists = cmds.ls(object + attrib) is not None
      locked = cmds.getAttr(object + attrib, lock = True)
  except:
      pass # if the object or attrib is missing, both vals will still be false    
  if exists and not locked:
      #do something

这样写可以在出现问题时更轻松地插入调试打印输出。