import Blender
import sys
import math

from Blender import Object, NMesh, Mesh, BGL, Draw

ANGLE_SEUIL=30.0

def vec_scalaire(u, v):
	return u[0]*v[0] + u[1]*v[1] + u[2]*v[2]

def vec_vectoriel(u, v):
	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_norme(u):
	return math.sqrt(u[0]*u[0] + u[1]*u[1] + u[2]*u[2])
 
def vec_normer(u):
	n = vec_norme(u)
	return [u[0]/n, u[1]/n, u[2]/n]

def vec_soustraire(u, v):
	return [v[0]-u[0], v[1]-u[1], v[2]-u[2]]
	
def vec_angle(u, v):
	val=vec_scalaire(u,v)/(vec_norme(u) * vec_norme(v))
	if (val>1) :
		val=1
	if (val<-1) :
		val=-1
	return math.acos( val )

def GetNormaleFace(nmesh, indiceFace):
	face=nmesh.faces[indiceFace]
	return vec_normer(vec_vectoriel(vec_soustraire(face.v[0].co, face.v[1].co), vec_soustraire(face.v[0].co, face.v[2].co)))

def EcritMat(fichier, mesh, face) :
	fichier.write('Material: "')

	if (face.materialIndex!=None) and (len(mesh.getMaterials())!=0) and (mesh.getMaterials()[face.materialIndex]!=None):
		fichier.write(mesh.getMaterials()[face.materialIndex].name)
	else:
		fichier.write('SANS')
	fichier.write('"\n')


def EcritVertex(fichier, nmesh, indiceFace, indiceVertex, tableauVertexFace) :
	face=nmesh.faces[indiceFace]
	normalePrincipale=GetNormaleFace(nmesh, indiceFace)

	normale=[]
	normale.extend(normalePrincipale)
	poids=1

	for autreFace in tableauVertexFace[face.v[indiceVertex].index] :
		if (autreFace != indiceFace) :
			autreNormale=GetNormaleFace(nmesh, autreFace)
			angle=vec_angle(normalePrincipale, autreNormale)
			if (angle<ANGLE_SEUIL*math.pi/180) :
				normale[0]=(normale[0]*poids+autreNormale[0]) / (poids+1)
				normale[1]=(normale[1]*poids+autreNormale[1]) / (poids+1)
				normale[2]=(normale[2]*poids+autreNormale[2]) / (poids+1)
				normale=vec_normer(normale)
				poids=poids+1

	fichier.write('X:%s ' % face.v[indiceVertex].co[0])
	fichier.write('Y:%s ' % face.v[indiceVertex].co[1])
	fichier.write('Z:%s ' % face.v[indiceVertex].co[2])
	if (len(face.uv)>indiceVertex) :
		fichier.write('U:%s ' % face.uv[indiceVertex][0])
		fichier.write('V:%s ' % face.uv[indiceVertex][1])
	else :
		fichier.write('U:%s ' % 0)
		fichier.write('V:%s ' % 0)

	fichier.write('x:%s ' % normale[0])
	fichier.write('y:%s ' % normale[1])
	fichier.write('z:%s\n' % normale[2])



def ExportASC(nomFichier) :
	fic=open(nomFichier,'w')
	select=Object.get()

	for ob in select :
		print ob
		nomMesh=ob.data.name
		mesh=Mesh.get(nomMesh)
		if (mesh!=None) :
			x, y, z=ob.getLocation()
			nmesh=NMesh.GetRaw(nomMesh)

			# Pour chaque vertex on trouve les faces
			verts=nmesh.verts
			tableauVertexFace=[]

			for v in nmesh.verts :
				tableauVertexFace.append([])

			faces=nmesh.faces
			numFace=0
			for face in faces :
				for vert in face.v :
					tableauVertexFace[vert.index].append(numFace)
				numFace=numFace+1


			# Au sauvegarde
			numFace=0
			for indiceFace in range(len(faces)) :
				face=faces[indiceFace]
				if (len(face.v)<3) :
					print "Erreur : le face contient moins de 3 vertices !"
				else :
					numVert=0
					indiceVert=1

					while indiceVert<(len(face.v)-1) :
						fic.write('FACE: %s\n' % (numFace+1))
						EcritMat(fic, mesh, face)
						numFace=numFace+1

						fic.write('Vertex %s: ' % numVert)
						EcritVertex(fic, nmesh, indiceFace, 0, tableauVertexFace)
						numVert=numVert+1

						fic.write('Vertex %s: ' % numVert)
						EcritVertex(fic, nmesh, indiceFace, indiceVert, tableauVertexFace)
						numVert=numVert+1
						indiceVert=indiceVert+1

						fic.write('Vertex %s: ' % numVert)
						EcritVertex(fic, nmesh, indiceFace, indiceVert, tableauVertexFace)
						numVert=numVert+1

	fic.close()

NomDuFichier=Draw.Create("")
Seuil=Draw.Create(0)
def draw():
	global NomDuFichier
	global Seuil
	BGL.glClearColor(0.4,0.4,0.6,0.0)
	BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
	BGL.glRasterPos2d(5, 300)
	Draw.Text("Export d'objets pour MOGL")

	NomDuFichier=Draw.String("Nom du fichier : ", 2, 5, 220, 220, 24,"objet.tri", 200, "Nom du fichier de sauvegarde")
	Seuil=Draw.Number("Angle Seuil : ", 4, 5, 250, 220, 24, ANGLE_SEUIL, 0, 180, "Angle de seuil d'interpolation des normales")
	Draw.Button("Enregistrer", 3, 70, 180, 150, 24)
	Draw.Button("Quitter", 1, 5, 180, 60, 24)

def event(evt, val):
	if (evt==Draw.QKEY and not val):
		Draw.Exit()
		print "*** Fin1 ***"
	
def bevent(evt):
	if (evt==1):
		Draw.Exit()
		print "*** Fin2 ***"
	if (evt==3):
		print NomDuFichier.val
		ANGLE_SEUIL=Seuil.val
		print ANGLE_SEUIL
		ExportASC(NomDuFichier.val)

# ExportASC('/home/cedric/temp.toto')

print "toto"
Draw.Register(draw, event, bevent)