#!BPY

__author__ = "Martin 'theeth' Poirier"
__url__ = ("http://www.blender.org", "http://www.elysiun.com")
__version__ = "based on 2.1"

__bpydoc__ = """\
This script exports the UV face layout of the selected mesh object to
a TGA image file with variable width and height.  Then you can, for example, paint details
in this image using an external 2d paint program of your choice and bring it back
to be used as a texture for the mesh.

Notes:<br>
	 Jean-Michel Soler (jms) wrote TGA functions used by this script.<br>
	 Zaz added the default path code and Selected Face option.<br>
	 Macouno fixed a rounding error in the step calculations<br>
	 Jarod added the SVG file export<br>
"""


import Blender

from math import *

def ExportCallback(f):
	obj = Blender.Object.GetSelected()[bIndex]
	
	time1= Blender.sys.time()
	
	if not obj:
		Blender.Draw.PupMenu("ERROR%t|No Active Object!")
		return

	if obj.type != "Mesh":
		Blender.Draw.PupMenu("ERROR%t|Not a Mesh!")
		return

	mesh = obj.getData()
	if not mesh.hasFaceUV():
		Blender.Draw.PupMenu("ERROR%t|No UV coordinates!")
		return

	if bObFile:
		name = AddExtension(f, obj.name)
	else:
		name = AddExtension(f, None)
		
	UVFaces = ExtractUVFaces(mesh, bAllFaces)
	
	if len(UVFaces) > 0:
		print "TGA export is running..."
		UV_Export_TGA(UVFaces, bWidth, bHeight, bWSize, name)
		print "...finished exporting in %.4f sec." % (Blender.sys.time()-time1)	

def GetExtension():
	ext = "tga"
	return ext
	
def AddExtension(filename, object_name):
	ext = "." + GetExtension()
	
	hasExtension = (ext in filename or ext.upper() in filename)
	
	if object_name and hasExtension:
		filename = filename.replace(ext, "")
		hasExtension = False
		
	if object_name:
		filename += "_" + object_name
		
	if not hasExtension:
		filename += ext
		
	return filename
	
def GetDefaultFilename():
	filename = Blender.Get("filename")
	
	filename = filename.replace(".blend", "")
	filename += "." + GetExtension()
	
	return filename

def ExtractUVFaces(mesh, allface):
	FaceList = []
	if not allface:
		faces = mesh.faces
	else:
		faces = mesh.getSelectedFaces()

	for f in mesh.faces:
		if not allface or f.sel:
			if bMatid != None:
				if f.materialIndex == bMatid:
					FaceList.append(f.uv)
			else:
				FaceList.append(f.uv)
	
	return FaceList


def Buffer(height=16, width=16, profondeur=1,rvb=255 ):  
	"""  
	reserve l'espace memoire necessaire  
	"""  
	p=[rvb]  
	myb=height*width*profondeur
	#print"Memory  : %ikB" % (myb/1024)
	b=p*myb
	return b


def rle_compress(bitmap):
	ret = []
	count = 1
	tmp = -1
	for t in bitmap:
		if tmp == -1:
			tmp = t
		if tmp != t:
			if count == 1:
				count = 0
			else:
				count += 127
			ret.append([count, tmp])
			count = 1
			tmp = t
		else:
			if count == 128:
				ret.append([255, tmp])
				count = 1
			else:
				count += 1
	ret.append([count, tmp])
	return ret
		

def write_tgafile(loc2,bitmap,width,height,profondeur):  
	
	f=open(loc2,'wb')

	Origine_en_haut_a_gauche=32
	Origine_en_bas_a_gauche=0

	Data_Type_2=10
	RVB=profondeur*8
	RVBA=32
	entete0=[]
	for t in range(18):
	  entete0.append(chr(0))

	entete0[2]=chr(Data_Type_2)
	entete0[13]=chr(width/256)
	entete0[12]=chr(width % 256)
	entete0[15]=chr(height/256)
	entete0[14]=chr(height % 256)
	entete0[16]=chr(RVB)
	entete0[17]=chr(Origine_en_bas_a_gauche)

	#print"  ...writing tga..."
	for t in entete0:
	  f.write(t)
	
	blackpx=chr(0) + chr(0) + chr(0)
	whitepx=chr(255) + chr(255) + chr(255)
			
	rle_array = rle_compress(bitmap)
	for elem in rle_array:
		f.write(chr(elem[0]))
		if elem[1] == 255:
			f.write(whitepx)
		else:
			f.write(blackpx)		
		
	f.close()
	
	
def UV_Export_TGA(vList, width, height, wsize, file):
	minx = 0
	miny = 0
	
	scale_x = 1.0
	scale_y = 1.0
	
	step = 0

	img = Buffer(width+1,height+1)

	wrapSize_x = width
	wrapSize_y = height
	
	fnum = 0
	fcnt = len (vList)

	for f in vList:
		fnum = fnum + 1
		if not fnum % 100:
			print "%i of %i Faces completed" % (fnum, fcnt)
			
		for index in range(len(f)):
			co1 = f[index]
			if index < len(f) - 1:
				co2 = f[index + 1]
			else:
				co2 = f[0]

			step = int(ceil(width*sqrt((co1[0]-co2[0])**2+(co1[1]-co2[1])**2)))
			if step:
				for t in range(step):
					x = int(floor((co1[0] + t*(co2[0]-co1[0])/step) * width))
					y = int(floor((co1[1] + t*(co2[1]-co1[1])/step) * height))

					x = x % wrapSize_x
					y = y % wrapSize_y
						
					co = x * 1 + y * 1 * width;
					
					img[co] = 0
					if wsize > 1:
						for x in range(-1*wsize + 1,wsize):
							for y in range(-1*wsize,wsize):
								img[co + 1 * x + y * 1 * width] = 0
	
		for v in f:
			x = int(v[0] * width)
			y = int(v[1] * height)

			x = x % wrapSize_x
			y = y % wrapSize_y

			co = x * 1 + y * 1 * width
			img[co] = 1
	
	write_tgafile(file,img,width,height,3)
	
def Export(obj_index, only_selected_flag, width, height, wsize):
	global bObFile, bAllFaces, bWSize, bWidth, bHeight, bIndex, bMatid
	bObFile = True
	bAllFaces = only_selected_flag
	bWSize = wsize
	bWidth = width
	bHeight = height
	bIndex = obj_index
	bMatid = None
	Blender.Window.FileSelector(ExportCallback, "Save UV (%s)" % GetExtension(), GetDefaultFilename())
	
def batch_export(obj_index, matid, filename, only_selected_flag, width, height, wsize):
	global bObFile, bAllFaces, bWSize, bWidth, bHeight, bIndex, bMatid
	bObFile = False
	bAllFaces = only_selected_flag
	bWSize = wsize
	bWidth = width
	bHeight = height
	bIndex = obj_index
	bMatid = matid
	ExportCallback(filename)
	

	