We've Moved


The blog has been retired - it's up for legacy reasons, but these days I'm blogging at blog.theodox.com. All of the content from this site has been replicated there, and that's where all of the new content will be posted. The new feed is here . I'm experimenting with crossposting from the live site, but if you want to keep up to date use blog.theodox.com or just theodox.com
Showing posts with label api. Show all posts
Showing posts with label api. Show all posts

Friday, March 27, 2015

Maya Bug Watch: API2 and GetPoints()

In general I’m more or less a fan of Maya Python API 2.0. It’s more pythonic and feels faster than the old version. However, it’s not without its quirks and I just found one that really bit me in the behind.
If you want to get the vertices of an object in the api, the usual formula is:
  1. Get the dagPath of the object
  2. make an MFnMesh
  3. call the ‘GetPoints’ method of your mesh
  4. party on.
Something like this, which returns a list of MPoint objects for the verts in the mesh
import maya.api.OpenMaya as api

def get_verts(mesh):
    mobj = api.MGlobal.getSelectionListByName(mesh).getDagPath(0)
    # that's lazy, it assumes that the first child is the mesh shape.
    # in practice you need to be more careful...
    mfn_mesh =  api.MFnMesh(mobj)
    vert_array = mfn_mesh.getPoints()
    return [i for i in vert_array]
This works fine and dandy… except:
If the mesh has 256 or more verts, the first vertex comes back as garbage
Here’s an example, using the same function:
mesh, _ = cmds.polyCube(sw = 1, sh= 1, sd = 1)
print get_verts(mesh)[:4]
#> [maya.api.OpenMaya.MPoint(-0.50000000000009082, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(0.5, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.5, 0.5, 0.5, 1), maya.api.OpenMaya.MPoint(0.5, 0.5, 0.5, 1)]

# this looks good... Here's the same thing for a 226 vert cube:
mesh, _ = cmds.polyCube(sw = 8, sh= 8, sd = 3)
print get_verts(mesh)[:4]
#> [maya.api.OpenMaya.MPoint(-0.50000000000005185, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.375, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.25, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.125, -0.5, 0.5, 1)]

# but up the vert count to 258:
mesh, _ = cmds.polyCube(sw = 8, sh= 8, sd = 4)
print get_verts(mesh)[:4]
#> [maya.api.OpenMaya.MPoint(5.0277956463997711e-315, 5.0313386899592279e-315, 0.5, 1), maya.api.OpenMaya.MPoint(-0.375, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.25, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.125, -0.5, 0.5, 1)]

# that first point is gibberish: python can't go to the -315th power!
I’ll leave it to wiser heads to figure out why it works out like this. My guess is that something is borked in pointer math going on inside the wrapper around MfnMesh, but I don’t know. Luckily, there’s a workaround: if you create new MPoints out of the items coming back from the GetPoints() call, you get good data. I’m not sure why but this should be so but it appears to be reliable on my machine (Windows 7, 64 bit maya 2015). Here’s the workaround:
def safe_get_verts(mesh):
    mobj = api.MGlobal.getSelectionListByName(mesh).getDagPath(0)
    mfn_mesh =  api.MFnMesh(mobj)
    vert_array = mfn_mesh.getPoints()
    return [api.MPoint(i) for i in vert_array]  # creating new MPoints fixes the issue

mesh, _ = cmds.polyCube(sw = 10, sh= 10, sd = 10)
print safe_get_verts(mesh)[:4]
#> [maya.api.OpenMaya.MPoint(-0.5, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.40000000596046448, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.30000001192092896, -0.5, 0.5, 1), maya.api.OpenMaya.MPoint(-0.20000001788139343, -0.5, 0.5, 1)]

Friday, December 12, 2014

All we are saying is give API 2.0 a chance

Doing all this math-related posting has reminded me of something I've been meaning to write up:

Maya's python API 2.0, first introduced in the 2013 version, got off to a rocky start. People complained about missing functions and missing modules.  It uses (mostly) the same function and class names as the original OpenMaya Python, which is a recipe for confusion. The documentation is pretty confusing too, since it points at the original C++ docs and leaves it up to you to do much of the translation in your head.    However....


Tuesday, March 18, 2014

If your Maya Python API is crashing

Check out this useful post from Cyril Fauvelle on the ins and outs of the dreaded MScriptUtil.

This kind of stuff is why I reserve API programming for only the knottiest of tasks.  maya.cmds won't clean-exit your Maya session if you reverse two lines by accident.  However, sometimes there's no alternative...  Here's hoping API 2.0 matures quickly and we can all forget all of this pointless distraction.