View Full Version : list normal orientation

 Tamis05 May 2007, 10:52 AMim a beginner mel scripter and im wondering how i can get a list of the normals within maya mel ?
tbaypaul
05 May 2007, 02:02 AM
face normals use the polyInfo command with the -faceNormals flag which might return a string as opposed to the vector or float array you might expect...

vertex normals use the polyNormalPerVertex -q -xyz command...make sure you are passing the right data to it though....it takes a VertexFace I think (it might have to be selected also)....something like cube.vtxFace[v#][f#] and returns a float array.....

or you can use the later with the vertex selected and get all the vertex face normals of that vertex......I think you have to calculate the final result by adding them to get the vertex normal (unless they added a flag or command to do it for you)

And now I bet you are sorry you asked........

Tamis
05 May 2007, 07:40 AM
hehe a litle bit yeah :P, thanks a bunch tho !

grantimus
05 May 2007, 09:50 PM
Yeah that commands tbypaul mentioned probably don't work the way you want. I don't know if this is waht you're after. But here is a procedure that will return the face normal using world space coordinates:

global proc float[] gtGetFaceNormal(string \$face) {

string \$faceVerts[] = gtGetVertsInRenderOrder(\$face);
float \$p1[],\$p2[];
vector \$v1,\$v2;
vector \$normalVector;

\$p1 = `xform -q -ws -t \$faceVerts[0]`;
\$p2 = `xform -q -ws -t \$faceVerts[1]`;
\$v1 = <<\$p1[0] - \$p2[0],\$p1[1] - \$p2[1],\$p1[2] - \$p2[2]>>;
\$p2 = `xform -q -ws -t \$faceVerts[2]`;
\$v2 = <<\$p1[0] - \$p2[0],\$p1[1] - \$p2[1],\$p1[2] - \$p2[2]>>;
\$normalVector = cross(\$v1,\$v2);
for(\$i=3;\$i<size(\$faceVerts);\$i++) {
\$p2 = `xform -q -ws -t \$faceVerts[\$i]`;
\$v2 = <<\$p1[0] - \$p2[0],\$p1[1] - \$p2[1],\$p1[2] - \$p2[2]>>;
\$normalVector+=cross(\$v1,\$v2);
}
return(gtVectorToFloatArray(unit(\$normalVector/(size(\$faceVerts)-2))));
}

that procude also relies on two other procedures I've written:

global proc string[] gtGetVertsInRenderOrder(string \$face){
string \$vertTokens[];
string \$objTokens[];
string \$faceVerts[];
string \$faceVertsSorted[];

tokenize \$face "." \$objTokens;
\$faceVerts = `polyInfo -faceToVertex \$face`;
tokenize \$faceVerts[0] " :\n\r" \$vertTokens;
for (\$i = 2;\$i<size(\$vertTokens);\$i++) {
\$faceVertsSorted[size(\$faceVertsSorted)] = \$objTokens[0] + ".vtx[" + \$vertTokens[\$i] + "]";
}
return \$faceVertsSorted;
}

global proc float[] gtVectorToFloatArray(vector \$vect){
return({\$vect.x,\$vect.y,\$vect.z});
}

hope this helps

nier
02 February 2008, 12:31 PM
Here is a Python code to achieve that:

#gets selected poly (must be selected on stage)
sel = cmds.ls(sl=1)
if (len(sel) != 1):
mm.eval('warning "You need to select an object!";')
return
obj = sel[0]
print "Selected object: " + obj

#get numberOfFaces on poly
nFaces = cmds.polyEvaluate(obj, face=1)
print " "+obj+" has "+str(nFaces)+" faces"

#for each face
i=0
while i < nFaces:
#face name
f = obj+".f["+str(i)+"]"
#get face normal
cmds.select(f, r=1)
fNt = cmds.polyInfo(faceNormals=1)
fN =fNt[0]
fN = fN.split()
del fN[0:2]
print fN

fN will be a list [float, float, float] with the normal of each face, which you can also store in another list to have all the normals in one list...

02 February 2008, 06:15 PM
here's the pymel way of doing it:

from pymel import *
sel = ls(sl=1)
if len(sel) != 1:
raise ValueError, "You need to select an object!"

obj = sel[0]
print "Selected object: " + obj

for face in obj.faces:
print face.normal

CGTalk Moderation
02 February 2008, 06:15 PM
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.

1