在OpenMaya api 2.0

时间:2017-08-09 21:15:39

标签: python maya maya-api

我最近开始意识到python OpenMaya api v2.0,所以我一直在浏览我的代码并尝试更新它以使用2.0版本。在大多数情况下,它对我来说比旧版OpenMaya更有意义......

在尝试使用OpenMaya.MFnNurbsSurface.closestPoint方法时,我遇到了麻烦。我似乎无法弄清楚如何将kwargs用于该方法。玛雅的文档说:

closestPoint(testPoint, uStart=None, vStart=None,
    ignoreTrimBoundaries=False, tolerance=kPointTolerance,
    space=kObject) -> (MPoint, float, float)

所以对我来说,这看起来像我应该能够使用的kwargs ......但是每次我尝试使用它时都会出现错误 - 当它没有错误时,我不会'我真的明白为什么它没有(下面的例子)。如果我没有放入kwargs,那么它的工作原理就是'但是我没有给出正确的结果,因为我确实需要改变其中的一些kwargs。

这里有一些旧的和新的方法代码(新的就是我到目前为止......):

import maya.OpenMaya as oldOM
import maya.api.OpenMaya as om

def getClosestPointOnSurfaceOLD(surf, position):
    selList = oldOM.MSelectionList()
    selList.add(surf)
    mDagPath = oldOM.MDagPath()
    selList.getDagPath(0, mDagPath)
    surfFn = oldOM.MFnNurbsSurface(mDagPath)

    u_util = oldOM.MScriptUtil()
    u_util.createFromDouble(0)
    u_param = u_util.asDoublePtr()

    v_util = oldOM.MScriptUtil()
    v_util.createFromDouble(0)
    v_param = v_util.asDoublePtr()

    p = surfFn.closestPoint(oldOM.MPoint(*position), u_param, v_param, False, 1.0, oldOM.MSpace.kWorld)

    return [(p[0], p[1], p[2]), (oldOM.MScriptUtil.getDouble(u_param), oldOM.MScriptUtil.getDouble(v_param))]

def getClosestPointOnSurfaceNEW(surf, position):
    selList = om.MSelectionList()
    selList.add(surf)
    surfFn = om.MFnNurbsSurface(selList.getDagPath(0))

    p, u, v = surfFn.closestPoint(om.MPoint(*position), ignoreTrimBoundaries=False, tolerance=1.0, space=om.MSpace.kWorld)

    return [(p[0], p[1], p[2]), (u, v)]

我通过创建nurbsPlane(默认值)然后将其向上移动0.5个单位并将这两个函数的输出与这些行进行比较来测试它:

getClosestPointOnSurfaceOLD('nurbsPlane1', (0.0, 1.0, 0.0))
getClosestPointOnSurfaceNEW('nurbsPlane1', (0.0, 1.0, 0.0))

# Result: [(-2.7755575615628914e-17, 0.5, 2.7755575615628914e-17), (0.5, 0.5)] # <-- old function result
# Error: TypeError: file <maya console> line 28: integer argument expected, got float # <-- new function result

我尝试过的最近点的其他事情&#39;我的职能部分:

surfFn.closestPoint(om.MPoint(*position), ignoreTrimBoundaries=False)
# Result: [(-2.7755575615628914e-17, -1.5407439555097887e-33, 2.7755575615628914e-17), (0.5, 0.5)] #

surfFn.closestPoint(om.MPoint(*position), False)
# Result: [(-1.1102230246251565e-16, -6.162975822039155e-33, 1.1102230246251565e-16), (0.5, 0.5)] #

surfFn.closestPoint(om.MPoint(*position), tolerance=1.0)
# Error: TypeError: file <maya console> line 28: integer argument expected, got float #

surfFn.closestPoint(om.MPoint(*position), tolerance=1)
# Error: RuntimeError: file <maya console> line 28: More keyword list entries (6) than format specifiers (5) #

surfFn.closestPoint(om.MPoint(*position), 1.0)
# Result: [(-1.1102230246251565e-16, -6.162975822039155e-33, 1.1102230246251565e-16), (0.5, 0.5)] #

surfFn.closestPoint(om.MPoint(*position), space=om.MSpace.kWorld)
# Error: RuntimeError: file <maya console> line 28: More keyword list entries (6) than format specifiers (5) #

surfFn.closestPoint(om.MPoint(*position), om.MSpace.kWorld)
# Result: [(-1.1102230246251565e-16, -6.162975822039155e-33, 1.1102230246251565e-16), (0.5, 0.5)] #

surfFn.closestPoint(om.MPoint(*position))
# Result: [(-2.7755575615628914e-17, -1.5407439555097887e-33, 2.7755575615628914e-17), (0.5, 0.5)] #

surfFn.closestPoint(om.MPoint(*position), False, 1.0, om.MSpace.kWorld)
# Result: [(-2.7755575615628914e-17, 3.851859888774472e-33, -6.938893903907228e-17), (0.5, 0.5000000000000001)] #

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), uStart=0.0, vStart=0.0, ignoreTrimBoundaries=False, tolerance=1.0, space=om.MSpace.kWorld)
# Error: TypeError: file <maya console> line 28: integer argument expected, got float #

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, False, 1.0, om.MSpace.kWorld)
# Error: TypeError: file <maya console> line 28: integer argument expected, got float #

输出中的一些差异对我来说很奇怪,错误似乎没有意义(比如调整“容忍度”值时的差异)......此外,事实证明0.5的uv值是正确的只是巧合 - 如果我移动和/或旋转平面,旧函数返回不同的uv值,而新函数总是返回0.5,因为它评估测试点来自飞机的物体空间,而不是使用世界空间。

我还看了相应的旧OpenMaya命令的文档,其中有两个条目 - 其中一个条目有一个&#39; paramAsStart&#39;如果要提供一些启动uv值,则使用boolean arg。考虑到2.0文档可能已经错过了,我尝试将其添加到我的api 2.0尝试中......它也没有工作(给了我一个错误,我通过了太多的args)。

至少,我需要弄清楚如何让它从世界空间评估测试点;但是,当我继续使用OpenMaya api 2.0时,我确定我会再遇到这种类型的东西(kwargs似乎无法正常工作......) - 任何有关如何使用的帮助实际上使用这些kwargs表示赞赏!

修改

更多的测试 - 在正统答案之后,我猜测文档的arg顺序可能不正确......所以,我决定测试排列。假设uStartvStart总是彼此相邻,则会给出&#34; kwargs&#34;的24个排列。但我决定尝试None,0.0和0作为他们的值(72次测试!)。 ALL 出错。

以下是我的测试行:

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, False, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, False, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, 1.0, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, 1.0, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, om.MSpace.kWorld, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), None, None, om.MSpace.kWorld, 1.0, False)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, None, None, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, None, None, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, None, None, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, om.MSpace.kWorld, None, None)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, None, None, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, 1.0, None, None)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, None, None, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, None, None, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, None, None, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, om.MSpace.kWorld, None, None)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, None, None, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, False, None, None)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, None, None, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, None, None, 1.0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, None, None, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, 1.0, None, None)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, None, None, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, False, None, None)



surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, False, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, False, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, 1.0, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, 1.0, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, om.MSpace.kWorld, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0.0, 0.0, om.MSpace.kWorld, 1.0, False)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 0.0, 0.0, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 0.0, 0.0, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, 0.0, 0.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, om.MSpace.kWorld, 0.0, 0.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, 0.0, 0.0, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, 1.0, 0.0, 0.0)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, 0.0, 0.0, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, 0.0, 0.0, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, 0.0, 0.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, om.MSpace.kWorld, 0.0, 0.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, 0.0, 0.0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, False, 0.0, 0.0)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 0.0, 0.0, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 0.0, 0.0, 1.0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, 0.0, 0.0, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, 1.0, 0.0, 0.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, 0.0, 0.0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, False, 0.0, 0.0)



surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, False, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, False, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, 1.0, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, 1.0, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, om.MSpace.kWorld, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 0, 0, om.MSpace.kWorld, 1.0, False)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 0, 0, 1.0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 0, 0, om.MSpace.kWorld, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, 0, 0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, 1.0, om.MSpace.kWorld, 0, 0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, 0, 0, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), False, om.MSpace.kWorld, 1.0, 0, 0)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, 0, 0, False, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, 0, 0, om.MSpace.kWorld, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, 0, 0, om.MSpace.kWorld)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, False, om.MSpace.kWorld, 0, 0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, 0, 0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), 1.0, om.MSpace.kWorld, False, 0, 0)

surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 0, 0, False, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 0, 0, 1.0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, 0, 0, 1.0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, False, 1.0, 0, 0)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, 0, 0, False)
surfFn.closestPoint(om.MPoint(0.0, 1.0, 0.0), om.MSpace.kWorld, 1.0, False, 0, 0)

这些是常见的错误:

# Error: RuntimeError: file <maya console> line 1: More keyword list entries (6) than format specifiers (5) #
# Error: TypeError: file <maya console> line 1: integer argument expected, got float #
# Error: TypeError: file <maya console> line 1: an integer is required #
# Error: TypeError: file <maya console> line 1: a float is required #

如果有人有兴趣,我可以发布行/错误...

所以,我猜这是一个玛雅人的错误 - 咩......

2 个答案:

答案 0 :(得分:0)

我认为这是文档生成方式的一个怪癖。 C ++版本以一种类似于kwargs的Python程序员的方式编写默认参数..但它并不是真正的kwargs,它是默认参数。你必须将它们视为只是命名位置参数并按顺序提供它们。

这对我有用:

def getClosestPointOnSurfaceNEW(surf, position):
    selList = om.MSelectionList()
    selList.add(surf)
    surfFn = om.MFnNurbsSurface(selList.getDagPath(0))

    p, u, v = surfFn.closestPoint(om.MPoint(*position))

    return [(p[0], p[1], p[2]), (u, v)]

也是如此
    p, u, v = surfFn.closestPoint(om.MPoint(*position), 0, 0 )

通常,如果您想提供更多参数,通常只需按顺序执行:

p, u, v = surfFn.closestPoint(om.MPoint(*position), 0,0, False, 0.01, om.MSpace.kWorld)

但是我无法验证这是否有效,因为它会导致我的(测试版)Maya崩溃;不确定2017年或2018年的生产情况。

答案 1 :(得分:0)

我在Autodesk Maya论坛上发布了这个...结果发现了一个已知的错误。

如果有人好奇的话,这里是maya forum thread的链接