finding a bone from a vertex

709 views
Skip to first unread message

Eugene Flormata

unread,
Apr 11, 2018, 3:23:52 PM4/11/18
to Python Programming for Autodesk Maya
does anyone know if it's possible to find a bone from a mesh vertex in python?

I've found links to code for finding the polygons effected from a bone
http://polycount.com/discussion/140109/melscript-python-selecting-influenced-polygons-from-a-joint

but I'm having trouble finding the right command in reverse
maybe getting a list of bones affecting one vertex, or the bone with the most weight


any help would be great
thanks!

Michael Boon

unread,
Apr 11, 2018, 5:58:40 PM4/11/18
to Python Programming for Autodesk Maya
PyMel is probably the most straightforward because you can use the API command influenceObjects and then read the weightList from an attribute.
Using the API would be much faster if your rig is complex.
Using cmds...I'm sure someone else knows how to get the influence objects from an attr. It's not something I've ever had to do.

Here's a PyMel example. With a couple of verts on a cylinder selected:
import pymel.core as pm
vert
= pm.selected()[0]
mesh
= vert.node()
sc
= mesh.listHistory(type='skinCluster')[0] # Note this is not a great way to get skinClusters in general, but it works in simple situations.
infs = sc.influenceObjects()
print vert
print mesh
print sc
vId
= vert.currentItemIndex()
print 'Vert:', vId
for jId in xrange(sc.numInfluenceObjects()):
   
print '\t', infs[jId], pm.getAttr(sc.weightList[vId].weights[jId])
prints
pCylinderShape1.vtx[16:17]
pCylinderShape1
skinCluster1
[nt.Joint(u'joint1'), nt.Joint(u'joint2'), nt.Joint(u'joint3'), nt.Joint(u'joint4')]
[0, 1, 2, 3]
Vert: 16
    joint1
0.0163752022203
    joint2
0.933793770143
    joint3
0.0495594248894
    joint4
0.000271602747264

Michael Boon

unread,
Apr 11, 2018, 6:01:00 PM4/11/18
to Python Programming for Autodesk Maya
Boo, sorry, wrong printout!
It's more like this:
pCylinderShape1.vtx[16:17]
pCylinderShape1
skinCluster1

Vert: 16
    joint1
0.0163752022203
    joint2
0.933793770143
    joint3
0.0495594248894
    joint4
0.000271602747264

Eugene Flormata

unread,
Apr 12, 2018, 4:36:11 PM4/12/18
to Python Programming for Autodesk Maya
cool! thanks!

I actually posted in the autodesk forum too and I got an interesting snippet there too, so I thought I'd post that here
https://forums.autodesk.com/t5/maya-programming/how-can-i-find-a-bone-from-a-vertex/m-p/7927115


thanks for the help!

Michael Boon

unread,
Apr 12, 2018, 6:27:13 PM4/12/18
to Python Programming for Autodesk Maya
Nice. That cmds way is probably better, unless you're using PyMel already.
"findRelatedSkinCluster" is a MEL script (you can find it on your PC) that works much better than my simple "listRelatives" call.
I had forgotten about cmds.skinPercent.

I'm suspicious of "objName = cmds.listRelatives(cmds.ls(rsSlVtx, o=True), p=True)" though. At the very least, it's impenetrable using those MEL abbreviations for all the switches.
Apparently
cmds.ls(rsSlVtx, objectsOnly=True)
returns the object (ie shape node) names for any supplied components. I didn't know that :)
The outer part ("cmds.listRelatives(...), parent=True)") returns the parent of that shape. That seems unnecessary to me since the skin is bound to the shape. The only time it could make a difference is if the shape is instanced, and the script makes no effort to handle that anyway.

You probably want to add a filterExpand command on your vertex list, to get rid of non-vertices, and to expand grouped verts into individual verts. Otherwise the skinPercent command will fail on those.

Marcus Ottosson

unread,
Apr 12, 2018, 7:01:10 PM4/12/18
to python_in...@googlegroups.com

Hey Michael,

You can query objects in the vicinity of a vertex using the MRichSelection class from the API. It’s piggybacking on Maya’s soft-selection feature.

I found a thread with an example here: https://groups.google.com/forum/#!topic/python_inside_maya/q1JlddKybyM

If that doesn’t do it, let me know and I’ll type up an example, I’ve done something similar using this class in the past.

Reply all
Reply to author
Forward
0 new messages