blender gives python acces to vertex coordinates, not face coordinates.
vertex coordinates point away from the vertex, and are not always perpendicular to the face.
to get normal coordinates for faces (traingles because they are planar) do a cross product of the vector from vertex 0 to 1, and the vector from vertex 1 to 2.
(If you have a quad it will be a good idea to do more than one cross product, normalize, and average to get your normal)
here is a portion of the code from my alpha face sorting script which does what I said (you may use it as it is incomplete)
def vec_dot(u, v):
return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]
def vec_cross(u, v):
# | i j k |
# | u0 u1 u2 |
# | v0 v1 v2 |
# (u1*v2-u2*v1)i - (u0*v2-u2*v0)j + (u0*v1-u1*v0)k
# (u1*v2-u2*v1)i + (u2*v0-u0*v2)j + (u0*v1-u1*v0)k
return [u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], u[0]*v[1]-u[1]*v[0]]
def vec_mag(u):
return sqrt(u[0]*u[0] + u[1]*u[1] + u[2]*u[2])
def vec_norm(u):
n = vec_mag(u)
return [u[0]/n, u[1]/n, u[2]/n]
def vec_between_points(u, v):
# returns the vector from point u to point v
return [v[0]-u[0], v[1]-u[1], v[2]-u[2]]
print "
--------------The Script has Begun--------------"
selectedObjs = Blender.Object.GetSelected()
if (len(selectedObjs)==0):
print "I NEED ONE SELECTED MESH!"
thisMesh = Blender.NMesh.GetRawFromObject(selectedObjs[0].name)
print "Object",selectedObjs[0].name
print "Mesh",thisMesh.name
print "Object Contains ",len(thisMesh.faces)," Faces"
alphaFaces = []
alphaFaceNorms = [] # face normals
alphaFacePoints = [] # a point of each face
alphaFacesDrawBefore = [] # the faces indicies that need to be drawn before
print "
Finding Alpha Faces..."
i = 0
while i < len(thisMesh.faces):
# print "Face", i, thisMesh.faces[i].transp
if (thisMesh.faces[i].transp == Const.ALPHA): # this is an alpha face
## btw, why did I have to look in the source to find this attribute?
alphaFaces.append(thisMesh.faces.pop(i))
else:
i += 1
print "Found", len(alphaFaces), "alpha faces and", len(thisMesh.faces), "other faces"
iffyFaces = 0
i=0
# make lists of the points and normal vectors
# that correspond to the alpha faces
print "
Finding face normals, and stuff"
while i < len(alphaFaces):
aFace = alphaFaces[i]
# non-triangles are not always planar.
if (len(aFace.v)>3):
iffyFaces += 1
alphaFaceNorms.append(vec_norm(vec_cross(vec_between_points(aFace.v[0], aFace.v[1]), vec_between_points(aFace.v[1], aFace.v[2]))))
# just a vertex on the face, which one it is should be irrelevant
alphaFacePoints.append(aFace.v[0])
# flipping normals doesn't appear to re-order verticies
if (vec_dot(alphaFaceNorms[i], alphaFacePoints[i].no)<0.0):
# the normal is (likely) opposite the direction the
# orientation of the faces would suggest
# if execution gets here the vertex normal that blender gave
# me is opposite the orientation of the faces...
# print aFace.v[0].no, alphaFaceNorms[i]
# may as well do this here...
alphaFacesDrawBefore.append([])
i += 1
it stores the alpha faces and their normals into arrays, but I am sure you can adapt it for your needs
(if you are looking down on the normal verticies are oriented counter-clock-wise… using a cross product will give this normal)