Mel is it possible to align a locator x y z with a face?

Mel is it possible to align a locator x y z with a face?

malcolm_341
Collaborator Collaborator
3,162 Views
6 Replies
Message 1 of 7

Mel is it possible to align a locator x y z with a face?

malcolm_341
Collaborator
Collaborator

Hi, I've been trying for two days to figure out how I can align a locator to the x y z of an arbitrary selected face. I've tried constraints, extruding moving things, normals, nothing seems to work. Is this possible, I would also be happy to select a face and also select an edge to define the object space rotation for the locator, but I've tried that I couldn't get that working either.

align_locator.jpg

0 Likes
3,163 Views
6 Replies
Replies (6)
Message 2 of 7

malcolm_341
Collaborator
Collaborator

I've made a bit of progress on this problem. You can use the manipMoveAlignHandleToComponent command to align the rotation with the selected faces. Below is the code to do that, but it gives random results, while the axis is always aligned correctly positive Y seems to be pretty random based on the shape of the model, sometimes Y is negative. Trying to figure out how to always have Y face positive at the moment.

string $face[] = `ls -sl`;
toggleSelMode;
toggleSelMode;
selectMode -object;
DeleteHistory;
string $object[] = `ls -sl`;
select $face;
manipMoveAlignHandleToComponent($face[0], {$object[0]}, {""}, "none", 0);;
BakeCustomPivot;
0 Likes
Message 3 of 7

jmreinhart
Advisor
Advisor

The Y axis is based of off the meshes UV's when you're in component mode.

 

Sticking to MEL you could find out the Y axis vector by querying the position of the translate manipulator, then translating the selected face along the local Y axis with this command

move -r -cs -ls -wd 0 0 1 ;

Then you can store that value and translate back.

Now that  we know which direction the Y axis is pointing in we can find out if it's pointed up or down. We can do that using the dot product. 

	float $v1[3] = {1,2,3};//the Y vector we just got
	float $v2[3] = {0,1,0};//the world up vector
	float $dp = dotProduct($v1, $v2, 0);

If the dot product  is positive then we know that the Y axis is already pointing up.  If it is negative we just need to flip the Y axis 180 degrees. We can do that by multiplying each component by -1.

 

I'm not exactly sure what the end result you want for this tool but hopefully that helps.

Message 4 of 7

osidedan
Advocate
Advocate

What jonahrnhrt said about using dot product is definitely correct for checking if your Y vector is facing the right way, and also using -1 to multiply to flip it around. 

 

As a side note, here is a script I wrote a while back that creates a locator and matches it to the move manipulator position and orientation, and you might be able to adapt it to what you are trying to do. (I also tweaked it a bit so that Y is forward since you said that's what you want to do).  Of note, it only works if the move tool is your current tool. Also keep in mind, it matches the move tool's current position and orientation, so you would want the move tool's Axis Orientation set to component so that it matches the selected component's orientation. It doesn't care what type of component you have selected, it just matches the move tool's orientation. 

 

 

# This script creates a locator aligned to the current move tool position and orientation. 
# To use: Select anything with the move tool and run this script (python).
import maya.cmds as cmds
import math as math
pos = cmds.manipMoveContext( 'Move',q=True, position=True)
rot = cmds.manipMoveContext( 'Move', q=True, orientAxes=True)

locator = cmds.spaceLocator()[0]
cmds.xform(locator,t=pos)
cmds.rotate(math.degrees(rot[0]),math.degrees(rot[1]),math.degrees(rot[2]),locator)
cmds.rotate(0,0,-90,locator,objectSpace=True,relative=True)

 


Let me know if you have any questions on what does what, or if you can't get it to work. I can also translate it into MEL if you want, just let me know. Hope that helps!

0 Likes
Message 5 of 7

malcolm_341
Collaborator
Collaborator

My vector's not coming out right for the face selection. When I rotate the locator using the vector I just created the rotation is not close to matching the orient of the face. Any ideas? I rotate a cube arbitrarily then freeze it's transform then select a face and run this.

//Query move tool
float $VectorStartY[] = `manipMoveContext -q -position "Move"`;
move -r -cs -ls -wd 0 0 30;
float $VectorEndY[] = `manipMoveContext -q -position "Move"`;
move -r -cs -ls -wd 0 0 -30;

//Get face Y vector
float $faceVectorX = $VectorEndY[0] - $VectorStartY[0];
float $faceVectorY = $VectorEndY[1] - $VectorStartY[1];
float $faceVectorZ = $VectorEndY[2] - $VectorStartY[2];


//Orient the move handle to align with the face
manipPivot -o $faceVectorX $faceVectorY $faceVectorZ;
//Doesn't work, gives me some random rotation?
0 Likes
Message 6 of 7

malcolm_341
Collaborator
Collaborator

osidedan thanks, I had written something similar already, it also needs to be in mel, but I can read your Python (can't write Python) and it appears to do what I've already got working. The part I'm stuck on is the orient of the handle after using the manipMoveAlignHandleToComponent command will randomly sometimes not be facing negative Y and I need it to always be facing positive Y.

0 Likes
Message 7 of 7

malcolm_341
Collaborator
Collaborator

I think I got it working, need to test it further and also write the if statement to flip axis if it detects negative. Will report back once I have time to test this on something more complex than a cube.

 

 

 

 

//Source Maya align transform script
source "others/manipMoveOrient.mel";

string $face[] = `ls -sl`;
toggleSelMode;
toggleSelMode;
selectMode -object;
DeleteHistory;
string $object[] = `ls -sl`;
select $face;

//Align the move tool with the face angle
manipMoveAlignHandleToComponent($face[0], {$object[0]}, {""}, "none", 0);;
BakeCustomPivot;

//Rotate Y because above command always makes Z up or down
float $OrientY[] = `xform -q -rotation`;
$plus90 = $OrientY[0] += 90;
manipPivot -o $OrientY[0] $OrientY[1] $OrientY[2];
BakeCustomPivot;

//Query move tool to create the Y vector
float $VectorStartY[] = `manipMoveContext -q -position "Move"`;
move -r -os -wd 0 30 0;
float $VectorEndY[] = `manipMoveContext -q -position "Move"`;
move -r -os -wd 0 -30 0;

//Get face Y vector
float $faceVectorX = $VectorEndY[0] - $VectorStartY[0];
float $faceVectorY = $VectorEndY[1] - $VectorStartY[1];
float $faceVectorZ = $VectorEndY[2] - $VectorStartY[2];

//Store the face Y vector
float $v1[3] = {$faceVectorX, $faceVectorY, $faceVectorZ};

//Store the world up vector
float $v2[3] = {0, 1, 0};

//Get the dot product to see if the move tool is facing positive or negative Y
float $dp = dotProduct($v1, $v2, 0);

 

 

 

 

 

0 Likes