multi component selection in MObject

212 views
Skip to first unread message

kevco...@gmail.com

unread,
Jan 13, 2015, 2:33:38 PM1/13/15
to python_in...@googlegroups.com
Hey Guys,

Working on some more tools right now, using python 1.0 api to try to speed things up.

It's not immediately obvious to me how to deal with different component types.

So If I do something like

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

mDag = om.MDagPath()
mComp = om.MObject()
for i in xrange( sel.length() ):
mSel.getDagPath(i, mDag, mComp)

#===========

What sort of function set, or Iterator would I use on mComp, if mComp contains vertices, faces, and or edges?

I know I can do something like

if mComp.hasFn( MFn.kMeshVertComponent )

But how do I best deal with not knowing the type of component(s) in mComp(MObject)?

Thanks!
Kev



Justin Israel

unread,
Jan 13, 2015, 5:43:50 PM1/13/15
to python_in...@googlegroups.com
Here is a random example from the API docs, showing both how you could be using an MItSelectionList (instead of using a python range loop), and also how they switch on the component type to handle it in different ways:


Its a c++ example, but I am sure you can translate it. 


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/52e9da24-18fe-43c5-8498-78cd872dd421%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

kevco...@gmail.com

unread,
Jan 13, 2015, 6:06:16 PM1/13/15
to python_in...@googlegroups.com
Hey Justin,

Thanks for this. I'd tried figuring out what was going on in that example, But I'm not all that familiar with c++, or the api for that matter, so it's a bit tough to decipher.

It looks like it's using a switch to do it, maybe I'm wrong, but I don't see how it's handling different components types within the MObject. does component.apiType() return the type for each component within the MObject, or just the first component in the MObject? like hasFn() does?

sorry, I require some hand holding here

Kev

Marcus Ottosson

unread,
Jan 13, 2015, 6:09:55 PM1/13/15
to python_in...@googlegroups.com
If you elaborate a little more on what it is your tool is meant to do, I might be able to chip in with some advice.​

kevco...@gmail.com

unread,
Jan 13, 2015, 6:21:11 PM1/13/15
to python_in...@googlegroups.com
it's fairly basic really. It's just a tool for creating follicles at selected components. Easy enough. But then I wanted it to work on selected components of any type.

So if it's a vert, I just get the UV value directly. and if it's a face or edge, I average the UV values of their appropriate verts.

I guess I just don't understand how to work with an MObject that holds these different component types.

Marcus Ottosson

unread,
Jan 13, 2015, 6:38:13 PM1/13/15
to python_in...@googlegroups.com
Ah I see. I've got a script that does exactly that, using only maya.cmds. I'll put it up here it tomorrow morning for you.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/ae10f7dd-bbdc-4032-a4d9-58dc3b7e53f2%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.


--
Marcus Ottosson
konstr...@gmail.com


kevco...@gmail.com

unread,
Jan 13, 2015, 7:23:29 PM1/13/15
to python_in...@googlegroups.com
Hey Marcus, I appreciate the offer, but it's not so much a problem for me creating the script. I've got on working in pymel just fine.

I'm really just trying to get more familiar with the api.

kevco...@gmail.com

unread,
Jan 13, 2015, 7:38:33 PM1/13/15
to python_in...@googlegroups.com, kevco...@gmail.com
specifically, on how to deal with MObjects with multiple component types in them

kevco...@gmail.com

unread,
Jan 13, 2015, 11:33:23 PM1/13/15
to python_in...@googlegroups.com, kevco...@gmail.com
okay, I think I'm getting this...

#==========================
import maya.OpenMaya as om

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

mDag = om.MDagPath()
mComp = om.MObject()

selIter = om.MItSelectionList( mSel, om.MFn.kComponent )
while not selIter.isDone():
selIter.getDagPath( mDag, mComp )
print mDag.fullPathName(), mComp.apiTypeStr()
selIter.next()
#==========================

I think that's the correct way to use MItSelectionList like Justin was mentioning, right?

Then I can just use switch/case like in the example you provided. Awesome!

Kev

kevco...@gmail.com

unread,
Jan 14, 2015, 10:46:35 PM1/14/15
to python_in...@googlegroups.com, kevco...@gmail.com
Okay, one last question on this...

I've got this all working great so far. Thanks for the help guys!

Now, I'm trying to create follicles at surface point locations, But I'm not sure how to work with it, since they're not components(?). I noticed in the scriptEditor, that when I'm selecting them, it's spitting out UV values, which is exactly what I need. But how do I get those UV values from OpenMaya?

Thanks!
Kev

Justin Israel

unread,
Jan 15, 2015, 1:04:38 AM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Maybe something like this? 
import maya.OpenMaya as om

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

d = om.MDagPath()
o = om.MObject()

selIt = om.MItSelectionList(sel)
fn = om.MFnSingleIndexedComponent()
uvs = om.MIntArray()

while not selIt.isDone():
    selIt.getDagPath(d, o)
    fn.setObject(o)
    fn.getElements(uvs)
    print list(uvs)

    geomIt = om.MitGeometry(d, o)
    while not geomIt.isDone():
        p = geomIt.position(om.MSpace.kWorld)
        print geomIt.index(), (p[0], p[1], p[2], p[3])
        geomIt.next()

    selIt.next()


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/33254070-9258-4d4b-baa0-95b6f28eae9a%40googlegroups.com.

Justin Israel

unread,
Jan 15, 2015, 1:07:34 AM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Forgive any typos in there. I had to hand type that code snippet from my workstation :-)

I already see I messed up:

geomIt = om.MitGeometry(d, o)
==>
geomIt = om.MItGeometry(d, o)

kevco...@gmail.com

unread,
Jan 15, 2015, 4:51:45 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
hey Justin, thanks for typing that out for me. I was having a real hard time figuring out what function set to use to get those values.

However, when I try to use MFnSingleIndexedComponent with passing in the MObject from the selection Iterator, I get a kInvalidParameter error, Object is not compatible with this method. I've tried other function sets, like MFnDoubleArrayData, MFnDoubleIndexedComponent, etc, but these all seems to give the same error. Is there a better way to figure out what function set I need to use? or just guess and check?

Thanks
Kev

Justin Israel

unread,
Jan 15, 2015, 5:16:05 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Can you print the apiTypeStr from your component in the selection iterator? When I tested it, selecting uvs, it worked for me. 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/47a6fbe5-e107-43db-aceb-985e2dcc8e88%40googlegroups.com.

kevco...@gmail.com

unread,
Jan 15, 2015, 5:26:53 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
sure, It's kIsoparmComponent

kevco...@gmail.com

unread,
Jan 15, 2015, 5:57:24 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Let me elaborate. I shift+Rclick on the nurbsSurface and drag down to select "Surface Point". I shift click on the surface a few times and run my code.

Justin Israel

unread,
Jan 15, 2015, 9:33:51 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Sorry, my example was based on a mesh. I actually can't figure out the answer to your problem when the selected points on the nurb are kIsoparmComponent. They would seem compatible with a MFnDoubleIndexedComponent function set, yet they don't pass the run time inspection:

# get the component MObject
# ...
ar = []
om.MGlobal.getFunctionSetList(o, ar)
print ar
# [u'kBase', u'kComponent', u'kIsoparmComponent']

And I couldn't find any compatible function sets that actually allowed you to inspect each element. 
Maybe someone else knows the answer. I can only see how to deal with the string representation of the selection from MSelectionList.getSelectionStrings(). The selected UV values could be parsed and then the points looked up via MFnNurbsSurface.getPointAtParam().... but that seems janky. 

There must be a legit way to list the elements of that component. 


On Fri Jan 16 2015 at 11:57:29 <kevco...@gmail.com> wrote:
Let me elaborate.  I shift+Rclick on the nurbsSurface and drag down to select "Surface Point".  I shift click on the surface a few times and run my code.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.

kevco...@gmail.com

unread,
Jan 15, 2015, 9:52:20 PM1/15/15
to python_in...@googlegroups.com, kevco...@gmail.com
Thanks Justin, This actually helps me out quite a bit. I was beginning to go crazy trying to figure this out.

I didn't know about 'MGlobal.getFunctionSetList'. That will certainly be helpful to me. I'll keep digging around for how to do this properly. I guess for now, I'll just getSelectionStrings() and retrieve the UV values that way.

If I call cmds.ls(sl=True), it prints out something like this:
[u'nurbsPlane1.uv[0.59253706134522][0.161564439096155]', u'nurbsPlane1.uv[0.599931211606115][0.410924399414686]', u'nurbsPlane1.uv[0.57016780534669][0.701572989190219]', u'nurbsPlane1.uv[0.584485270214895][0.858501935271855]']

So that will be simple. I just wish it was simple to grab those selected UV coordinates through the API. Bah!

Anyways, Many Thanks for your help, I really appreciate it. This has taught me quite a bit already ;)

Kev
Reply all
Reply to author
Forward
0 new messages