#!BPY

"""
Name: 'OBJ'
Blender: 233
Group: 'Export'
Tip: 'Export to OBJ file format. (.obj)'
"""

######################################################
# OBJ Exporter
# By:  Bob Holcomb
# Date: 19 Jan 04
# Ver: 0.6
######################################################
# This script imports a text OBJ file and the materials
#  into blender for editing.  Hopefully
# this will make it into a future version as an import
# feature of the menu.  Loader is based on OBJ loader
# from www.gametutorials.com-Thanks DigiBen!  The export
# portion is based on blenderobjex.py by Christoph Frick
# <rid@zefix.tv>
######################################################

######################################################
# Importing modules
######################################################

import Blender
from Blender import NMesh, Scene, Object, Draw, Image, Material
from Blender.BGL import *
from Blender.Draw import *
from Blender.Window import *
from Blender.Image import *
from Blender.Material import *

import sys, struct, string
from types import *

import os
from os import path

def point_by_matrix(p, m):
	return [p[0] * m[0][0] + p[1] * m[1][0] + p[2] * m[2][0] + m[3][0],
	p[0] * m[0][1] + p[1] * m[1][1] + p[2] * m[2][1] + m[3][1],
	p[0] * m[0][2] + p[1] * m[1][2] + p[2] * m[2][2] + m[3][2]]

# HACK -- it seems that some Blender versions don't define sys.argv,
# which may crash Python if a warning occurs.
if not hasattr(sys, "argv"): sys.argv = ["???"]

# Import globals
g_obj_filename=Create("model")
#search buttons
g_filename_search=Create("model")

#Globals
g_scale=Create(1.0)


# Events
EVENT_NOEVENT=1
EVENT_CHOOSE_FILENAME=3
EVENT_CHOOSE_MATERIAL=4
EVENT_EXPORT_OBJ=5
EVENT_EXIT=100

######################################################
# Callbacks for Window functions
######################################################
def filename_callback(input_filename):
	global g_obj_filename
	g_obj_filename.val=input_filename

######################################################
# GUI Loader
######################################################
def draw_gui():
	global g_scale
	global g_obj_filename
	global g_material_filename
	global g_scale_slider
	global EVENT_NOEVENT,EVENT_EXPORT_OBJ,EVENT_CHOOSE_FILENAME,EVENT_EXIT

	########## Titles
	glClear(GL_COLOR_BUFFER_BIT)
	glRasterPos2d(8, 103)
	Text("OBJ exporter")

	######### Parameters GUI Buttons
	g_obj_filename = String("OBJ file to export: ", EVENT_NOEVENT, 10, 55, 210, 18,
			g_obj_filename.val, 255, "OBJ file to load")
	########## obj File Search Button
	Button("Search",EVENT_CHOOSE_FILENAME,220,55,80,18)


	########## Scale slider-default is 1
	g_scale= Slider("Scale Factor: ", EVENT_NOEVENT, 10, 75, 210, 18,
		1.0, 0.001, 10.0, 1, "Scale factor for obj Model");

	######### Draw and Exit Buttons
	Button("Export",EVENT_EXPORT_OBJ, 10,10,80,18)
	Button("Exit",EVENT_EXIT , 170, 10, 80, 18)

def event(evt, val):
	if (evt == QKEY and not val):
		Exit()

def bevent(evt):
	global g_obj_filename
	global g_material_filename
	global EVENT_NOEVENT,EVENT_EXPORT_OBJ,EVENT_EXIT

	######### Manages GUI events
	if (evt==EVENT_EXIT):
		Exit()
	elif (evt==EVENT_CHOOSE_FILENAME):
		FileSelector(filename_callback, "OBJ File Selection")
	
	#export the object and materials
	elif (evt==EVENT_EXPORT_OBJ):
		#check if the user was lazy and didn't pick a file
		if(g_obj_filename.val=="model"):
			result=Blender.Draw.PupMenu("No filename entered.  Use Scene Name?%t|Yes|No")
			if(result==1):
				export_obj(g_obj_filename.val)
				Exit()
		#are we overwriting a file?
		if (os.path.isfile(g_obj_filename.val)):
			temp=os.path.basename(g_obj_filename.val)
			result=Blender.Draw.PupMenu("Overwrite file: "+temp+"?%t|Yes|No")
			if(result==1):
				#strip ".obj" off the filename of the overwriten file.  It's added later
				if(g_obj_filename.val[-4:]==".ico"):
					temp=g_obj_filename.val[:-4]
				export_obj(temp)
				Exit()
		else:
			if(g_obj_filename.val[-4:]==".ico"):
				temp=g_obj_filename.val[:-4]
			export_obj(temp)
			Exit()

Register(draw_gui, event, bevent)

######################################################
# EXPORT
######################################################
def export_obj(filename):
	#open the current scene
	scene = Blender.Scene.GetCurrent()
	#if the user was lazy and didn't add a filename,
	#just name the files after the scene name
	#hope they weren't lazy there too.
	if filename=="model":
		filename=scene.getName()
		#basefilename and /path/filename are the same
		bfilename=filename
	else:
		#extract the actual filename from the
		#entire path of the /path/filename
		bfilename = os.path.basename(filename)

	vdata = ""
	
	current_material = ""

	image=""
	
	#get a list of the objects in the scene
	obj_list=scene.getChildren()
	
	vn=0
	
	#loop through the objects in the scene
	for current_obj in obj_list:
		if current_obj.getType()=="Mesh":
			mesh=current_obj.getData()
			matrix=current_obj.getMatrix()
			for f in mesh.faces:
				if len(f.v)!=3:
					print("Bad face "+str(len(f.v)))
					co=point_by_matrix(f.v[0].co,matrix)
					Blender.Window.SetCursorPos(co)
					Blender.Redraw()
					return
				image=f.image.getFilename()
				for vnum in range(3):
					v=f.v[vnum]
					co=point_by_matrix(v.co,matrix)
					x=int((co[0]/g_scale.val)*4096)
					y=int(-((co[2]/g_scale.val)*4096))
					z=int((co[1]/g_scale.val)*4096)
					vdata = vdata + struct.pack("hhhH",x,y,z,0)
					x=int((v.no[0]/g_scale.val)*4096)
					y=int(-((v.no[2]/g_scale.val)*4096))
					z=int((v.no[1]/g_scale.val)*4096)
					vdata = vdata + struct.pack("hhhH",x,y,z,0)
					u=int((f.uv[vnum][0])*4096)
					v=int((1-(f.uv[vnum][1]))*4096)
					vdata = vdata + struct.pack("hh",u,v)
					vdata = vdata + struct.pack("BBBB",127,127,127,255) # RGBA no se usan de momento
					vn=vn+1
	
	
	icofile = open( filename+".ico", "w" )
	icofile.write(struct.pack("IIIII",0x010000,1,7,0x3f800000,vn)) # header
	icofile.write(vdata) # vector data
	icofile.write(struct.pack("IIIII",0x01,1,0,0,1)) # animation header
	icofile.write(struct.pack("IIII",0,1,0,0x3f800000)) # frame 1
	
	os.system("convert -depth 8 -size 128x128 "+image+" rgb:"+os.path.splitext(filename)[0]+".rgb")
	rfile=open(os.path.splitext(filename)[0]+".rgb","r")
	for i in range(128*128):
		(r,g,b)=struct.unpack("BBB",rfile.read(3))

		r=int(r/8)
		g=int(g/8)
		b=int(b/8)
		
		n=0
		
		n=n+r
		n=n+(g<<5)
		n=n+(b<<10)
		n=n+(1<<15)
#		print "TIMd: "+str(n)+" RGB"+str(r)+" "+str(g)+" "+str(b)
		d=struct.pack("H",n)
		icofile.write(d)

	icofile.close()
	rfile.close()	
				
