- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I've recently become aware of the python OpenMaya api v2.0, so I've been going through my code and trying to update it to use the 2.0 version. For the most part it has made a lot more sense to me than the older version of OpenMaya...
I've run into a snag while trying to use the OpenMaya.MFnNurbsSurface.closestPoint method. I can't seem to figure out how to actually use the kwargs for the method. Maya's docs say this:
closestPoint(testPoint, uStart=None, vStart=None, ignoreTrimBoundaries=False, tolerance=kPointTolerance, space=kObject) -> (MPoint, float, float)
So to me, that looks like kwargs that I should be able to use... but I get errors just about every time I try to use them - and when it doesn't error, I don't really understand why it didn't (examples below). If I don't put in the kwargs, it 'works' but doesn't give me the correct results since I actually do need to change some of those kwargs.
Here's some code of the old and new way of doing this (the new is just what I have so far...):
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), False, 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)]
I've tested it by creating a nurbsPlane (with defaults) and then moving it up 0.5 units in y and comparing the output of the two functions with these lines:
getClosestPointOnSurfaceOLD('nurbsPlane1', (0.0, 1.0, 0.0)) # Result: [(-2.7755575615628914e-17, 0.5, 2.7755575615628914e-17), (0.5, 0.5)] # getClosestPointOnSurfaceNEW('nurbsPlane1', (0.0, 1.0, 0.0)) # Error: TypeError: file <maya console> line 28: integer argument expected, got float #
Other things I've tried to do with the 'closestPoint' line in my function:
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 #
Some of the differences in output is just strange to me, and the errors don't seem to make sense (like the differences when adjusting the 'tolerance' arg value)... Also, it turns out that the uv values of 0.5 being correct is just coincidental - if I move and/or rotate the plane, the old function returns different uv values while the new function always returns 0.5 since it's evaluating the test point from the plane's object space instead of using world space.
I also took a look at the docs for the corresponding old OpenMaya command where there were two entries - one of which has a 'paramAsStart' boolean arg to use if you are going to provide some start uv values. Thinking the 2.0 docs may have missed that, I tried adding that into my api 2.0 attempt too... It didn't work either (gave me an error that I passed in too many args).
For the bare minimum, I need to figure out how to make it evaluate the test point from world space; However, as I continue using the OpenMaya api 2.0, I'm sure I'll run across this type of thing again - any help on how to actually use these kwargs is appreciated!
Solved! Go to Solution.