#!BPY

""" 
Name: 'UV-Space-Coordinator'
Blender: 248
Group: 'UV'
Tooltip: 'Allows some work on the uv coordinates of a selected mesh (scale, arrange, export)'	
"""

__author__ = "Sammler Rene"
__url__ = ("http://www.blender.org", "http://www.sammler-mediengestaltung.com")
__version__ = "v070706"

__bpydoc__ = """\
***** BEGIN GPL LICENSE BLOCK *****

This program is free software; you can redistribute it and/or<br>
modify it under the terms of the GNU General Public License<br>
as published by the Free Software Foundation; either version 2<br>
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

***** END GPL LICENCE BLOCK *****
--------------------------------------------------------------------------

This script allows some work on uv coordinates:<br>
	1. Scale the uv coordinates in dependency of the object<br>
	   size to the texture size.<br>
	2. Arrange the uv coordinates on the texture space.<br>
	3. Fit the uv coordinates to image size.<br>
	4. Export the uv coordinates to a TGA image file.<br>

Usage:

First select an object and create uv coordinates. Than make your settings on the 
ScriptUI and choose the button 'Calc and Scale UV'.
If you deselect the option 'AS' (auto scale), you have to use the button 'Calc UV' first
and than 'Scale UV'.<br>
Note: if you change some settings after you press 'Calc UV', you have to press this button again to make the changes take effect.

Notes:<br>
	 The TGA-Export-Script is a modified version (to export<br>
	 also rectangular images)of the pythonscript<br>
	 'uv_export.py'<br>
	 Jean-Michel Soler (jms) wrote TGA functions used by<br>
	 this script.<br>
	 Zaz added the default path code and Selected Face<br>
	 option.<br>
	 Macouno fixed a rounding error in the step calculations.<br>
"""


import Blender
from Blender.Draw import *
from Blender.BGL import *
from Blender.Types import *
from Blender.Object import *
from Blender.Window import *
from Blender.Mathutils import *
import uv_export_width_height


def ExportConfig():
	global export_dir
	conf = {}
	
	conf["HIGHT"] = hoehe.val
	conf["WIDTH"] = breite.val
	conf["AUTO"] = auto.val
	conf["ONLYSEL"] = only_selected.val
	conf["BUNIT"] = blend_unit_base.val
	conf["PIXEL"] = pixel_base.val
	conf["NORMALLST"] = normalize_lst
	conf["AUTOSCALE"] = auto_scale.val
	
	conf["ARR_ACTIVE"] = is_arrange.val
	conf["MIN_X"] = arr_min_x.val
	conf["MIN_Y"] = arr_min_y.val
	conf["MAX_X"] = arr_max_x.val
	conf["MAX_Y"] = arr_max_y.val
	conf["CEN_X"] = arr_cen_x.val
	conf["CEN_Y"] = arr_cen_y.val		
	
	conf["FIT_ACTIVE"] = is_fit.val
	conf["FIT_X"] = fit_x.val
	conf["FIT_Y"] = fit_y.val
	conf["FIT_XY"] = fit_xy.val	
	
	conf["EXPORT_ACTIVE"] = is_export.val
	conf["WSIZE"] = wsize.val

	conf["BATCH_ACTIVE"] = is_batch.val
	
	Blender.Registry.SetKey("UVSPACECOORD", conf, True)
	export_dir = ""

def ImportConfig():
	global hoehe, breite, auto, blend_unit_base, pixel_base, only_selected, normalize_lst
	global is_arrange, arr_min_x, arr_cen_x, arr_max_x, arr_min_y, arr_cen_y, arr_max_y	
	global is_fit, fit_x, fit_y, fit_xy
	global is_export, auto_export, use_obj_name, wsize
	
	conf = Blender.Registry.GetKey("UVSPACECOORD", True)
	
	if not conf:
		return
	
	try:
		
		hoehe.val = conf["HIGHT"]
		breite.val = conf["WIDTH"]
		auto.val = conf["AUTO"]
		only_selected.val = conf["ONLYSEL"]
		blend_unit_base.val = conf["BUNIT"]
		pixel_base.val = conf["PIXEL"]
		auto_scale.val = conf["AUTOSCALE"]		
		if conf["NORMALLST"]:
			normalize_lst = conf["NORMALLST"]	
		
		is_arrange.val = conf["ARR_ACTIVE"]
		arr_min_x.val = conf["MIN_X"]
		arr_min_y.val = conf["MIN_Y"]
		arr_max_x.val = conf["MAX_X"]
		arr_max_y.val = conf["MAX_Y"]
		arr_cen_x.val = conf["CEN_X"]
		arr_cen_y.val =	conf["CEN_Y"]	
		
		is_fit.val = conf["FIT_ACTIVE"]
		fit_x.val = conf["FIT_X"]
		fit_y.val = conf["FIT_Y"] 
		fit_xy.val = conf["FIT_XY"]
		
		is_export.val = conf["EXPORT_ACTIVE"]
		wsize.val = conf["WSIZE"]

		is_batch.val = conf["BATCH_ACTIVE"]		
				
	except KeyError:
		pass



def type_check(obj_list, index = 0):
	global failur
	ret = 0
	if len(obj_list) == 0: 
		failur = "ERROR: Select a mesh object first!!"
		print failur
		ret = 1
	elif type(obj_list[index].getData()) != NMeshType: 
		failur = "ERROR: '"+obj_list[index].name+"' isn't a mesh object!!"
		print failur
		ret = 1
	else: failur = ""
	return ret


def handleBtnGroup(to_deactivate):
	for elem in to_deactivate:
		elem.val = 0

def create_menustr (str, aray):
	ret = str + "%t"
	for i in range (0, len(aray)):
		tmp1 = "|"
		tmp2 = "%d" % (aray[i])
		tmp3 = "%x"
		tmp4 = "%d" % (i) 
		ret += tmp1+tmp2+tmp3+tmp4
	return ret


def normalize(val, norm):
		i = 0
		ret = -1
		while ret == -1:
			if i == len(norm): ret = 0
			elif norm[i] > val: ret = norm[i]
			i += 1
		return ret

def calc_uv(face, only_select_flag):
	global difference, factor
	uv_coords = face.uv
	threshold = 1
	if only_select_flag == 0 or face.sel:
		for i in range (0, len(face.v)):
			if min[0] == "x":
				min[0] = face.uv[i][0]
				max[0] = face.uv[i][0]
				min[1] = face.uv[i][1]
				max[1] = face.uv[i][1]
			else:
				if face.uv[i][0] < min[0]: min[0] = face.uv[i][0]
				elif face.uv[i][0] > max[0]: max[0] = face.uv[i][0]
				if face.uv[i][1] < min[1]: min[1] = face.uv[i][1]
				elif face.uv[i][1] > max[1]: max[1] = face.uv[i][1]
			if len(face.v) > 2:
				p1 = i
				if i == len(face.v) - 1: p2 = 0
				else: p2 = i + 1
				if i == len(face.v) - 2: p3 = 0
				elif i == len(face.v) - 1: p3 = 1
				else: p3 = i + 2
				
				tmp_vec1 = face.v[p1].co - face.v[p2].co
				tmp_vec2 = face.v[p2].co - face.v[p3].co 
				
				tmp_uvvec1 = Vector(face.uv[p1]) - Vector(face.uv[p2])
				tmp_uvvec2 = Vector(face.uv[p2]) - Vector(face.uv[p3]) 
	
				if tmp_vec1.length > 0 and tmp_vec2.length > 0:
					proportion_v = tmp_vec1.length / tmp_vec2.length
				else: proportion_v = -1
				if tmp_uvvec1.length > 0 and tmp_uvvec2.length > 0:
					proportion_uv = tmp_uvvec1.length / tmp_uvvec2.length
				else: proportion_uv = -1
				if proportion_v > 0 and proportion_uv > 0:
					if proportion_uv < proportion_v + threshold and proportion_uv > proportion_v - threshold:
						tmp_dif = proportion_uv - proportion_v
						if tmp_dif < 0: tmp_dif *= -1
						if difference == "x" or difference > tmp_dif: 
							difference = tmp_dif
							factor = tmp_vec1.length / tmp_uvvec1.length	

def scale_uv(face, alt_x, alt_y, scale_x, scale_y, min, neu_x_min, neu_y_min, only_select_flag):
	uv_coords = face.uv
	tmp_uv = []
	if only_select_flag == 0 or face.sel:
		for j in uv_coords:
			tmp_x = neu_x_min + ((j[0] - min[0]) * 100 / alt_x) * scale_x / 100
			tmp_y = neu_y_min + ((j[1] - min[1]) * 100 / alt_y) * scale_y / 100
			tmp_uv.append((tmp_x,tmp_y))		
		face.uv = tmp_uv	

def recalc_uv_space(mode, flags, blenderunits, pixelunits, width, height, normal, obj_index = 0):
	global min, max, difference, factor, failur, uv_reset, export_dir, hoehe, breite
	obj = Blender.Object.GetSelected()[obj_index]
	mesh = Blender.NMesh.GetRawFromObject(obj.name)
	lst_of_faces = []
	tmp1 = len(obj.getMaterials())
	tmp2 = len(mesh.getMaterials())
	if tmp1 > tmp2: tmp = tmp1
	else: tmp = tmp2	
	if flags[3] and tmp > 0:
		for mat in xrange(tmp):
			lst_of_faces.append([])
		for face in mesh.faces:
			lst_of_faces[face.materialIndex].append(face)
	else:
		lst_of_faces.append(mesh.faces)
	
	for matid in range(0,len(lst_of_faces)):
		faces = lst_of_faces[matid]
		if mode == 0 or mode == 1:
			factor = 1
			difference = "x"
			min = ["x","x"]
			max = ["x","x"]
			
			print "-------------------------------------------------"
			[calc_uv(face, flags[0]) for face in faces]
			print "uv-space-calculation is done"
				
			uv_x = (max[0] - min[0]) 
			uv_y = (max[1] - min[1]) 		
			
			o[0] = (pixelunits * uv_x * factor) / blenderunits
			o[1] = (pixelunits * uv_y * factor) / blenderunits
			if flags[1] == 1:			
				n[0] = normalize(o[0],normal)
				n[1] = normalize(o[1],normal)
				hoehe.val = n[1]
				breite.val = n[0]
			else:
				n[0] = width
				n[1] = height
			s[0] = (o[0] * 100 / n[0])/100
			s[1] = (o[1] * 100 / n[1])/100
			
			if s[0] > 1 and s[1] > 1:
				failur = "WARNING: The Scalfactor in X and Y direction is about 1!"
			elif s[0] > 1:
					failur = "WARNING: The Scalfactor in X direction is about 1!"
			elif s[1] > 1:
				failur = "WARNING: The Scalfactor in Y direction is about 1!"	

			obj.properties.update({'uvspace_min': min})
			obj.properties.update({'uvspace_max': max})

		if mode == 0 or mode == 2:
			if mode == 2:
				try:
					min = obj.properties.convert_to_pyobject()['uvspace_min']	
					max = obj.properties.convert_to_pyobject()['uvspace_max']	
					uv_x = (max[0] - min[0]) 
					uv_y = (max[1] - min[1])				
				except KeyError:
					min = ['x','x'] 
					failur = "Please execute Calc UV first!"
			
			if min[0] != 'x':
				neu_x_min = (1 - s[0])/2
				neu_y_min = (1 - s[1])/2
				
				uv_reset = Blender.NMesh.GetRawFromObject(obj.name)
				[scale_uv(face,uv_x, uv_y, s[0], s[1], min, neu_x_min, neu_y_min, flags[0]) for face in faces]
				print "scale uv coordinates is done"
				
				Blender.NMesh.PutRaw(mesh, mesh.name, 0, 0)
				if len(mesh.getMaterials()) > 0:
					obj.setMaterials(mesh.getMaterials())
				obj.colbits = int(pow(2, len(obj.getMaterials())) - 1)
				print "update mesh is done"
				
				if flags[2] == 1:
					if n[0] > 0 and n[1] > 0:
						if flags[3] and tmp > 0:
							uv_export_width_height.batch_export(obj_index, matid, export_dir+obj.name+"_matid"+str(matid), flags[0], n[0], n[1], wsize.val)
						else:
							uv_export_width_height.batch_export(obj_index, None, export_dir+obj.name, flags[0], n[0], n[1], wsize.val)
					else:
						failur = "Invalid image width or image height!"
				failur = "The calculations for object '"+obj.name+"' is done."
				print failur
	failur = "Operation complete!"


def arrange_uvs(x_direction, y_direction, only_select_flag, by_mat_groups, obj_index = 0):
	global min, max, uv_reset
	obj = Blender.Object.GetSelected()[obj_index]
	mesh = Blender.NMesh.GetRawFromObject(obj.name)
	lst_of_faces = []
	tmp1 = len(obj.getMaterials())
	tmp2 = len(mesh.getMaterials())
	if tmp1 > tmp2: tmp = tmp1
	else: tmp = tmp2	
	if by_mat_groups and tmp > 0:
		for mat in xrange(tmp):
			lst_of_faces.append([])
		for face in mesh.faces:
			lst_of_faces[face.materialIndex].append(face)
	else:
		lst_of_faces.append(mesh.faces)
	
	for matid in range(0,len(lst_of_faces)):
		faces = lst_of_faces[matid]	
	
		min = ["x","x"]
		max = ["x","x"]

		[calc_uv_bb(face,only_select_flag) for face in faces]	

		size_x = max[0] - min[0]	
		size_y = max[1] - min[1]
		
		ofset_x = 0
		ofset_y = 0

		if x_direction[1] == 1:
			ofset_x = (0.5 - (min[0] + size_x / 2.0))
		elif x_direction[0] == 1:
			ofset_x = (0 - min[0])
		elif x_direction[2] == 1:
			ofset_x = (1 - max[0])
			
		if y_direction[1] == 1:
			ofset_y = (0.5 - (min[1] + size_y / 2.0))
		elif y_direction[0] == 1:
			ofset_y = (0 - min[1])
		elif y_direction[2] == 1:
			ofset_y = (1 - max[1])
		
		uv_reset = Blender.NMesh.GetRawFromObject(obj.name)	
		[execute_arrange_uv(face, ofset_x, ofset_y, only_select_flag) for face in faces]
		
		Blender.NMesh.PutRaw(mesh, mesh.name, 0 , 0)	

def execute_arrange_uv(face, ofset_x, ofset_y, only_select_flag):
	if only_select_flag == 0 or face.sel:	
		uv_coords = face.uv
		tmp_uv = []
		for j in uv_coords:
			tmp_x = j[0] + ofset_x
			tmp_y = j[1] + ofset_y
			tmp_uv.append((tmp_x,tmp_y))		
		face.uv = tmp_uv


def fit_uvs (fit_to, only_select_flag, by_mat_groups, obj_index = 0):
	global min, max, uv_reset
	obj = Blender.Object.GetSelected()[obj_index]
	mesh = Blender.NMesh.GetRawFromObject(obj.name)
	lst_of_faces = []
	tmp1 = len(obj.getMaterials())
	tmp2 = len(mesh.getMaterials())
	if tmp1 > tmp2: tmp = tmp1
	else: tmp = tmp2	
	if by_mat_groups and tmp > 0:
		for mat in xrange(tmp):
			lst_of_faces.append([])
		for face in mesh.faces:
			lst_of_faces[face.materialIndex].append(face)
	else:
		lst_of_faces.append(mesh.faces)
	
	for matid in range(0,len(lst_of_faces)):
		faces = lst_of_faces[matid]	

		min = ["x","x"]
		max = ["x","x"]

		[calc_uv_bb(face,only_select_flag) for face in faces]	

		size_x = max[0] - min[0]	
		size_y = max[1] - min[1]	
			
		scale_x = 1
		scale_y = 1
		
		if fit_to[2] == 1:
			if size_x > size_y:
				scale_y = (size_y * 100 / size_x) / 100
			else:
				scale_x = (size_x * 100 / size_y) / 100
		
		uv_reset = Blender.NMesh.GetRawFromObject(obj.name)
		[execute_fit_uv(fit_to,face, size_x, size_y, min, scale_x, scale_y,only_select_flag) for face in faces]
		
		Blender.NMesh.PutRaw(mesh, mesh.name, 0 , 0)

def execute_fit_uv(fit_to, face, size_x, size_y, min, scale_x, scale_y, only_select_flag):
	if only_select_flag == 0 or face.sel:
		uv_coords = face.uv
		tmp_uv = []
		min_x = min_y = 0
		for j in uv_coords:
			if fit_to[0] == 1 or fit_to[2] == 1:
				if scale_x < 1:
					min_x = (1 - scale_x) / 2
				tmp_x = min_x + ((j[0] - min[0]) * 100 / size_x) * scale_x / 100
			else:
				tmp_x = j[0]

			if fit_to[1] == 1 or fit_to[2] == 1:
				if scale_y < 1:
					min_y = (1 - scale_y) / 2					
				tmp_y = min_y + ((j[1] - min[1]) * 100 / size_y) * scale_y / 100
			else:
				tmp_y = j[1]
				
			tmp_uv.append((tmp_x,tmp_y))		
		face.uv = tmp_uv		


def calc_uv_bb(face, only_select_flag):
	if only_select_flag == 0 or face.sel:
		uv_coords = face.uv
		for i in range (0, len(face.v)):
			if min[0] == "x":
				min[0] = face.uv[i][0]
				max[0] = face.uv[i][0]
				min[1] = face.uv[i][1]
				max[1] = face.uv[i][1]
			else:
				if face.uv[i][0] < min[0]: min[0] = face.uv[i][0]
				elif face.uv[i][0] > max[0]: max[0] = face.uv[i][0]
				if face.uv[i][1] < min[1]: min[1] = face.uv[i][1]
				elif face.uv[i][1] > max[1]: max[1] = face.uv[i][1]	

def set_dir(f_name):
	global export_dir
	tmp = f_name.rfind("\\")
	if tmp != -1:
		export_dir = f_name[0:tmp+1]
		print "The export directory is set to '"+f_name[0:tmp+1]+"'!"	

def set_export_dir():
	Blender.Window.FileSelector(set_dir, "Set Export Dir", "")

def tga_export(f_name):
	global failur
	tmp = f_name.rfind("\\")
	if tmp != -1:
		filename = f_name[0:tmp+1]

	obj_lst = Blender.Object.GetSelected()
	edit_mode = EditMode()
	if EditMode(): EditMode(0)
	for i in range(0, len(obj_lst)):
		if type_check(obj_lst, i) == 0:		
			if breite.val > 0 and hoehe.val > 0:
				if not batch_obj.val and not batch_mat_groups.val:
					uv_export_width_height.batch_export(i, None, filename+obj_lst[i].name, only_selected.val, breite.val, hoehe.val, wsize.val)
					failur = "Export is done."
					print failur
					break
				else:
					if batch_mat_groups.val:
						tmp1 = len(obj_lst[i].getMaterials())
						tmp2 = len(Blender.NMesh.GetRawFromObject(obj_lst[i].name).getMaterials())
						if tmp1 > tmp2: tmp = tmp1
						else: tmp = tmp2
						for matid in xrange(tmp):
							uv_export_width_height.batch_export(i, matid, filename+obj_lst[i].name+"_matid"+str(matid), only_selected.val, breite.val, hoehe.val, wsize.val)
						if tmp == 0:
							uv_export_width_height.batch_export(i, None, filename+obj_lst[i].name, only_selected.val, breite.val, hoehe.val, wsize.val)
						if not batch_obj.val:
							break
					else:
						uv_export_width_height.batch_export(i, None, filename+obj_lst[i].name, only_selected.val, breite.val, hoehe.val, wsize.val)					
					failur = "Export for '"+obj_lst[i].name+"' is done."
					print failur
			else:
				failur = "Invalid image width or image height!"
				break
	failur = "Export complete."
	print failur
	if edit_mode: EditMode(1)						

def BEvent(evt):
	global blend_unit_base, blend_unit, pixel, pixel_base, breite, hoehe, only_selected,normal_list_gui,normalize_lst, auto
	global arr_min_x, arr_cen_x, arr_max_x, arr_min_y, arr_cen_y, arr_max_y
	global uv_reset, failur
	global fit_x, fit_y, fit_xy
	global export_dir, auto_export, auto_scale, batch_obj, batch_mat_groups
	
	failur = ""
	
	if evt == 1:
		try:
			print "--------------- Calculate and Scale UV's ---------------"
			obj_lst = Blender.Object.GetSelected()
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			for i in range(0, len(obj_lst)):
				if type_check(obj_lst, i) == 0:		
					uv_space = recalc_uv_space(0, [only_selected.val, auto.val, auto_export.val, batch_mat_groups.val], blend_unit_base.val, pixel_base.val, breite.val, hoehe.val, normalize_lst, i)
					if not batch_obj.val: break
			if edit_mode: EditMode(1)
			failur = "Operation complete."
			print failur				
		except KeyError:
			failur = "There are no mapping coordinates available!"				

	if evt == 2:
		try:
			print "--------------- Calculate UV's ---------------"
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			if type_check(Blender.Object.GetSelected()) == 0:		
				uv_space = recalc_uv_space(1, [only_selected.val, auto.val, auto_export.val, 0], blend_unit_base.val, pixel_base.val, breite.val, hoehe.val, normalize_lst)
			if edit_mode: EditMode(1)
			failur = "Operation complete."
			print failur				
		except KeyError:
			failur = "There are no mapping coordinates available!"				
	
	if evt == 3:
		try:
			print "--------------- Scale UV's ---------------"
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			if type_check(Blender.Object.GetSelected()) == 0:		
				recalc_uv_space(2, [only_selected.val, auto.val, auto_export.val, 0], blend_unit_base.val, pixel_base.val, breite.val, hoehe.val, normalize_lst)
			if edit_mode: EditMode(1)
			failur = "Operation complete."
			print failur				
		except KeyError:
			failur = "There are no mapping coordinates available!"
					
	elif evt == 4:		
		edit_mode = EditMode()
		if EditMode(): EditMode(0)
		if type_check(Blender.Object.GetSelected()) == 0:					
			obj = Blender.Object.GetSelected()[0]
			if uv_reset != 0 and Blender.NMesh.GetRawFromObject(obj.name).name == uv_reset.name:
				Blender.NMesh.PutRaw(uv_reset, uv_reset.name, 0 , 0)
				uv_reset = 0
			else:
				failur = "No reset point for this object available!"
		if edit_mode: EditMode(1)
	
	elif evt == 5:
		if len(normalize_lst) == 0 or normalize_lst[len(normalize_lst)-1] < breite.val:
			normalize_lst.append(breite.val)
			normal_list_gui.val = len(normalize_lst)-1
		else:
			for i in range(0,len(normalize_lst)):
				if normalize_lst[i] > breite.val: 
					normalize_lst.insert(i, breite.val)
					normal_list_gui.val = i
					break
	
	elif evt == 6:
		if len(normalize_lst) == 0 or normalize_lst[len(normalize_lst)-1] < hoehe.val:
			normalize_lst.append(hoehe.val)
			normal_list_gui.val = len(normalize_lst)-1
		else:
			for i in range(0,len(normalize_lst)):
				if normalize_lst[i] > hoehe.val: 
					normalize_lst.insert(i, hoehe.val)
					normal_list_gui.val = i
					break
	
	elif evt == 7:
		if len(normalize_lst) > 0:
			breite.val = normalize_lst[normal_list_gui.val]
	
	elif evt == 8:
		if len(normalize_lst) > 0:
			hoehe.val = normalize_lst[normal_list_gui.val]
	
	elif evt == 9:
		if normal_list_gui.val < len(normalize_lst):
			del normalize_lst[normal_list_gui.val]
			if normal_list_gui.val == len(normalize_lst): normal_list_gui.val = 0
	
	elif evt == 10:
		normalize_lst = [normalize_lst_base[i] for i in range(0,len(normalize_lst_base))]
	
	elif evt == 11:
		try:
			print "--------------- Arrange UV's ---------------"
			obj_lst = Blender.Object.GetSelected()
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			for i in range(0, len(obj_lst)):
				if type_check(obj_lst, i) == 0:	
					arrange_uvs([arr_min_x, arr_cen_x, arr_max_x],[arr_min_y, arr_cen_y, arr_max_y],only_selected.val, batch_mat_groups.val,i)					
					if not batch_obj.val: break
					failur = "Operation for '"+obj_lst[i].name+"' complete."
					print failur							
			if edit_mode: EditMode(1)
			failur = "Operation complete."
			print failur					
		except KeyError:
			failur = "There are no mapping coordinates available!"
		
	elif evt == 12:
		try:
			print "--------------- Fit UV's ---------------"
			obj_lst = Blender.Object.GetSelected()
			edit_mode = EditMode()
			if EditMode(): EditMode(0)
			for i in range(0, len(obj_lst)):
				if type_check(obj_lst, i) == 0:	
					fit_uvs([fit_x.val,fit_y.val,fit_xy.val],only_selected.val, batch_mat_groups.val,i)					
					if not batch_obj.val: break
					failur = "Operation for '"+obj_lst[i].name+"' complete."
					print failur							
			if edit_mode: EditMode(1)
			failur = "Operation complete."
			print failur				
		except KeyError:
			failur = "There are no mapping coordinates available!"	
	elif evt == 13:
		print "--------------- TGA Export ---------------"
		try:
			Blender.Window.FileSelector(tga_export, "Set Export Dir", "")
		except KeyError:
			failur = "There are no mapping coordinates available!"
	elif evt == 100:
		if arr_min_x.val == 1:
			handleBtnGroup([arr_cen_x, arr_max_x])
	elif evt == 101:
		if arr_cen_x.val == 1:
			handleBtnGroup([arr_min_x, arr_max_x])			
	elif evt == 102:
		if arr_max_x.val == 1:
			handleBtnGroup([arr_min_x, arr_cen_x])
	elif evt == 103:
		if arr_min_y.val == 1:
			handleBtnGroup([arr_cen_y, arr_max_y])
	elif evt == 104:
		if arr_cen_y.val == 1:
			handleBtnGroup([arr_min_y, arr_max_y])
	elif evt == 105:
		if arr_max_y.val == 1:
			handleBtnGroup([arr_min_y, arr_cen_y])
	elif evt == 106:
		if fit_x.val == 1:
			handleBtnGroup([fit_xy])
	elif evt == 107:
		if fit_y.val == 1:
			handleBtnGroup([fit_xy])
	elif evt == 108:
		if fit_xy.val == 1:
			handleBtnGroup([fit_x, fit_y])
	elif evt == 109:
		if auto_export.val == 1:
			set_export_dir()
	elif evt == 110:
		if not auto_scale.val:
			auto_scale.val = 1
			failur = "The 'auto scale mode' is switched off!"
	elif evt == 111:
		if batch_obj.val or batch_mat_groups.val:
			batch_obj.val = 0
			batch_mat_groups.val = 0
			failur = "All 'batch modes' are switched off!"
	elif evt == 112:
		if not auto_scale.val:
			auto_scale.val = 1
			failur = "The 'auto scale mode' is switched off!"			
	elif evt == 50:
		ExportConfig()
		Exit()
		return
		
	Blender.Redraw(1)	
	Blender.Window.Redraw(Blender.Window.Types['IMAGE'])

def Event(evt, val):
	if evt == QKEY:
		ExportConfig()
		Exit()
		return

def  GUI ():
	global blend_unit_base, failur, pixel_base, breite, hoehe, auto, only_selected, normal_list_gui,auto_scale
	global is_arrange, arr_min_x, arr_cen_x, arr_max_x, arr_min_y, arr_cen_y, arr_max_y
	global is_fit, fit_x, fit_y, fit_xy
	global is_export, auto_export, wsize
	global is_batch, batch_mat_groups, batch_obj

	glColor3f(0.7, 0.7, 0.7)
	glRecti(15, 15, 385,295)
	glColor3f(0.9, 0.9, 0.9)
	glRecti(15, 15, 385, 30)
	glColor3f(0.65, 0.65, 0.65)	
	glRecti(15, 295, 385, 315)
	
	glColor3f(0.0, 0.0, 0.0)
	glRasterPos2f(20,302)		
	Text("UV-Space-Coordinator (v 07 07 06)")			

	glColor3f(0.15, 0.15, 0.15)

	blend_unit_base = Number("blendunits: ", 0, 100, 250, 120, 20, blend_unit_base.val, 0, 1000, "the blender units for the pixel-blender-unit relationship")
	pixel_base = Number("pixel: ", 0, 260, 250, 120, 20, pixel_base.val, 0, 7500, "the pixelunits for the pixel-blender-unit relationship")
	glRasterPos2f(20,255)		
	Text("Units Setup:")	
	glRasterPos2f(230,255)		
	Text("<->")	

	breite = Number("width: ", 0, 100, 220, 120, 20, breite.val, 2, 7500, "the width of the texture")
	hoehe = Number("height: ", 0, 260, 220, 120, 20, hoehe.val, 2, 7500, "the height of the texture")
	glRasterPos2f(20,225)		
	Text("image setup:")		
	glRasterPos2f(237,225)		
	Text("x")	
	
	glRasterPos2f(20,200)		
	Text("normalize setup:")		
	
	normal_list_gui = Menu(create_menustr ("Normalize To", normalize_lst), 0, 205, 170, 175, 20, normal_list_gui.val, "the normalize values")
	auto = Toggle("AutoNormalize", 0, 20, 170, 175, 20, auto.val, "use automatic normalization")	
	add_width = Button("Add Width", 5, 20, 145, 118, 20, "adds the image width from Image Setup to the normalize-list")
	add_height = Button("Add Height", 6, 20, 120, 118, 20, "adds the image height from Image Setup to the normalize-list")
	use_width = Button("Use Width", 7, 142, 145, 116, 20, "use the choosen value from the normalize-list for the width at the Image Setup")
	use_height = Button("Use Height", 8, 142, 120, 116, 20, "use the choosen value from the normalize-list for the height at the Image Setup")	
	del_value = Button("Del Value", 9, 262, 145, 118, 20, "deletes the choosen value from the normalize list")
	reset_list = Button("Reset", 10, 262, 120, 118, 20, "returns the normalize-list to the default values")

	only_selected = Toggle("Only Selected", 0, 20, 35, 90, 20, only_selected.val, "scale only selected uvs")
	auto_scale = Toggle("AS", 111, 115, 35, 20, 20, auto_scale.val, "change between the automatic and manual modus")
	if auto_scale.val == 1:
		scale = Button("Calc and Scale UV", 1, 140, 35, 125, 20, "calculate and scale the uv-coordinates")
	else:
		only_calc = Button("Calc UV", 2, 140, 35, 60, 20, "calculate the uv-coordinates")
		only_scale = Button("Scale UV", 3, 205, 35, 60, 20, "scale the uv-coordinates")

	reset = Button("Reset", 4, 270, 35, 55, 20, "reset the uv-coordinates of the last updated mesh (note: the function will not work if you have changed the name of the mesh)") 
	quit = Button("Quit", 50, 330, 35, 50, 20, "quit the script")	

	is_arrange = Toggle("Arrange UVs", 0, 20, 277, 85, 13, is_arrange.val, "activate the uv-arrange-panel")
	if is_arrange.val == 1:
		tmp_x = 390
		tmp_y = 195
		
		glColor3f(0.7, 0.7, 0.7)
		glRecti(tmp_x, tmp_y + 10, tmp_x+200, tmp_y+100)
		glColor3f(0.15, 0.15, 0.15)
		glRasterPos2f(tmp_x+5, tmp_y+90)		
		Text("arrange UVs:", "small")					
	
		arr_min_x = Toggle("Min X", 100, tmp_x+5, tmp_y+65, 60, 20, arr_min_x.val, "arrange the uvs to minimal x values of the image")		
		arr_cen_x = Toggle("Center X", 101, tmp_x+70, tmp_y+65, 60, 20, arr_cen_x.val, "arrange the uvs to the center position in x direction")		
		arr_max_x = Toggle("Max X", 102, tmp_x+135, tmp_y+65, 60, 20, arr_max_x.val, "arrange the uvs to maximal x values of the image")
				
		arr_min_y = Toggle("Min Y", 103, tmp_x+5, tmp_y+40, 60, 20, arr_min_y.val, "arrange the uvs to minimal y values of the image")		
		arr_cen_y = Toggle("Center Y", 104, tmp_x+70, tmp_y+40, 60, 20, arr_cen_y.val, "arrange the uvs to the center position in y direction")		
		arr_max_y = Toggle("Max Y", 105, tmp_x+135, tmp_y+40, 60, 20, arr_max_y.val, "arrange the uvs to maximal y values of the image")		
		
		arrange_uvs = Button("Arrange UVs", 11, tmp_x+5, tmp_y+15, 190, 20, "arrange the uvs")
	
	is_fit = Toggle("Fit UVs", 0, 112, 277, 85, 13, is_fit.val, "activate the uv-fit-panel")	
	if is_fit.val == 1:
		tmp_x = 390
		tmp_y = 129
		
		glColor3f(0.7, 0.7, 0.7)
		glRecti(tmp_x, tmp_y+10, tmp_x+200, tmp_y+75)
		glColor3f(0.15, 0.15, 0.15)
		glRasterPos2f(tmp_x+5, tmp_y+65)		
		Text("fit UVs:", "small")			
		
		fit_x = Toggle("Fit to X", 106, tmp_x+5, tmp_y+40, 60, 20, fit_x.val, "fit uvs to the imagewidth")	
		fit_y = Toggle("Fit to Y", 107, tmp_x+70, tmp_y+40, 60, 20, fit_y.val, "fit uvs to the imageheight")		
		fit_xy = Toggle("Fit to XY (fix proportion)", 108, tmp_x+135, tmp_y+40, 60, 20, fit_xy.val, "fit uvs to the imagesize and keep the width height relation of the uv-coordinates")			
		fit_uvs = Button("Fit UVs to Imagesize", 12, tmp_x+5, tmp_y+15, 190, 20, "fit uvs to the imagesize")

	is_export = Toggle("Export UVs", 0, 203, 277, 85, 13, is_export.val, "activate the uv-export-panel")
	if is_export == 1:
		tmp_x = 390
		tmp_y = 57	
		
		glColor3f(0.7, 0.7, 0.7)
		glRecti(tmp_x, tmp_y+15, tmp_x+200, tmp_y+80)
		glColor3f(0.15, 0.15, 0.15)
		glRasterPos2f(tmp_x+5, tmp_y+70)		
		Text("export UVs:", "small")
	
		auto_export = Toggle("Auto Export", 109, tmp_x+5, tmp_y+45, 125, 20, auto_export.val, "export the uv-coordinates automaticly after the scale process")	
		wsize = Number("Wire: ", 0, tmp_x+135, tmp_y+45, 60, 20, wsize.val, 1, 9, "set the wiresize (pixel) of the exported mesh")		
			
		export_uvs = Button("Export UV's", 13, tmp_x+5, tmp_y+20, 190, 20, "export uvs to a tga image")	

	is_batch = Toggle("Batch", 0, 295, 277, 85, 13, is_batch.val, "activate the batch-panel")
	if is_batch == 1:
		tmp_x = 390
		tmp_y = 25	
		
		glColor3f(0.7, 0.7, 0.7)
		glRecti(tmp_x, tmp_y+5, tmp_x+200, tmp_y+45)
		glColor3f(0.15, 0.15, 0.15)
		glRasterPos2f(tmp_x+5, tmp_y+35)		
		Text("batch options:", "small")
	
		batch_mat_groups = Toggle("All MatGroups", 112, tmp_x+5, tmp_y+10, 93, 20, batch_mat_groups.val, "the scaling process will be done for every material group of the selected object")	
		batch_obj = Toggle("All Sel Objects", 110, tmp_x+103, tmp_y+10, 93, 20, batch_obj.val, "the scaling process will be done for every selected object")		

	glRasterPos2f(20,80)		
	Text("Width:")	
	glRasterPos2f(20,60)		
	Text("Height:")	
	glRasterPos2f(70,100)	
	Text("Original Pixel")
	glRasterPos2f(170,100)	
	Text("Normal. Pixel")
	glRasterPos2f(270,100)	
	Text("Scalefactor")

	glRasterPos2f(70,80)	
	Text(str(o[0])[0:12], "small")
	glRasterPos2f(170,80)	
	Text(str(n[0])[0:12], "small")
	glRasterPos2f(270,80)	
	Text(str(s[0])[0:12], "small")

	glRasterPos2f(70,60)	
	Text(str(o[1])[0:12], "small")
	glRasterPos2f(170,60)	
	Text(str(n[1])[0:12], "small")
	glRasterPos2f(270,60)	
	Text(str(s[1])[0:12], "small")
	
	glRasterPos2f(100,5)	
	Text("created by Rene Sammler (sammler-mediengestaltung.com) (v 07 07 06)", "tiny")

	glColor3f(1.0, 0.0, 0.0)
	glRasterPos2f(20,20)	
	Text(failur)	


o = [0,0]
n = [0,0]
s = [0,0]
failur = ""

normalize_lst_base = [16,32,64,128,256,512,1024,1500,2048,2500,3000,3500,4096,4500,5000,5500,6000,6500,7000,7500]
normalize_lst = [16,32,64,128,256,512,1024,1500,2048,2500,3000,3500,4096,4500,5000,5500,6000,6500,7000,7500]

hoehe = Create(1024)
breite = Create(1024)
auto = Create(1)
only_selected = Create(0)
blend_unit_base = Create(15.357)
pixel_base = Create(2048)
normal_list_gui = Create(0)
auto_scale = Create(1)

is_arrange = Create(0)
arr_min_x = Create(0)
arr_cen_x = Create(1)
arr_max_x = Create(0)
arr_min_y = Create(0)
arr_cen_y = Create(1)
arr_max_y = Create(0)

is_fit = Create(0)
fit_x = Create(0)
fit_y = Create(0)
fit_xy = Create(0)

is_export = Create(0)
auto_export = Create(0)
wsize = Create(1)

is_batch = Create(0)
batch_mat_groups = Create(0)
batch_obj = Create(0)

uv_reset = 0
export_dir = Blender.Get("homedir")+"\\"

ImportConfig()
print "--------------- UV Space Coordinator ---------------"
Register(GUI, Event, BEvent)
Blender.Redraw(1)
