使用 python 在 Maya 中一次设置多个键和值的任何方法?

Any way to set multiple keys and values at once in Maya using python?

我正在寻找一个允许设置值列表的解决方案

[0,1,2]

超过给定的时间列表

[0,1,2]

一次,没有循环,像这样:

for frame, value in zip([0,1,2], [0,1,2]):
    cmds.keyframe(node, e=True, vc=value, t=frame)

有命令

cmds.setKeyframe()

cmds.keyframe()

允许在给定时间设置动画关键点 但是它们都不允许在时间范围(帧)内设置值范围。

相同的值可以放在时间范围上,但事实并非如此。

mel.eval("setKeyframe -e -v %s -t 0 -t 1 -t 2 %s" % (value, node))

我试图获取动画曲线节点的属性,其中存储了关键点, 但输出为空。

node = '...'
types = cmds.listAttr(node)

for t in types:
    if cmds.objExists(node+t):
        try:
            print t, cmds.getAttr(node+t)
        except:
            print 'failed with', t
            continue

...
keyTimeValue [()]
...

想通了。 这是有关动画曲线节点的文档。 https://download.autodesk.com/us/maya/2011help/Nodes/animCurveUU.html

可以看到,keyTimeValue属性本身不存储任何数据。 但它的属性 keyTimeValue.keyTime 和 keyTimeValue.keyValue 可以。

此命令如我所料运行:

def keyframe_range(node, values, id_range):

    eval("cmds.setAttr('%s.ktv[%s].kv', %s, size=%s)" % (
        node, id_range, ','.join([str(v) for v in values]), str(len(values))))

selected_id = cmds.keyframe(sl=True, query=True, iv=True)
index_range = '%s:%s' % (str(selected_id[0]), str(selected_id[-1]))
selected_curve = cmds.keyframe(query=True, name=True)
keyframe_range(selected_curve[0], values, index_range)

但是在Python 2.7 中一个函数最多可以有255 个参数。 一旦将值直接提供给函数, 一次最多只能处理255个键。

最新方法在 2019 Maya 中不起作用。 对于那些偶然发现的人,这是正确的代码。

def add_keys(plugName, times, values, changeCache=None):
    # Get the plug to be animated.
    sel = om.MSelectionList()
    sel.add(plugName)
    plug = om.MPlug()
    sel.getPlug(0, plug)
    # Create the animCurve.
    animfn = oma.MFnAnimCurve(plug)
    timeArray = om.MTimeArray()
    valueArray = om.MDoubleArray()

    for i in range(len(times)):
        timeArray.append(om.MTime(times[i], om.MTime.uiUnit()))
        valueArray.append(values[i])
    # Add the keys to the animCurve.
    animfn.addKeys(
        timeArray,
        valueArray,
        oma.MFnAnimCurve.kTangentGlobal,
        oma.MFnAnimCurve.kTangentGlobal,
        False,
        changeCache)