Query primary joint axis

627 views
Skip to first unread message

flaye

unread,
May 25, 2014, 6:58:22 PM5/25/14
to python_in...@googlegroups.com
Hi,

Is there a way to query the primary joint axis in a joint chain? I can't seem to find anything to return that value.
Querying the orientJoint flag doesn't work, only editing it.

One way is to figure out which channel has translations on a child joint node, but this doesn't seem the correct and elegant solution.

Thanks.

Paul Molodowitch

unread,
May 26, 2014, 1:17:21 PM5/26/14
to python_inside_maya
I don't think that's anything that's inherent to a joint, or stored on it - it's just something that's used temporarily by the jointOrient flag / command to clean up your skeleton.  But you can have joints at all sorts of random positions + orientations, and it would still be a valid (though messy) skeleton.


--
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/c2037bbe-0d8c-41df-bdad-5d870ed2be09%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

flaye

unread,
May 26, 2014, 3:25:54 PM5/26/14
to python_in...@googlegroups.com


The reason I want to do this is to be able to measure the overall length of a joint chain. As far as I can tell, if the absolute values of the primary axis are all added up in a joint chain, regardless of how bent it is, you'll get the full chain length. I'm trying to automatically figure that out, rather than have the user enter the primary axis manually through a GUI or command.

If there's a better way to do so, maybe even through some API nodes, I'll be happy to hear about it.

Thanks.

Todd Widup

unread,
May 26, 2014, 6:49:41 PM5/26/14
to python_in...@googlegroups.com
its not a valued that is stored anyplace.  the common practice is to check the position of the children.  this will help to determine what it is as most should be offset on only 1 axis


--
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.

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



--
Todd Widup
Creature TD / Technical Artist
to...@toddwidup.com
todd....@gmail.com
www.toddwidup.com

Eduardo Grana

unread,
May 26, 2014, 11:09:03 PM5/26/14
to python_in...@googlegroups.com
Hello People,

If you want to get the distance in world space,
you may have to query he world position of the joints,
instead of taking the translate values, since there may
be scales in the hierarchy that will distort the result.
You can use the joint command on query mode with the -p flag,
to get world position.
If you want to use the api to do the math, you can use MPoint's
 distanceTo method

import maya.OpenMaya as om

def distance (scrVec, targetVec):
'''
get the distance of two vectors
scrVec -> is a vector
targetVec -> is a vector
'''
scr = om.MPoint(scrVec[0], scrVec[1], scrVec[2],1.0)
tgt = om.MPoint(targetVec[0], targetVec[1], targetVec[2], 1.0)
return scr.distanceTo(tgt)

Other thing you can do, is draw a degree 1 curve through the joints,
and use the curve nfo node to get the lenght.

Hope this is usefull!
Cheers,
Eduardo



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



--
Eduardo Graña
www.eduardograna.com.ar

Andres Weber

unread,
May 27, 2014, 3:21:56 PM5/27/14
to python_in...@googlegroups.com
You could also just create a curve based on the joints (each CV matching position with each joint's world position using a decomposeMatrix) and then do an arclen of that curve.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
--
Todd Widup
Creature TD / Technical Artist
to...@toddwidup.com
todd....@gmail.com
www.toddwidup.com

--
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.



--
Eduardo Graña
www.eduardograna.com.ar

Marcus Ottosson

unread,
May 27, 2014, 4:08:17 PM5/27/14
to python_in...@googlegroups.com
I second Eduardos and Andres suggestions! An alternative to decomposeMatrix (which may be unfamiliar to some) is to put a locator under each joint. The locator shape will have a world position attribute you can use to position your CVs.


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/4df5702a-0697-403f-9ea2-76e6fffd4316%40googlegroups.com.

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



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

flaye

unread,
May 28, 2014, 3:18:13 PM5/28/14
to python_in...@googlegroups.com


# Find the full length of the chain
sel
=[]
sel
=mc.ls(sl=True)
length
= 0
for i in range(1, len(sel)):
    length
+= abs(mc.getAttr(sel[i]+'.tx'))

print length


The above code will provide the correct answer, on the condition that the primary axis of the joints (in this case, X) is known.

I've also tried using the MVector function, but unfortunately the numbers are off

import maya.api.OpenMaya as om #for api 2.0
sel
=[]
sel
=mc.ls(sl=True)

startjnt
=sel[0]
numjnts
=len(sel)
length
=0
for i in range(0,numjnts-1):
       
        currentjnt
=sel[i]
       
        nextjnt
=mc.listRelatives(currentjnt,children=1)[0]
   
       
print currentjnt,nextjnt

        t1
=mc.xform(currentjnt,q=1,t=1)
        t2
=mc.xform(nextjnt,q=1,t=1)
       
        v1
=om.MVector(t1)
        v2
=om.MVector(t2)
       
        dist
=om.MVector(v2-v1).length() #equivalent to MEL's mag?
        length
+=dist
print length


any ideas? Thanks.

Andres Weber

unread,
May 28, 2014, 5:15:12 PM5/28/14
to python_in...@googlegroups.com
I'm not really sure why you're doing it the way you're doing it...
This is how I solved it quickly (There's better ways but I'm lazy and I didn't want to keep working on it.)  Just a simple recursive function.

def dist( objA, objB ):

   Ax, Ay, Az = objA.getTranslation(space="world")

   Bx, By, Bz = objB.getTranslation(space="world")

   return (  (Ax-Bx)**2 + (Ay-By)**2 + (Az-Bz)**2  )**0.5


def lenJointChain(obj,len=0):

       if obj.getChildren()==[]:

              return len

       else:

               child=obj.getChildren(type='transform')[0]

               return lenJointChain(child, len=len+dist(obj,child))


lenJointChain(pm.ls(sl=True)[0])

flaye

unread,
May 28, 2014, 8:04:56 PM5/28/14
to python_in...@googlegroups.com
Thanks Andres! That worked great. Now, regardless of the primary axis, it returns the correct length.

By the way, I'm not too familiar with pymel (yet). Is there an equivalent to the code in Python proper? Specifically the getTranslation & getChildren commands?

I've tried this, but I get errors:

from math import *
def dist (objA, objB):
   
Ax,Ay,Az=mc.xform(objA,q=1,t=1)
   
Bx,By,Bz=mc.xform(objB,q=1,t=1)
   
return sqrt(pow((Ax-Bx),2)+pow((Ay-By),2)+pow((Az-Bz),2))
   
def lenJointChain(obj,len=0):
   
print obj
   
if mc.listRelatives(obj,children=1)==[]:
       
return len
   
else:
        child
=mc.listRelatives(obj,children=1,type='transform')[0]
       
return lenJointChain (child, len=len+dist(obj,child))
       
lenJointChain
(mc.ls(sl=True)[0])


Thanks.

Andres Weber

unread,
May 29, 2014, 3:21:01 PM5/29/14
to python_in...@googlegroups.com
You pretty much got it, you're missing a ws=True flag in your xform command (that way we get the worldspace instead of the local space...just in case the transforms are funkily nested).  The last thing you're missing is, getChildren() returns [] when it doesn't have children, but mc.listRelatives() returns None.  So the line in the if statement becomes: if not mc.listRelatives(obj,children=True,type='transform'):

flaye

unread,
May 30, 2014, 7:53:08 PM5/30/14
to python_in...@googlegroups.com
Excellent! Thank you for the insight Andres. Much appreciated.
Reply all
Reply to author
Forward
0 new messages