Проблема с MFnNurbsSurface.closestPoint в API OpenMaya 2.0

Недавно мне стало известно о python OpenMaya API v2.0, поэтому я просматривал свой код и пытался обновить его, чтобы использовать версию 2.0. По большей части это имело для меня гораздо больше смысла, чем старая версия OpenMaya...

Я столкнулся с проблемой при попытке использовать метод OpenMaya.MFnNurbsSurface.closestPoint. Кажется, я не могу понять, как на самом деле использовать kwargs для этого метода. Документы Maya говорят следующее:

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 единицы вверх по оси y и сравнив вывод двух функций со следующими строками:

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

Другие вещи, которые я пытался сделать с помощью строки «closestPoint» в моей функции:

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 #

Некоторые различия в выводе просто странны для меня, и ошибки кажутся бессмысленными (например, различия при настройке значения аргумента «допуск»)... Кроме того, оказывается, что значения uv равные 0,5 правильное совпадение - если я перемещаю и/или поворачиваю плоскость, старая функция возвращает разные значения uv, в то время как новая функция всегда возвращает 0,5, поскольку она оценивает контрольную точку из пространства объекта плоскости, а не использует мировое пространство.

Я также просмотрел документы для соответствующей старой команды OpenMaya, где было две записи, одна из которых имеет логический аргумент «paramAsStart», который можно использовать, если вы собираетесь указать некоторые начальные значения uv. Думая, что документы 2.0, возможно, пропустили это, я попытался добавить это и в свою попытку API 2.0... Это тоже не сработало (выдало мне ошибку, которую я передал слишком много аргументов).

Как минимум, мне нужно выяснить, как заставить его оценивать контрольную точку из мирового пространства; Однако, поскольку я продолжаю использовать API OpenMaya 2.0, я уверен, что снова столкнусь с этим типом вещей (kwargs, которые, кажется, не работают...) - любая помощь в том, как на самом деле использовать эти kwargs, приветствуется. !

ИЗМЕНИТЬ:

больше тестов - после ответа теодокса я догадался, что в документах может быть неправильный порядок аргументов... Итак, я решил проверить перестановки. Предполагая, что uStart и vStart всегда будут рядом друг с другом, мы получаем 24 перестановки "kwargs", но я решил также попробовать None, 0.0 и 0 для их значений (72 теста!). Ошибка ВСЕ.

Вот мои тестовые строки:

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 #

Я могу опубликовать строку/ошибки, если кому-то интересно...

Итак, я предполагаю, что это ошибка майя - бле...


person silent_sight    schedule 09.08.2017    source источник


Ответы (2)


Я думаю, что это особенность того, как генерируются документы. версия C++ записывает аргументы по умолчанию таким образом, что программист на Python выглядит как kwargs... но на самом деле это не 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.

person theodox    schedule 16.08.2017
comment
Да, я тоже пробовал это и получил TypeError (ожидаемый целочисленный аргумент, получил число с плавающей запятой). Я также пытался использовать None для uStart/vStart, а также 0 и 0.0. Вы можете видеть, что мой последний пример теста/результата - это в основном то, что вы предложили, но он также дерьмо... Спасибо за дополнительную информацию о документах C ++, хотя - приятно знать, что я не схожу с ума, думая, что kwargs не т работает... - person silent_sight; 16.08.2017

Я также разместил это на форумах Autodesk Maya ... Оказывается, в этом есть известная ошибка.

Вот ссылка на тема форума Maya, если кому-то интересно

person silent_sight    schedule 16.08.2017