OpenMaya, getting the current componet selection

searched a little, and haven’t found any methods for grabbing the current component selection with openMaya from python, that i can use with methods like the MItMeshFaceVertex() iterator.

anyone got a little hint?

MSelectionList’s getDagPath method takes a 3rd optional argument of an MObject. This MObject will hold the selected components (if there are any, otherwise it will be null).

import maya.OpenMaya as om
sel = om.MSelectionList()
om.MGlobal.getActiveSelectionList(sel)

dag = om.MDagPath()
component = om.MObject()
sel.getDagPath(0, dag, component)
if not component.isNull():
    # There were components selected
    vert_itr = om.MItMeshVertex(dag, component)
    while not vert_itr.isDone():
        # Do stuff
        vert_itr.next()

How would you go about adding the result of each iteration to a list? Since there really seems to be know way from the iterator to get which iteration your on expecially with the MItMeshFaceVertex, where i would need to track what vert, and what face it is on?

This is what i got sofar


import maya.OpenMaya as om
import sys

uvList = [None, None]
uv_util = om.MScriptUtil()
uv_util.createFromList(uvList, 2)
uvPoint = uv_util.asFloat2Ptr()

sel = om.MSelectionList()
om.MGlobal.getActiveSelectionList(sel)

dag = om.MDagPath()
component = om.MObject()
sel.getDagPath(0, dag, component)

if not component.isNull():
    vert_itr = om.MItMeshFaceVertex(dag, component)
    while not vert_itr.isDone():
        vert_itr.getUV(uvPoint)
        uvList[1] = uv_util.getFloat2ArrayItem(uvPoint, 0, 1)
        uvList[0] = uv_util.getFloat2ArrayItem(uvPoint, 0, 0)
        print >> sys.stderr, uvList
        vert_itr.next()

MItFaceVertex has three methods that return information about the current iteration:
vertId() - Current object/global vertex index
faceId() - Current face index
faceVertId() - Current face-relative vertex index

import maya.OpenMaya as om
sel = om.MSelectionList()
om.MGlobal.getActiveSelectionList(sel)
dag = om.MDagPath()
comp = om.MObject()
sel.getDagPath(0, dag, comp)

itr = om.MItMeshFaceVertex(dag, comp)
print '| %-15s| %-15s| %-15s' % ('Face ID', 'Object VertID', 'Face-relative VertId')
while not itr.isDone():
    print '| %-15s| %-15s| %-15s' % (itr.faceId(), itr.vertId(), itr.faceVertId())
    itr.next()

# | Face ID      |Object VertID |Face-relative VertId
# | 1            | 2            | 0            
# | 1            | 3            | 1            
# | 1            | 5            | 2            
# | 1            | 4            | 3            
# | 5            | 6            | 0            
# | 5            | 0            | 1            
# | 5            | 2            | 2            
# | 5            | 4            | 3    

alright since im wanting all the data in a list of lists i tried something


import comtypes.client
import maya.OpenMaya as om
import sys

uvList = [None, None]
uv_util = om.MScriptUtil()
uv_util.createFromList(uvList, 2)
uvPoint = uv_util.asFloat2Ptr()

sel = om.MSelectionList()
om.MGlobal.getActiveSelectionList(sel)

dag = om.MDagPath()
component = om.MObject()
sel.getDagPath(0, dag, component)

mainList = []
if not component.isNull():
    vert_itr = om.MItMeshFaceVertex(dag, component)
    while not vert_itr.isDone():
        vert_itr.getUV(uvPoint)
        uvList[1] = uv_util.getFloat2ArrayItem(uvPoint, 0, 1)
        uvList[0] = uv_util.getFloat2ArrayItem(uvPoint, 0, 0)
        print >> sys.stderr, uvList
        mainList.append(uvList)
        vert_itr.next()
    print >> sys.stderr, mainList

and after printing the mainList it is just carrying the last value in every index of the list, would you know how i can properly build this list.

thought it was something wrong with my usage of append, but i tested it on a loop to create a list and it worked fine.

Kinda feels like it is adding references to my master list instead of just the values, but didn’t think python could do that.

Because you are assigning the UV values to uvList by specifying the index, you are just editing the existing list and so uvList is always pointing to the same object in memory.

inner = [None, None]
print id(inner)
inner[0] = 5
inner[1] = 2
print id(inner)

# 814542024
# 814542024

Therefore in your code, mainList just contains a bunch of references to the same uvList, so when you change uvList[0], it is updating the object that EVERY index of mainList is pointing to.

inner = [None, None]
main = []
print id(inner)
main.append(inner)
inner[0] = 5
inner[1] = 2
main.append(inner)
print main
print id(main[0]), id(main[1])

# 814541896
# [[5, 2], [5, 2]]
# 814541896 814541896

Notice that the memory id of inner and of both elements in main, are the same, and the thus the contents of those elements will be the same.
You can avoid this by assigning the uv values to variables and then using mainList.append([u_val, v_val]).

This is the same idea behind the fairly common python “gotcha” where defining a mutable object as the value of a default argument in a function def produces unexpected results:

def pygotcha(num, contents=[]):
    contents.append(num)
    print contents
pygotcha(5)
pygotcha(10)

# [5]
# [5, 10]
1 Like

thanks, would having separate vars for u and v be better than just doing this in my append line?


mainList.append(uvList[:])

that will just copy the list each time.

Use variables. It’s clearer and easier to read and is also faster (though you’d have to be looping millions of times before you noticed any speed difference). There is no gained functionality in this case from updating and copying a list.