View Full Version : Help Orienting Joints to Polygon Faces

05 May 2007, 01:33 AM
Hello, I'm writing a script to create a joint chain along an edge selection and so far everything works great up to the point where I try to write MEL to align the join orientation to a selected face or edge on creation. I've tried the orientJoint/delete trick but it doesn't seem to work on components(unless I am doing it wrong). Any help would be greatly appreciated! And I am a newbie when it comes to scripting, but I love it so far!

ps: I manually aligned the first joint.

05 May 2007, 08:26 AM
there has been before threads about listing components in selection order. You could do a search about the subject...if I remember correctly maya list components always in index you had to make a tool to select component in order...that might be your first problem.

alinging joints to edges might be dificult cos maya doest have any tool to do it...atleast I dont know of. but you could aling them to vertex by normal constraint.

05 May 2007, 11:15 AM
Hello kojala, the selection order was an issue when I first started but was solved using the undo-redo trick. I'll have to research the vertex normal suggestion, that sounds like it might solve my problem, Thanks,


06 June 2007, 02:55 AM
Let me take a stab at this.

As far as getting elements in selection order, you might want to take a look at script contexts. I know in Maya 7, scriptCtx stopped returning elements in selection order if you wanted an expanded string. I don't know if this is still the case in 8/8.5.

Regarding your orientation problem, what I would do is build a 3x3 transformation matrix (aka directional cosine matrix) and perform an affine conversion to get the needed Euler angles.

I could go on and on about matrices, and vectors, and linear algebra in general, but I'll spare you. The following procedure will give you the angles you need. Just supply a face and an edge that lies on that face, the procedure will do the rest.

global proc float[] gtFaceEdgeEuler(string $face, string $edge){

float $DCM[] = gtFaceEdgeDCM($face,$edge);
float $angles[] = gtDCMToEuler($DCM);


The above procedure relies on two other procedures. Here they are.

global proc float[] gtFaceEdgeDCM(string $face, string $edge){

vector $x;
vector $y;
vector $z;
string $edgeVerts[] = `polyListComponentConversion -tv $edge`;
string $faceVerts[] = `polyListComponentConversion -tv $face`;
float $edgeVertPos1[];
float $edgeVertPos2[];
float $faceVertPos[];

$edgeVerts = `ls -fl $edgeVerts`;
$faceVerts = `ls -fl $faceVerts`;
$faceVerts = stringArrayRemove($edgeVerts,$faceVerts);
$edgeVertPos1 = `xform -q -ws -t $edgeVerts[0]`;
$edgeVertPos2 = `xform -q -ws -t $edgeVerts[1]`;
$faceVertPos = `xform -q -ws -t $faceVerts[0]`;
$x = <<$edgeVertPos2[0] - $edgeVertPos1[0],$edgeVertPos2[1] - $edgeVertPos1[1],$edgeVertPos2[2] - $edgeVertPos1[2]>>;
$z = <<$faceVertPos[0] - $edgeVertPos1[0],$faceVertPos[1] - $edgeVertPos1[1],$faceVertPos[2] - $edgeVertPos1[2]>>;
$y = cross($x,$z);
$z = cross($x,$y);
$x = unit($x);
$y = unit($y);
$z = unit($z);

global proc float[] gtDCMToEuler(float $DCM[]){

float $eulerAngles[];

$eulerAngles[0] = atan2d($DCM[5],$DCM[8]);
$eulerAngles[1] = asind(-1 * $DCM[2]);
$eulerAngles[2] = atan2d($DCM[1],$DCM[0]);

I hope this helps. If you have any questions, feel free to ask.

CGTalk Moderation
06 June 2007, 02:55 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.