#!/usr/bin/python

"""
This script takes a Wavefront .obj file
and exports a .dat file containing the same trimesh.

Colour for the faces is set to flat grey (127,127,127)
and surface normals calculated for each triangle.

This script tweaked for Platypus
"""

import sys, string, math

inputfilenames = sys.argv[2:]	# for Platypus (was [1:])
print "converting..."
print inputfilenames
for inputfilename in inputfilenames:
	outputfilename = inputfilename.lower().replace(".obj", ".dat")
	if (outputfilename == inputfilename):
		outputfilename = outputfilename,append(".1")
	print inputfilename+"->"+outputfilename
	inputfile = open( inputfilename, "r")
	lines = inputfile.read().splitlines(0)
	outputfile = open( outputfilename, "w")
	mode = 'SKIP'
	vertex_lines_out = ['VERTEX\n']
	faces_lines_out = ['FACES\n']
	n_verts = 0
	n_faces = 0
	skips = 0
	vertex=[]
	uv=[]
	face=[]
	texture=[]
	uvForVertex=[]
	uvsForTexture={}
	textureForFace=[]
	uvsForFace=[]
	textureCounter = 0
	interpretTexture = 0
	materials = {}
	max_v = [0.0, 0.0, 0.0]
	min_v = [0.0, 0.0, 0.0]
	# find materials from mtllib
	for line in lines:
		tokens = string.split(line, ' ')
		if (tokens[0] == 'mtllib'):
			path = string.split(inputfilename, '/')
			path[-1] = tokens[1]
			materialfilename = string.join(path,'/')
			print "going to open material library file: %s" % materialfilename
			infile = open( materialfilename, "r")
			mlines = infile.read().splitlines(0)
			newMaterial = 0
			for mline in mlines:
				tokens1 = string.split(mline, ' ')
				if (tokens1[0] == 'newmtl'):
					newMaterialName = tokens1[1]
					newMaterial = 1
				if (tokens1[0] == 'map_Kd'):
					if (newMaterial):
						materials[newMaterialName] = tokens1[1]
						print "Material %s -> %s" % (newMaterialName, tokens1[1])
					newMaterial = 0
	#print "materials :"
	#print materials
	# find geometry vertices first
	for line in lines:
		tokens = string.split(line, ' ')
		if (tokens[0] == 'v'):
			n_verts = n_verts + 1
	#		x = float(tokens[1])
	# negate x value for vertex to allow correct texturing...
			x = -float(tokens[1])
			y = float(tokens[2])
			z = float(tokens[3])
			vertex.append( ( x, y, z) )
			vertex_lines_out.append('%.5f, %.5f, %.5f\n' % ( x, y, z))
			if (x > max_v[0]):
				max_v[0] = x
			if (y > max_v[1]):
				max_v[1] = y
			if (z > max_v[2]):
				max_v[2] = z
			if (x < min_v[0]):
				min_v[0] = x
			if (y < min_v[1]):
				min_v[1] = y
			if (z < min_v[2]):
				min_v[2] = z
	#print "vertex:"
	#print vertex, len(vertex), n_verts
	#print "\n"
	# find texture coordinates next
	for line in lines:
		tokens = string.split(line, ' ')
		if (tokens[0] == 'vt'):
			uv.append( ( float(tokens[1]), 1.0 - float(tokens[2])) )
	#print "uv:"
	#print uv, len(uv), n_verts
	#print "\n"
	# find faces next
	for line in lines:
		tokens = string.split(line, ' ')
		if (tokens[0] == 'usemtl'):
			textureName = tokens[1]
			if (materials.has_key(textureName)):
				textureName = materials[textureName]
			interpretTexture = 1
			texture.append(textureName)
			uvsForTexture[textureName] = n_verts * [[]]
		if (tokens[0] == 'f'):
			#print "line: %s" % line
			while (len(tokens) >=4):
				bits = string.split(tokens[1], '/')
				v1 = int(bits[0]) - 1
				if (bits[1] > ''):
					vt1 = int(bits[1]) - 1
				bits = string.split(tokens[2], '/')
				v2 = int(bits[0]) - 1
				if (bits[1] > ''):
					vt2 = int(bits[1]) - 1
				bits = string.split(tokens[3], '/')
				v3 = int(bits[0]) - 1
				if (bits[1] > ''):
					vt3 = int(bits[1]) - 1
				else:
					interpretTexture = 0
				#print "face (geometry): %d %d %d" % (v1, v2, v3)
				#print "face (textures): %d %d %d\n" % (vt1, vt2, vt3)
				d0 = (vertex[v2][0]-vertex[v1][0], vertex[v2][1]-vertex[v1][1], vertex[v2][2]-vertex[v1][2])
				d1 = (vertex[v3][0]-vertex[v2][0], vertex[v3][1]-vertex[v2][1], vertex[v3][2]-vertex[v2][2])
				xp = (d0[1]*d1[2]-d0[2]*d1[1], d0[2]*d1[0]-d0[0]*d1[2], d0[0]*d1[1]-d0[1]*d1[0])
				det = math.sqrt(xp[0]*xp[0] + xp[1]*xp[1] + xp[2]*xp[2])
				if (det > 0):
					n_faces = n_faces + 1
				#	norm = (xp[0]/det, xp[1]/det, xp[2]/det)
				# negate the normal to allow correct texturing...
					norm = ( -xp[0]/det, -xp[1]/det, -xp[2]/det)
					face.append((v1,v2,v3))
					faces_lines_out.append('127,127,127,\t%.5f,%.5f,%.5f,\t3,\t%d,%d,%d\n' % (norm[0],norm[1],norm[2],v1,v2,v3))
					if (interpretTexture):
						textureForFace.append(textureName)
						uvsForTexture[textureName][v1] = uv[vt1]
						uvsForTexture[textureName][v2] = uv[vt2]
						uvsForTexture[textureName][v3] = uv[vt3]
						uvsForFace.append([ uv[vt1], uv[vt2], uv[vt3]])
				tokens = tokens[:2]+tokens[3:]
	# begin final output...
	outputfile.write('// output from Obj2DatTex.py Wavefront text file conversion script\n')
	outputfile.write('// runnign within an app created by Platypus \n')
	outputfile.write('// (c) 2005 By Giles Williams\n')
	outputfile.write('// \n')
	outputfile.write('// original file: "%s"\n' % inputfilename)
	outputfile.write('// \n')
	outputfile.write('// model size: %.3f x %.3f x %.3f\n' % ( max_v[0]-min_v[0], max_v[1]-min_v[1], max_v[2]-min_v[2]))
	outputfile.write('// \n')
	outputfile.write('// textures used: %s\n' % uvsForTexture.keys())
	outputfile.write('// \n')
	outputfile.write('NVERTS %d\n' % n_verts)
	outputfile.write('NFACES %d\n' % n_faces)
	outputfile.write('\n')
	outputfile.writelines(vertex_lines_out)
	outputfile.write('\n')
	outputfile.writelines(faces_lines_out)
	outputfile.write('\n')
	# check that we have textures for every vertex...
	okayToWriteTexture = 1
	#print "uvsForTexture :"
	#print uvsForTexture
	#print "uvsForFace :"
	#print uvsForFace
	if (len(textureForFace) != len(face)):
		okayToWriteTexture = 0
	if (len(uvsForFace) != len(face)):
		okayToWriteTexture = 0
	for texture in textureForFace:
		if (texture == ''):
			okayToWriteTexture = 0
	# if we're all clear then write out the texture uv coordinates
	if (okayToWriteTexture):
		outputfile.write('TEXTURES\n')
		for i in range(0, len(face)):
			facet = face[i]
			texture = textureForFace[i]
			uvForVertex = uvsForTexture[texture]
			outputfile.write('%s\t1.0 1.0\t%f %f\t%f %f\t%f %f\n' % (texture, uvsForFace[i][0][0], uvsForFace[i][0][1], uvsForFace[i][1][0], uvsForFace[i][1][1], uvsForFace[i][2][0], uvsForFace[i][2][1]))
	outputfile.write('\n')
	outputfile.write('END\n')
	outputfile.close();
print "done"
print ""
#
#	end
#
