MFnMesh.getClosestPoint using Maya Python API 2.0

david | maya,OpenMaya,python,tutorials | Tuesday, July 9th, 2013

Yesterday I wrote about my experiences with the OpenMaya modules for python in maya, and showed some code to get the closest vertex on a mesh from the position of a locator. Today I'm going to show the same code, rewritten to use the new Maya Python API 2.0, which, according to the intro in the manual, " is a new version of the Maya Python API which provides a more Pythonic workflow and improved performance."

I have not done any speed tests, so I'll leave that for another day, but I found the syntax much more within my comfort zone.

In API 2.0, most methods output through return values instead of their parameter list like they did in the old API. This simplifies things greatly since it avoids most of the confusion with passing values through pointers etc.

API 2.0 is only available in the more recent versions of maya and changes with each release as new modules are added. It is too soon for the new API to be a complete replacement for the old, since so far only a subset of the modules have been implemented, but for the simple script example shown below it works just fine (in maya 2014).

This script performs exactly the same task as the one from yesterday's post, but I'm now importing from maya.api.OpenMaya. There are some changes and some of the old code has been removed because now the methods return their output directly to return values. So, for example, there is no need to use MScriptUtil() to manage the idPointer from getClosestPoint(). Now it simply returns the closestPoint and the faceIdx.

 

import maya.api.OpenMaya as OpenMaya
import pymel.core as pm

geo = pm.PyNode('pSphere1')
loc = pm.PyNode('locator1')
pos = loc.getRotatePivot(space='world')

try:
    selectionList = OpenMaya.MSelectionList()
    selectionList.add(geo.name())
    nodeDagPath = selectionList.getDagPath(0)
except:
    raise RuntimeError('maya.api.OpenMaya.MDagPath() failed on %s' % geo.name())

mfnMesh = OpenMaya.MFnMesh(nodeDagPath)

point = OpenMaya.MPoint(pos.x, pos.y, pos.z)
space = OpenMaya.MSpace.kWorld

closestPoint, faceIdx = mfnMesh.getClosestPoint(point, space)  

faceVerts = [geo.vtx[i] for i in geo.f[faceIdx].getVertices()]
closestVert = None
minLength = None
for v in faceVerts:
    thisLength = (pos - v.getPosition(space='world')).length()
    if minLength is None or thisLength < minLength:
        minLength = thisLength
        closestVert = v
pm.select(closestVert)

1 Comment »

  1. Thanks, David. Really straightforward tutorial.

    Comment by cgbeige — February 28, 2015 @ 11:24 am

RSS feed for comments on this post.

Leave a comment

You must be logged in to post a comment.

Powered by WordPress | Based on a theme by Roy Tanck