[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [14175] trunk/blender/release/scripts/ flt_toolbar.py: -> Color Fixing tool in FLT toolbar

Geoffrey Bantle hairbat at yahoo.com
Wed Mar 19 22:14:49 CET 2008


Revision: 14175
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14175
Author:   briggs
Date:     2008-03-19 22:14:49 +0100 (Wed, 19 Mar 2008)

Log Message:
-----------
-> Color Fixing tool in FLT toolbar

A new tool for for fixing colors on meshes imported from other files with
conflicting color palettes has been added to the FLT toolbar script. This
will find the closest match for all the colors in the faces of selected
meshes and update their baked vertex color representation.

Also added a small tweak to the 'update all' tool which will fix black faces

Modified Paths:
--------------
    trunk/blender/release/scripts/flt_toolbar.py

Modified: trunk/blender/release/scripts/flt_toolbar.py
===================================================================
--- trunk/blender/release/scripts/flt_toolbar.py	2008-03-19 19:23:42 UTC (rev 14174)
+++ trunk/blender/release/scripts/flt_toolbar.py	2008-03-19 21:14:49 UTC (rev 14175)
@@ -76,7 +76,8 @@
 	"IDPROP_COPY" : 501,
 	"IDPROP_KILL" : 502,
 	"CLIGHT_MAKE" : 700,
-	"DFROMACT" : 701
+	"DFROMACT" : 701,
+	"FIXCOL" : 702
 }
 
 XREF_PREFIX = None
@@ -92,7 +93,45 @@
 SCENE_UPDATE = None
 CLIGHT_MAKE = None
 DFROMACT = None
+FIXCOL = None
 
+
+def RGBtoHSV( r, g, b):
+	cmin = min( r, g, b )
+	cmax = max( r, g, b )
+	v = cmax				
+
+	if(cmax!=0.0):
+		s = (cmax-cmin)/cmax
+	else:
+		s = 0.0
+		h = 0.0
+	
+	if(s == 0.0):
+		h = -1.0
+	else:
+		cdelta = cmax-cmin
+		rc = (cmax-r)/cdelta
+		gc = (cmax-g)/cdelta
+		bc = (cmax-b)/cdelta
+		if(r==cmax):
+			h = bc-gc
+		else:
+			if(g==cmax):
+				h = 2.0+rc-bc
+			else:
+				h = 4.0+gc-rc
+		h = h*60.0
+		if(h<0.0):
+			h += 360.0
+			
+		
+	h = h/360.0
+	if(h < 0.0): 
+		h = 0.0
+	return (h,s,v)
+
+
 def update_state():
 	state = dict()
 	state["activeScene"] = Blender.Scene.getCurrent()
@@ -141,25 +180,131 @@
 				for key in source.properties['FLT']:
 					object.properties['FLT'][key] = source.properties['FLT'][key]
 
-def update_all():
+def unpack_color(color):
+	return struct.unpack('>BBBB',struct.pack('>I',color))
+
+
+def findColorKey(colordict, hsv):
+	hdelta = 0.001
+	for key in colordict:
+		if not (((hsv[0] < (key[0] + hdelta)) and (hsv[0] > (key[0] - hdelta))) and ((hsv[1] < (key[1] + hdelta)) and (hsv[1] > (key[1] - hdelta)))):
+			return key
+	return None
+
+def hsvsort(a, b):
+	(index1, mag1) = a
+	(index2, mag2) = b
+	if mag1 > mag2:
+		return 1
+	elif mag1 < mag2:
+		return -1
+	return 0
+
+def fix_colors():
+	
+	editmode = 0
+	if Blender.Window.EditMode():
+		Blender.Window.EditMode(0)
+		editmode = 1
 	state = update_state()
-	#update the baked FLT colors for all meshes.
-	for object in state["activeScene"].objects:
-		if object.type == "Mesh":
+	
+	scene = state["activeScene"]
+	colors = None
+	if state["activeScene"].properties.has_key('FLT'):
+		try:
+			colors = state["activeScene"].properties['FLT']['Color Palette']
+		except:
+			pass
+	if not colors:
+		return
+	
+	#first build a HSV version of our palette
+	hsvpalette = list()
+	for swatch in colors:
+		color = unpack_color(swatch)
+		hsv = RGBtoHSV(color[0] / 255.0, color[1] / 255.0, color[2] / 255.0)
+		hsvpalette.append(hsv)
+		
+	#collect all of our meshes
+	meshes = list()
+	for object in scene.objects.context:
+		if object.sel and object.type == 'Mesh':
 			mesh = object.getData(mesh=True)
-			if 'FLT_COL' in mesh.faces.properties:
-				mesh.activeColorLayer = "FLT_Fcol"
-				for face in mesh.faces:
-					(index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
-					color = struct.unpack('>BBBB',struct.pack('>I',state["colors"][index]))
-					#update the vertex colors for this face
-					for col in face.col:
-						col.r = int(color[0] * intensity)
-						col.g = int(color[1] * intensity)
-						col.b = int(color[2] * intensity)
-						col.a = 255
+			if "FLT_COL" in mesh.faces.properties:
+				meshes.append(mesh)
+				
+				
+	#Now go through our meshes, and build a dictionary of face lists keyed according to (hue,saturation) of the baked color
+	colordict = dict()
+	for mesh in meshes:
+		for face in mesh.faces:
+			hsv = RGBtoHSV(face.col[0].r/255.0, face.col[0].g/255.0, face.col[0].b/255.0) #retrieve baked color
+			if colordict.has_key((hsv[0],hsv[1])):
+				colordict[(hsv[0],hsv[1])].append(face)
+			else:
+				colordict[(hsv[0],hsv[1])] = [face]				
+	
 
+	#for each color key in the color dict, build a list of distances from it to the values in hsvpalette and then quicksort them for closest match
+	for key in colordict:
+		maglist = list()
+		for i, hsv in enumerate(hsvpalette):
+			norm = Blender.Mathutils.Vector(hsv[0], hsv[1]) - Blender.Mathutils.Vector(key[0],key[1])
+			maglist.append((i,norm.length))
+		maglist.sort(hsvsort)
+		print maglist[0]
+		for face in colordict[key]:
+			(index, intensity) = unpack_face_index(face.getProperty("FLT_COL"))
+			newfindex = pack_face_index(maglist[0][0],intensity)
+			face.setProperty("FLT_COL", int(newfindex))
+	
+	for mesh in meshes:
+		update_mesh_colors(colors,mesh)	
+	
+	if editmode:
+		Blender.Window.EditMode(1)	
+	
 
+def update_mesh_colors(colors, mesh):
+	if 'FLT_COL' in mesh.faces.properties:
+		mesh.activeColorLayer = "FLT_Fcol"
+		for face in mesh.faces:
+			(index,intensity) = unpack_face_index(face.getProperty('FLT_COL'))
+			color = struct.unpack('>BBBB',struct.pack('>I',colors[index]))
+			
+			if index == 0 and intensity == 0:
+				color = (255,255,255)
+				intensity  = 1.0
+			#update the vertex colors for this face
+			for col in face.col:
+				col.r = int(color[0] * intensity)
+				col.g = int(color[1] * intensity)
+				col.b = int(color[2] * intensity)
+				col.a = 255
+	
+		
+def update_all():
+	
+	editmode = 0
+	if Blender.Window.EditMode():
+		Blender.Window.EditMode(0)
+		editmode = 1
+	state = update_state()
+	
+	if state["activeScene"].properties.has_key('FLT'):
+		try:
+			colors = state["activeScene"].properties['FLT']['Color Palette']
+		except:
+			colors = None
+	if colors:
+		#update the baked FLT colors for all meshes.
+		for object in state["activeScene"].objects:
+			if object.type == "Mesh":
+				mesh = object.getData(mesh=True)
+				update_mesh_colors(colors,mesh)
+	if editmode:
+		Blender.Window.EditMode(1)
+
 #Change this to find the deep parent
 def xref_create():
 	global xrefprefix
@@ -528,6 +673,8 @@
 		clight_make()
 	if evt == evcode["DFROMACT"]:
 		dfromact()
+	if evt == evcode["FIXCOL"]:
+		fix_colors()
 	Draw.Redraw(1)
 	Blender.Window.RedrawAll()
 
@@ -582,17 +729,20 @@
 
 
 def draw_propsheet(x,y):
-        global XREF_PREFIX
-        global XREF_MAKE
-        global XREF_EDIT
-        global XREF_SELECT
-        global XREF_POP
-        global FACE_MAKESUB
-        global FACE_SELSUB
-        global FACE_KILLSUB
-        global IDPROP_KILL
-        global IDPROP_COPY
-        global SCENE_UPDATE
+	global XREF_PREFIX
+	global XREF_MAKE
+	global XREF_EDIT
+	global XREF_SELECT
+	global XREF_POP
+	global FACE_MAKESUB
+	global FACE_SELSUB
+	global FACE_KILLSUB
+	global IDPROP_KILL
+	global IDPROP_COPY
+	global SCENE_UPDATE
+	global DFROMACT
+	global FIXCOL
+		
 	global CLIGHT_MAKE
 	global xrefprefix
 	global xrefstack
@@ -643,11 +793,13 @@
 	
 	y=y-20
 	DFROMACT = Blender.Draw.PushButton("Dof from Active", evcode["DFROMACT"],x,y,width,20,"Get Dof origin from active object")
-        draw_postcommon(origx, origy,y)
+	y=y-20
+	FIXCOL = Blender.Draw.PushButton("Fix Colors", evcode["FIXCOL"],x,y,width,20,"Fix baked FLT colors of selected meshes") 	
+	draw_postcommon(origx, origy,y)
 		
 def gui():
 	#draw the propsheet/toolbox.
-	psheety = 280
+	psheety = 300
 	#psheetx = psheety + 10
 	draw_propsheet(0,psheety)
 Draw.Register(gui,event,but_event)





More information about the Bf-blender-cvs mailing list