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 时的问题。当您 运行 一个 attributeQuery 说 exists = 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
这样写可以在出现问题时更轻松地插入调试打印输出。
我是 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 时的问题。当您 运行 一个 attributeQuery 说 exists = 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
这样写可以在出现问题时更轻松地插入调试打印输出。