#!BPY

""" Registration info for Blender menus: <- these words are ignored
Name: 'Gimp Palet Manager'
Blender: 248
Group: 'Materials'
Tip: 'Import/create/export/manage colors Palettes'
"""
# Renamed from Transpal Express
__author__ = "Raphael Betemps (dwarf)"
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Materials/TransplExpress")
__version__ = "0.7 03/2005"

__bpydoc__ = """\
This script imports palettes from gimp 2.0 and above. You can import/create palettes
from the current Blender File, or from a Mesh vertices colors. The script can
manage an unlimited number of palettes.

Then, you can apply colors to materials, or to Mesh vertices colors (NMcols).

A : Usage for Objects:

1 - import or select a palette

2 - Select  color in the palette with the right mouse button

3 - Select an Object (with materials), select the material you
	want to midify and press "assign".
	
B : Usage for Meshs:

1 - import or select a palette

2 - Select one or more Mesh objects

3 - Apply the palette to the mesh(s) by using misc options:

		* Spherical map from cursor
		* Use UV Mapping
		* Materials colors to Mesh Colors
		* Draw surfaces borders
		* Apply by using Edges Sharpness (to get dust or snow effects)
		* Apply by using different vectors (view, x,y,z axis, cursor->object, etc...)
	
		
	You can mix colors (from palette and original) by using the "mix" button.

NOTES  - The script is still alpha, and can be very slow on large Meshs.
	   - You can get palettes for gimp here : http://www.gimp.org
 

"""

# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) 2003,2004: Rick Kimball rick@vrmlworld.net
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 *****
	
	
import Blender

try:
	import time
except:
	#print "Python on installe - profile tmps impossible"
	Blender.Draw.PupMenu(" !!! Python introuvable - profile tmps impossible !!!")
	
from Blender.Draw import *
from Blender.BGL import *
from Blender import Window,Registry, Mathutils,sys,Mesh,Image

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# palette par defaut, au cas ou le scrip n'en trouve aucune sur le disque

def MakeDefaultPal():
	#print "MakeDefaultPal() 87"
	
	defaultPal=[]

	for ri in range(6):
		for vi in range(6):
			for bi in range(6):
				defaultPal.append([pow(ri+1,3),pow(vi+1,3),pow(bi+1,3)])
		
	for gray_step in range(40):
		gray=int(gray_step*6.55)
		defaultPal.append([gray,gray,gray])


	try:
		palettes=Registry.GetKey("palettes")
		print palettes.keys()
	except:
		palettes={}

	palData=[defaultPal,"Default"," Palette"]
	palettes["current"]=palData
	Registry.SetKey("palettes",palettes)

def inversePal():
	#print "inversePal() 110"
	palettes=Registry.GetKey("palettes")
	palData=palettes["current"]
	palData[0].reverse()
	#palettes={}
	#palettes["current"]=palData
	Registry.SetKey("palettes",palettes)

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# palette extraite des materiaux du fichier courrant

def getBlendPal():
	
	palette=[]
	mats=Blender.Material.Get()
	
	localpath=Blender.Get("filename")
	fileData=getpath(localpath)
	
	
	for mat in mats:
		R=int(mat.R*255)
		G=int(mat.G*255)
		B=int(mat.B*255)
		col=[R,G,B]
		palette.append(col)
	
	palette.sort()	
	
	miss=256-len(mats)
	for fill in range(miss,0,-1):
		palette.append([fill,fill,fill])
	palette.reverse()
	palData=[palette,"From_file-",fileData[1]]
	return palData
	
######################################################

def getPalFromMesh(object):
	
	me=object.getData()
	box=object.getBoundBox()[0]
	palCols=[]
	lnPal=256
	palette=range(lnPal)
	
	for face in me.faces:
		i=0
		for v in face.v:
			col=face.col[1]
			sortCol=getPointsDist(box,[v.co[0],v.co[1],v.co[2]])
			palCols.append([sortCol,col.r,col.g,col.b])
			i+=1
			
	palCols.sort()

	i=0
	long=len(palCols)
	for col in palette:
		indice=i*long/lnPal
		palette[i]=palCols[indice][1:]
		i+=1

	palette1=[]
	for i in range(0,len(palette),16):
		cols=palette[i:i+16]
		cols.sort()
		for col in cols:
			palette1.append(col)

	palette1.sort()

	palData=[palette1,"From_mesh-",me.name]
	return palData

######################################################	
	
def exportCurrentPal(palData):
	palette=palData[0]
	palette_tmp=palette[:]
	palette_tmp.reverse()
	
	localpath=Blender.Get("filename")
	fileData=getpath(localpath)
	
	paltxt="GIMP Palette exported from Blender\n"
	paltxt+="FILE : "+Blender.Get("filename")+"\n"
	for col in palette_tmp:
		line=""
		for num_val in col:
			val=str(num_val)
			if len(val) == 1: val="00"+val
			if len(val) == 2: val="0"+val
			val+=" "
			line+=val
		paltxt+=line+"\n"
	
	#print fileData
	file=fileData[0]+palData[2]+".gpl"
	#print file
	saveFile(file,paltxt)
	
	gradient=exportGimpGradient(palData)
	gradient_file=fileData[0]+palData[2]+".ggr"
	saveFile(gradient_file,gradient)
		

def exportGimpGradient(palData):
	
	pal=palData[0]
	n=len(pal)
	s=1.0/n
	LX=0 #segment extremite gauche
	RX=LX+s #extremite droite
	i=1
	
	gradient="GIMP Gradient\n"
	gradient+="Name: "+palData[2]+"\n"
	gradient+=str(n)+"\n"
	
	for col1 in pal:
		MX=(LX+RX)/2.0

		r1=col1[0]/255.0
		g1=col1[1]/255.0
		b1=col1[2]/255.0
		
		col2=pal[i]
		r2=col2[0]/255.0
		g2=col2[1]/255.0
		b2=col2[2]/255.0
			
		colors=str(r1)+" "+str(g1)+" "+str(b1)+" 1.0 "
		colors+=str(r2)+" "+str(g2)+" "+str(b2)+" 1.0 0 0\n"

		segment=str(LX)+" "+str(MX)+" "+str(RX)+" "+colors
		LX=RX
		RX+=s
		if(i<n-1):i+=1
		gradient+=segment
		
	return gradient





# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# importe la palette choisie -- attention, ce doit etre une palette provenant de gimp 2.0
# ou supperieur. 

def getMenuPal(palName):
	#print "getMenuPal(palName) 224"
	palettes=Registry.GetKey("palettes")
	palNew=palettes[palName]
	palettes["current"]=palNew
	Registry.SetKey("palettes",palettes)
	
def getPalKeys():
	try:
		palettes=Registry.GetKey("palettes")
		return palettes.keys()
	except:
		return []

def getpath(filepath):
	filename=[]
	for i in range (len(filepath)-1,-1,-1):
		if ord(filepath[i])==ord(sys.sep):
			path=filepath[0:i+1]
			break
		filename.append(filepath[i])
	filename.reverse()	
	file=""
	file=file.join(filename)
	file=file.replace(".blend","")

	return [path,file]			

def loadPal(filename):
	getPal(filename)

def getPal(filename):
	#print "getPal("+filename+") 246"
	#fonctionne pour les palettes de gimp 2.0
	
	file=open(filename,'rb')
	palette=[]
	
	for ln in file.readlines():
		col=[ln[0:3],ln[4:7],ln[8:11]]
		for val in col:
			i=col.index(val)
			try:
				col[i]=int(val)
				
			except:
				col="txt"
				break
		if col != "txt":
			palette.append(col)

	palette.reverse()

	if len(palette)==0:
		MakeDefaultPal()

	else:
		
		fileData=getpath(filename)
		palData=[palette,fileData[0],fileData[1]]

		if "palettes" in Registry.Keys():
			palettes=Registry.GetKey("palettes")
			palettes["current"]=palData

			if palData[2] not in palettes.keys():
				palettes[palData[2]]=palData
			
			Registry.SetKey("palettes",palettes)
			
		else:
	
			palettes={}
			palettes["current"]=palData
			Registry.SetKey("palettes",palettes)



# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# creation du code qui sera evalue, avec eval(), par la fonction gui().
# Il s'agit d'afficher la palette sous forme de petits carres de couleurs

def make_menu_options(mat_list):

	op="Menu%t"
	X=1
	for e in mat_list:
		op=op+"| "+e+" "+"%x"+`X`
		X=X+1
	return op

def make_square255(xpos,ypos,xsize,ysize,border,r1,g1,b1):
	glColor3f(0,0,0)
	glRectf(xpos,ypos,xpos+xsize,ypos+ysize)
	glColor3f(r1/255.0, g1/255.0, b1/255.0)
	glRectf(xpos+border,ypos+border,xpos+xsize-border,ypos+ysize-border)
	
def make_square(xpos,ypos,xsize,ysize,border,r1,g1,b1):
	glColor3f(0,0,0)
	glRectf(xpos,ypos,xpos+xsize,ypos+ysize)
	glColor3f(r1, g1, b1)
	glRectf(xpos+border,ypos+border,xpos+xsize-border,ypos+ysize-border)

def make_squarecol(xpos,ypos,xsize,ysize,border,r,g,b):
	txt="glColor3f("+`r`+","+`g`+","+`b`+"),"
	txt=txt+"glRectf("+`xpos`+","+`ypos`+","+`xpos+xsize-border`+","+`ypos+ysize-border`+")"
	return txt

def make_txt_eval(chn,x,y,r,g,b):
	txt="glColor3f("+`r`+","+`g`+","+`b`+"),"
	txt=txt+"glRasterPos2i("+`x`+","+`y`+"),"
	txt=txt+"Text('"+`chn`+"')"
	return txt

def make_codepal_gl(palette,xmax,xsize,ysize,xpos=0,ypos=0,border=2):
	
	codepal_lst=[]
	ycount=0
	xcount=0
	xstart=xpos
		
	for e in palette:
		R=float(e[0])
		G=float(e[1])
		B=float(e[2])
		r=R/255.0
		g=G/255.0
		b=B/255.0

		if xcount < xmax :
			txt=make_squarecol(xpos+5,ypos+5,xsize,ysize,border,r,g,b)
			codepal_lst.append(txt)
			xcount=xcount+1
			xpos=xpos+xsize
	
		if xcount == xmax:
			ypos=ypos+ysize
			ycount=ycount+1
			xpos=xstart
			xcount=0
	
	return codepal_lst		

def get_color(mousepos):
	global xmax,ycount,xsize,ysize
	loc=((mousepos[1]/ysize)*xmax)+(mousepos[0]/xsize)
	return loc

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Fonctions pour ecrire les VextexCOls dans l'UVMap


def getUVCols(face,x,y):
	uvCols=[]
	i=0
	for v in face.v:
		U=int(face.uv[i][0]*x-0.5)
		V=int(face.uv[i][1]*y-0.5)
		uvCols.append((U,V,face.col[i]))
		i+=1
	return uvCols

def drawUVGL(uvCols):
	glBegin(GL_POLYGON);
	for uv in uvCols:
  		glColor3f(uv[2].r/255.0,uv[2].g/255.0,uv[2].b/255.0)
  		glVertex2i(uv[0],uv[1])	
	glEnd();
	
	glEnable(GL_BLEND);
	glEnable(GL_LINE_SMOOTH);
	glBegin(GL_LINE_LOOP);
	for uv in uvCols:
  		glColor3f(uv[2].r/255.0,uv[2].g/255.0,uv[2].b/255.0)
  		glVertex2i(uv[0],uv[1])	
	glEnd();
	

def col2img(me,x,y,img,dx,dy):
	#print "col2img"
	glDrawBuffer(GL_BACK)
	
	r,g,b=r1/255.0,g1/255.0,b1/255.0
	glClearColor(r,g,b,0.0)
	glClear(GL_COLOR_BUFFER_BIT)
	for face in me.faces:
		uvCols=getUVCols(face,x,y)
		drawUVGL(uvCols)
		
	im=Buffer(GL_BYTE,[x*y,4])
	glReadBuffer(GL_BACK)
	glReadPixels(dx,dy,x,y,GL_RGBA,GL_BYTE,im)
	
	mxvt=len(im)/x
	vt=0
	hz=0
	for i in im:
		if vt==mxvt:
			vt=0
			hz+=1
		img.setPixelI(vt,hz,(i[0]*2,i[1]*2,i[2]*2,255))
		vt+=1

	

		
# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# recuperation de la liste des materiaux du mesh

def get_mats():
	try:
		objet=Blender.Object.GetSelected()
		me = objet[0].getData()
		ls_tmp = me.getMaterials()
		mat_list=[]
		for e in ls_tmp:
			mat_list.append(e.name)
	except:
		mat_list=[]
		#print "Select an object"
		Blender.Draw.PupMenu(" !! Select a Mesh object / Selectionnez un objet de type Mesh !!")
	return mat_list

def setMixMeshCols(colMesh,colPal,mix):
	# fait un mix de la couleur du mesh
	# avec celle de la palette
	
	colMesh.r=int(colMesh.r-(-colPal[0]+colMesh.r)*mix)
	colMesh.g=int(colMesh.g-(-colPal[1]+colMesh.g)*mix)
	colMesh.b=int(colMesh.b-(-colPal[2]+colMesh.b)*mix)


##############################################################

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# position relative de la souris

def getRealativeMousePos():
	wins=Window.GetScreenInfo()
	winid=Window.GetAreaID()
	for win in wins:
		if winid==win["id"]:
			absoluteMousePos=Window.GetMouseCoords()
			relativeMousePos=[absoluteMousePos[0]-win["vertices"][0]-5,absoluteMousePos[1]-win["vertices"][1]-5]
			return relativeMousePos
	

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# utils
		
def sort(list):
	list.sort()
	return list
	
def reverse(list):
	list.reverse()
	return list

	
def getLoopList(list,index):
	count=len(list)
	if index >= count:
		i= index - count*(index/count)
	elif index < 0:
		i= index - count*(index/count)
	else:
		i=index
	return list[i]
	
def saveFile(file,chaine):
	f=open(file,'w')
	f.writelines(chaine)
	f.close()

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# utils meshes

def testMeshVColUV(object):
	me=object.getData()
	if me.hasVertexColours() == 0:
		me.hasVertexColours(1)
	if me.hasFaceUV() == 0:
		me.hasFaceUV(1)		
	me.update()	


def getPointsDist(p1,p2):

	d2=pow(p1[0]+p2[0],2)+pow(p1[1]+p2[1],2)+pow(p1[2]+p2[2],2)
	return pow(d2,0.5)
		

def getEffectVector(indice):
	# vecteurs de comparaison 
	# avec les normales 

	x=Mathutils.Vector([-1,0,0])
	y=Mathutils.Vector([0,-1,0])
	z=Mathutils.Vector([0,0,1])
	
	view=Window.GetViewVector()
	vview=Mathutils.Vector(view)
	vview.normalize()
	
	cp=Window.GetCursorPos()		
	ob=Blender.Object.GetSelected()[0]
	loc=ob.getLocation()
	cv_tmp=[cp[0]-loc[0],cp[1]-loc[1],cp[2]-loc[2]]
	curv=Mathutils.Vector(cv_tmp)
	curv.normalize()
	
	vecs=[x,y,z,vview,curv]
	
	return vecs[indice]

	
# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Fonctions pour appliquer la palette au mesh

def paintMesh01(object,palData,mix,EffectVector):
	#print "paintMesh01 630 "
	
	me=object.getData()

	palette=palData[0]
	palSize=len(palette)

	
	verts=range(len(me.verts))
	
	fi=0
	for f in me.faces:
		fnor=Mathutils.Vector(f.no)
		fnor.normalize()
		
		vi=0
		for v in f.v:
			col=f.col[vi]
			vnor=Mathutils.Vector([v.no[0],v.no[1],v.no[2]])
			vnor.normalize()
			if type(verts[v.index]) == type(1):

				verts[v.index]=[[fnor],[col],vnor]
			else:
				verts[v.index][0].append(fnor)
				verts[v.index][1].append(col)
			vi+=1
		fi+=1
				
	
	indices=[]
	for vfaces in verts:
		fi1=0
		vx,vy,vz=0,0,0
		for nor in vfaces[0]:
			vx+=nor[0]
			vy+=nor[1]
			vz+=nor[2]
	
		fnor=Mathutils.Vector([vx,vy,vz])
		fnor.normalize()
		vnor=vfaces[2]
		
		indice=Mathutils.DotVecs(EffectVector,fnor)
		indices.append(indice)
		
	
	#itmp=sort(indices[:])		
	#imax=itmp[-1]
	#imin=itmp[0]
	imax,imin=max(indices),min(indices)
	
	id=0
	for vfcol in verts:
	
		indice=indices[id]
		iCol=int((palSize-1)*abs(indice-imin)/(imax-imin))

		colPal=palette[iCol]
		for col in vfcol[1]:
			setMixMeshCols(col,colPal,mix)
		
		id+=1
	
	me.update()


##############################################################

def paintMesh02(object,palData,mix):
	#print "paintMesh02 699 "
	#t1=time.time()
	# colorisation spherique depuis le curseur
	
	cp= Window.GetCursorPos()			
	#me=object.getData()
	me=Mesh.Get(object.data.name)
	loc=object.getLocation()
	origin=[-loc[0]+cp[0],-loc[1]+cp[1],-loc[2]+cp[2]]
	palette=palData[0]
	palSize=len(palette)
	
	
	
	vdist=[]
	vcols=[]
	for face in me.faces:
		i=0
		for v in face.v:
			vdist.append(getPointsDist(origin,v.co))
			vcols.append(face.col[i])
			i+=1
			
	
	
	#dst=sort(vdist[:])
	#dmax=dst[-1]
	#dmin=dst[0]
	dmax,dmin=max(vdist),min(vdist)
	
	a=(palSize-1)/(dmax-dmin)
	b=-dmin*a
	
	
	for indice in range(len(vdist)):
		x=vdist[indice]
		iCol=int(a*x+b)
		colPal=palette[iCol]
		col=vcols[indice]
		setMixMeshCols(col,colPal,mix)
		
	
	#t2=time.time()
	#print 10*(t2-t1), "seconde(s)"
	me.update()
	

##############################################################
	
def paintMesh03(object,palData,mix):
	# colorisation selon map UV
			
	me=object.getData()
	palette=palData[0]
	palSize=len(palette)
	
	#print xmax
	
	
	rootPal=pow(palSize,0.5)
	#print 
	for face in me.faces:
		i=0
		for uv in face.uv:
			
			icol=int((uv[0]+uv[1])*(palSize-1)/2.0)
			if icol> 255:
				icol=255
			colPal=palette[icol]
			col=face.col[i]
			setMixMeshCols(col,colPal,mix)
			
			i+=1
	
	me.update()


##############################################################
# fonctions pour PaintMesh 4 et 4b

def getWebEdges01(me):

	vtl=range(len(me.verts))
	for e in me.edges:
		
		a,b=e.v1,e.v2
		
		if type(vtl[a.index]) != type([]):
				vtl[a.index]=[b]
		else :
			if b not in vtl[a.index]: vtl[a.index].append(b)
				
		if type(vtl[b.index]) != type([]):
				vtl[b.index]=[a]
		else :
			if a not in vtl[b.index]: vtl[b.index].append(a)

	return vtl


def getEdgesRawDots01(vtl,me):
					
	iv=0
	dots=[]
	for vtx in vtl:
		X,Y,Z=0,0,0
		vert=me.verts[iv]
		for pt in vtx:
			X+=vert.co[0]-pt.co[0]
			Y+=vert.co[1]-pt.co[1]
			Z+=vert.co[2]-pt.co[2]
			
		vec_tmp=Mathutils.Vector([X,Y,Z])
		dot=Mathutils.DotVecs(vec_tmp,vert.no)
		dots.append(dot)
		iv+=1	
	return dots
	
def getEdgesSmoothDots01(dots,sharp=0):
	
	
	dotmax=max(dots)
	dotmin=min(dots)
	
	if sharp==0:
		return dots,dotmin,dotmax
	else:
		di=0
		for elm in dots:
			dot=elm+abs(dotmin)
			dots[di]=pow(dot,sharp)
			di+=1

		dotmax=pow(dotmax+abs(dotmin),sharp)
		dotmin=pow(dotmin+abs(dotmin),sharp)
		return dots,dotmin,dotmax
		

def paintMesh04(object,palData,mix,sharp=0.5):
	# colorisation des sommets selon durete
	print "paintMesh04 -- 760"
	Window.drawProgressBar(0.5, "paint4")
	me=Mesh.Get(object.data.name)
	palette=palData[0]
	palSize=len(palette)
	
	
	vtl=getWebEdges01(me)
	rawdots=getEdgesRawDots01(vtl,me)
	smoothdots=getEdgesSmoothDots01(rawdots,sharp)

	dots=smoothdots[0]
	dotmin=smoothdots[1]
	dotmax=smoothdots[2]
	
	# resolution equation premier
	# degre : trouver la fonction
	# qui relie les indices (dots)
	# et la palette
	# y=ax+b
	# ymax=Palsize-1
	# ymin=0
	# xmax=dotmax
	# xmin=dotmin
	# a=(ymax-ymin)/(xmax-xmin)
	# b= ymin-xmin*a
	# y => l'index dans la palette
	# x => l'index du vertex
	
	
	a=(palSize-1)/(dotmax-dotmin)
	b=-dotmin*a
	#mix=1.0
	for face in me.faces:
		j=0
		for v in face.v:
			if v.sel==1:
				x=dots[v.index]
				icol=int(a*x+b)
				colPal=palette[icol]
				col=face.col[j]
				setMixMeshCols(col,colPal,mix)
				j+=1

	me.update()



def paintMesh04b(object,palData,mix,sharp):
	# colorisation selon saillance des arretes
	# rm : lent et pas encore au point
	print "paintMesh 04b -811"
	me=Mesh.Get(object.data.name)
	palette=palData[0]
	palSize=len(palette)
	
	# mise en relation edges/faces
	#
	
	edFaces=range(len(me.edges))
	edCols=range(len(me.edges))
	for f in me .faces:
		if len(f.v)==3:
			fed=[(f.v[0].index,f.v[1].index),(f.v[1].index,f.v[2].index),(f.v[2].index,f.v[0].index)]
			fdi=[(0,1),(1,2),(2,0)]
		else:
			fed=[(f.v[0].index,f.v[1].index),(f.v[1].index,f.v[2].index),(f.v[2].index,f.v[3].index),(f.v[3].index,f.v[0].index)]
			fdi=[(0,1),(1,2),(2,3),(3,0)]
	
		for ed in fed:
			ie=me.findEdges(ed[0],ed[1])
			
			idCols=fdi[fed.index(ed)]
			
			#print idCols
			
			if type(ie) == type(1):
				
				if type(edFaces[ie]) == type([]):
					edFaces[ie].append(f)
					edCols[ie].append(f.col[idCols[0]])
					edCols[ie].append(f.col[idCols[1]])
					
	
				else:
					edFaces[ie]=[f]
					edCols[ie]=[f.col[idCols[0]]]
					edCols[ie].append(f.col[idCols[1]])
				
	
	# creation des indices (produit vectoriel faces adjacentes)
	dots=[]
	for edf in edFaces:	
		if len(edf) == 2:
			dot=Mathutils.DotVecs(edf[0].no,edf[1].no)+1.0
		else:
			dot = 1.0	
		dots.append(dot)
	#dots.reverse()
	# contraste des indices
	smoothdots=getEdgesSmoothDots01(dots,sharp*8)
	
	# choix couleur + application
	dv=(palSize-1)/smoothdots[2]
	edi=0
	for edf in edFaces:
		
		dot=smoothdots[0][edi]
		cols=edCols[edi]
		icol=int(dv*dot)
		colPal=palette[icol]
		
		for f in edf:
			if f.sel:
				for col in f.col:
					setMixMeshCols(col,colPal,mix)
					
		"""
		for col in cols:
			setMixMeshCols(col,colPal,mix)
		"""
		edi+=1
		
	me.update()


##############################################################
	
	
def paintMesh05(object,mix):
	# colorisation du mesh selon couleur en selection
	#print r1,g1,b1		
	me=Mesh.Get(object.data.name)
	colPal=range(3)
	colPal[0]=r1
	colPal[1]=g1
	colPal[2]=b1
	for face in me.faces:
		for colMesh in face.col:
			setMixMeshCols(colMesh,colPal,mix)
	me.update()

##############################################################
	
def paintMesh06(object,mix):
	# colorisation frontieres des mats
	# selon couleur active de la palette
	
	me=Mesh.Get(object.data.name)
	mats=object.getMaterials()
	colPal=(r1,g1,b1)
	
	verts=range(len(me.verts))
	
	for f in me.faces:
		mat=f.mat
		i=0
		for v in f.v:
			col=f.col[i]
			if type(verts[v.index]) == type(1):
				verts[v.index]=[[mat],[col]]
			else:
				if mat in verts[v.index][0]:
					verts[v.index][1].append(col)

				else:
					verts[v.index][0].append(mat)
					verts[v.index][1].append(col)
			i+=1
	

	for MatMesh in verts:
		cols=MatMesh[1]
		if len(MatMesh[0]) > 1:
			for colMesh in cols:
				setMixMeshCols(colMesh,colPal,mix)
				

	me.update()

##############################################################
# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# l'interface graphique du script

def Gui():
	global loc,xmax,xsize,ysize,r1,g1,b1
	global viewApply,menu_mat,mat_list,mixSlide1,mixToggle,sel_mat,mixApply,menu_pals
	global palKeys,sharpSlide

	glClearColor(0.5,0.5,0.5, 0.0)
	glClear(GL_COLOR_BUFFER_BIT)

	palData=Registry.GetKey("palettes")["current"]
	palette=palData[0]
	palette_path=palData[1]
	palette_name=palData[2]
	palette_file=palData[1]+palData[2]

	lenPal=len(palette)
	if lenPal < 32 :
		lenPal=32
	
	ypos=(lenPal/xmax)*(ysize+1)
	xpos=0
	
	
	
	
	# affichage de la pallette
	#
	codepal_gl=make_codepal_gl(palette,xmax,xsize,ysize)
	for ln in codepal_gl:
		eval(ln)
		
	
	
	# Import / export des palettes
	#
	
	ypal=ypos+15
	make_square(xpos+5,ypal-10,240,95,1,0.4,0.4,0.4)
	glColor3f(1.0,1.0,1.0)
	glRasterPos2i(xpos+10, ypal+70)
	Text("> From Gimp/Blend/Mesh - export pal")	
	PushButton("1.gimp", 3, xpos+10, ypal+45, 50, 19,"import gimp palette")
	PushButton("2.file", 4, xpos+60, ypal+45, 50, 19,"Create a new palette with materials colors available in the scene")
	PushButton("3.mesh", 8, xpos+110, ypal+45, 50, 19,"Create a new palette with meshes colors")
	PushButton("export 2&3", 5, xpos+165, ypal+45, 75, 19, "Save Blend/Mesh palette into a gimp palette file (in your filename dir)")
	palFile= String("file:", 2, xpos+10, ypal+23, 150, 19, palette_file+"  ", 100,"path+name of the current palette")
	mixSlide1= Slider("mix : ", 52, xpos+10, ypal, 150, 19, mixSlide1.val, 0.0, 1.0,0)
	
	
	
	
	palKeys=Registry.GetKey("palettes").keys()
	for key in palKeys:
		if key=="current":
			palKeys.remove(key)
	
	
	palKeys_options=make_menu_options(palKeys)
		
	menu_pals= Menu(palKeys_options, 12, xpos+165, ypal+23, 75, 18, menu_pals.val,"List of loaded palettes")
	PushButton("inverse cols", 19, xpos+165, ypal, 75, 19)
	
	
	
	
	# menu de selection dans la palette et
	# menu de selection des materiaux
	#
	yobj=ypos+34

	make_square(xpos+5,yobj+70,240,75,1,0.4,0.4,0.4)
	glColor3f(1.0,1.0,1.0)
	glRasterPos2i(xpos+60, yobj+80)
	Text("pal col")
	make_square255(xpos+10,yobj+75,40,18,1,r1,g1,b1)
	PushButton("Assign", 6, xpos+115, yobj+75, 45, 18,"Assign color to selected mats")
	PushButton("update mats", 7, xpos+165, yobj+75, 75, 18,"Update the list of materials for the selected obj")
	if loc < len(palette):
		r1=float(palette[loc][0])
		g1=float(palette[loc][1])
		b1=float(palette[loc][2])
	else:
		r1=float(palette[0][0])
		g1=float(palette[0][1])
		b1=float(palette[0][2])

	glColor3f(1.0,1.0,1.0)
	glRasterPos2i(xpos+10, yobj+125)
	Text("> Apply to Object mats (RMB+assign) ")

	try:
		sel_mat=Blender.Material.Get(mat_list[menu_mat.val-1])
		make_square(xpos+10,yobj+100,40,18,1,sel_mat.R,sel_mat.G,sel_mat.B)
		glColor3f(1.0,1.0,1.0)
		glRasterPos2i(xpos+60, yobj+105)
		Text("mat col")
		options_mats=make_menu_options(mat_list)
		menu_mat=Menu(options_mats, 2, xpos+115, yobj+100, 125, 18, menu_mat.val,"List of Mesh's materials")
	except:
		glColor3f(1.0,1.0,1.0)
		glRasterPos2i(xpos+5, yobj+100)
		Text("  Select an object or create a material")
	
	
		
	
		
	# interface pour appliquer la palette au maillage
	# 
	ymesh=ypos+44
	glColor3f(0.8,0.9,1.0)
	glRasterPos2i(xpos+10, ymesh+295)
	Text("  Transpal Express / Palette Translator")
	glColor3f(0.8,0.8,0.8)
	glRasterPos2i(xpos+10, ymesh+280)
	Text("  raf 03.2005 raphael@graphtime.com")
	
	make_square(xpos+5,ymesh+140,240,130,1,0.4,0.4,0.4)
	glColor3f(1.0,1.0,1.0)
	glRasterPos2i(xpos+10, ymesh+250)
	Text("> Apply palette colors to Mesh Cols")

	
	glRasterPos2i(xpos+10, ymesh+153)
	Text(" Compare normals to")
	viewOptions=make_menu_options(["x axis","y axis","z axis","view axis","cursor-ObCenter"])
	viewApply= Menu(viewOptions, 2, xpos+130, ymesh+150, 65, 18, viewApply.val)
	Button("go", 20, xpos+200, ymesh+150, 40, 19)
	

	Button("sphere cursor map", 21, xpos+10, ymesh+200, 115, 19)
	Button("use UV map", 22, xpos+130, ymesh+200, 110, 19)

	Button("PalCol2meshCols", 25, xpos+10, ymesh+175, 115, 19)
	Button("surfaces borders", 26, xpos+130, ymesh+175, 110, 19)

	Button("VTX", 23, xpos+175, ymesh+225, 30, 19)
	Button("EDG", 24, xpos+210, ymesh+225, 30, 19)
	sharpSlide= Slider("contrast ", 30, xpos+10, ymesh+225, 160, 19, sharpSlide.val, 0.0, 2.0,0)
	

	
# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# gestion des evenements	
	
def event(evt, val):
	global mousepos,loc
	
		
	if (evt== ESCKEY and not val): Exit()
	elif (evt== RIGHTMOUSE):
		mousepos=getRealativeMousePos()
		loc=get_color(mousepos)
		
		Draw()
	
	if (evt== QKEY and not val): Exit()

	if (evt== LKEY and not val):
	
			
		objects=Blender.Object.GetSelected()
		object=objects[0]
		me=Mesh.Get(object.data.name)
		me.vertexShade(object)
		me.update()
		#print "Light Cols"

		
		
def bevent(evt):
	Window.WaitCursor(1)
	try:
		objects=Blender.Object.GetSelected()
		
	
	except:
		"select an object"

	palData=Registry.GetKey("palettes")["current"]
		
		
	if   (evt == 1): Exit()
	elif (evt == 2):Draw()
	elif (evt == 3):
		Window.FileSelector(loadPal,"loadFile")
		Blender.Redraw()
		
	elif (evt== 4):
		palData=getBlendPal()
		palettes=Registry.GetKey("palettes")
		palettes["current"]=palData
		if palData[2] not in palettes.keys():
			palettes[palData[2]]=palData	
		Registry.SetKey("palettes",palettes)
		Blender.Redraw()

		
	elif (evt== 5):
		palData=Registry.GetKey("palettes")["current"]
		exportCurrentPal(palData)
		Blender.Redraw()

	elif (evt==7):
		global mat_list
		mat_list=get_mats()
		if len(mat_list) > 0:
			if menu_mat.val==0:
				menu_mat.val=1
		Blender.Redraw()

			
	elif (evt== 8):
		palData=getPalFromMesh(objects[0])
		palettes=Registry.GetKey("palettes")
		palettes["current"]=palData
		palettes[palData[2]]=palData	
		Registry.SetKey("palettes",palettes)
		Blender.Redraw()
			

	elif (evt== 6):
		try:
			sel_mat.R=float(r1/255)
			sel_mat.G=float(g1/255)
			sel_mat.B=float(b1/255)
			
			#sel_mat.setMirCol([sel_mat.R,sel_mat.G,sel_mat.B])
			
		except:
			#print "Select a material / selectionnez un materiau"
			Blender.Draw.PupMenu(" !! Select a material / selectionnez un materiau !!")
		Blender.Redraw()

	elif (evt== 12):
		getMenuPal(palKeys[menu_pals.val-1])
		Blender.Redraw()
	
	elif (evt==19):
		inversePal()
		Blender.Redraw()

	elif (evt== 20):
		EffectVector=getEffectVector(viewApply.val-1)
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh01(object,palData,mixSlide1.val,EffectVector)
		
	elif (evt== 21):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh02(object,palData,mixSlide1.val)
		
	elif (evt== 22):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh03(object,palData,mixSlide1.val)
	
	elif (evt== 23):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh04(object,palData,mixSlide1.val,sharpSlide.val)
				
	elif (evt== 24):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh04b(object,palData,mixSlide1.val,sharpSlide.val)

	elif (evt== 25):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh05(object,mixSlide1.val)


	elif (evt== 26):
		for object in objects:
			if object.getType() == "Mesh":
				testMeshVColUV(object)
				paintMesh06(object,mixSlide1.val)

	Window.WaitCursor(0)

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# variables du script
#
	
# Ces valeurs servent pour laffichage de la palette
xmax=16
xsize=15
ysize=10


# menu listant les materiaux de l'objet selectionne
menu_mat = Create(0)
viewApply = Create(1)
mixSlide1 = Create(0.5)
mixApply=Create(1)
sharpSlide=Create(0.5)


mat_list=get_mats()
palette_path=Create("Default")
try:
	palKeys=getPalKeys()
	curName=Registry.GetKey("palettes")["current"][2]
	curId=palKeys.index(curName)
	menu_pals= Create(curId)
	
except:
	menu_pals= Create(0)

# couleur choisie par defaut 
r1= 127.0
g1= 127.0
b1= 127.0
loc=0
mousepos=[0,0]

# -- # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#execution

if Registry.GetKey("palettes"):
	palData=Registry.GetKey("palettes")["current"]
	
	if len(palData[0])==0:
		MakeDefaultPal()
else:
	MakeDefaultPal()
	
Register(Gui, event, bevent)