Messed Up TriangleNormal

Hi, I’m trying to use TriangleNormal from Mathutils, but I can’t get it to work properly. Currently, if i multiply the normal that TriangleNormal returns by a large number, the normal approximates the true normal. Otherwise, it points down. I’d rather not have to approximate the normal, what is wrong with my script?

``````
#Hopefully simulates light
import Blender as b
detail = 2
#Get scene, etc.
scn = b.Scene.GetCurrent()
#Making base mesh...
tmesh = b.Mesh.Primitives.Cube()
#Now that there is a mesh, let's make it an object, named "Tree",
tobj = scn.objects.new(tmesh, "Tree")
#and place its center at (0, 0, 1)
tobj.setLocation(0,0,1)
#Create a mesh for the ground with an edge length of 200.
gmesh = b.Mesh.Primitives.Plane(200)
#Now, make gmesh an object, named "Ground",
gobj = scn.objects.new(gmesh, "Ground")
#and set it at (0, 0, 0).
gobj.setLocation(0,0,0)
#Make the sun mesh using an icosphere, using detail to determine how subdivided it is,
smesh = b.Mesh.Primitives.Icosphere(detail, int(detail))
#make it an object named "Sun",
sobj = scn.objects.new(smesh, "Sun")
#and place its center at (0, 0, 10).
sobj.setLocation(0,0,10)
#Get location from which each light ray will be emitted
light = 0
#Rays is a list of all of the light rays created.
rays = []
#Omat is the sun's matrix.
omat = sobj.getMatrix()
#For each of the sun's faces,
for face in smesh.faces:
#Get the sun's mesh, as a Mesh object, not an NMesh object.
smesh = sobj.getData(mesh = True)
#For each vert in the mesh,
for vert in smesh.verts:
#the coordinates are the local ones times the object's matrix,
vert.co = (vert.co * omat) - omat.translationPart()
#Get the face;s normal,
######################################
facenormal = b.Mathutils.TriangleNormal(face.verts[0].no, face.verts[1].no, face.verts[2].no)
######################################
#and the face's center point.
center = face.cent * omat
#HERE IS THE PROBLEM
###############################
#I can fix it here by changing 1 to a large number. Why/How does this work?
facenormal = facenormal * 1
###############################
#SET the mouse to the last center.
b.Window.SetCursorPos(center)
print center, "&lt;=======CENTER"
center = b.Mathutils.Vector(center)
pair = []
pair.append(facenormal)
pair.append(center)
tuple(pair)
rays.append(pair)
print pair[1], center, "PAIR[1] = CENTER"
#Using these normals, check if
for face in tmesh.faces:
for  vertex in face.verts:
vertex.co = (vertex.co * omat) - omat.translationPart()
for pair in rays:
#Intersect(corner1, corner2, corner3, raydirection, origin, only count a[rea in triangle=1)
vec = b.Mathutils.Intersect(face.verts[0].co, face.verts[1].co, face.verts[2].co, pair[0], pair[1], 0)
#print pair[1], "&lt;====pair[1]", center, "&lt;====center"
if vec != None:
#print vec, "= vec"
light = light + 1

#print light, "= light"
#THIS IS PURELY FOR TESTING, REMOVE EVENTUALLY.
lmesh = b.Mesh.New()
scn.objects.new(lmesh, "TEST")
lverts =  [pair[1], (pair[0])]
# print lverts, "LVERTS"
n = 1
lmesh.verts.extend(lverts)
lmesh.faces.extend(0, 1)

b.Redraw()

``````

it seems you refer to the wrong attribute of the vertices:

``````
facenormal = b.Mathutils.TriangleNormal(face.verts[0].no, face.verts[1].no, face.verts[2].no)

``````

should be (highlighted)

``````
facenormal = b.Mathutils.TriangleNormal(face.verts[0].<b><i>co</i></b>, face.verts[1].<b><i>co</i></b>, face.verts[2].<i><b>co</b></i>)

``````

You may approximate a face normal by vertex normals but then you have to add them together and normalize them. That is a fairly useless exercise though as vertex normals are derived from face normals that share that vertex.

BTW, you don’t have to calculate the face normal at all: once you added a face to a mesh its normal is available as the no attribute

Even if i just use [facenormal = face.no], i still don’t get the correct normals. They point down still. If I make:
#The face normal multiplied by the matrix.

facenormal = face.no * omat

I get something closer to the correct normals, but they still are not correct. Am I supposed to multiply normals by the matrix? What do I need to do to get the correcct normals?

Nevermind, the problem was not with the normals, (although those were incorrect at first as well), but that my definition of the line that was supposed to trace the normal was wrong. I defined:

#the vertices of the line to be [the center of the face, the normal]
lverts = [ pair[1], pair[0] ]

This was completely wrong. I had to define it to be:

lverts = [pair[1], (pair[0] + pair[1]) ] to get the correct line.

That was a dumb mistake, thanks varkenvarken for your help.