#!BPY

""" 
Name: 'Random Color'
Blender: 248
Group: 'Materials'
Tooltip: 'Randomly changing colors of multiple objects (Mesh, Lamp)'
"""

__author__ = ["RedSharky"]
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Materials/Random_Color")
__version__ = "0.4"
__bpydoc__ = """Tool to randomly vary color of many selected objects. 
Fully functional with mesh and lamp objects, also simultaneously. (7th May 2007)"""



# ***** BEGIN GPL LICENSE BLOCK *****
#
# Script copyright (C) Bob Holcomb 
#
# 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 *****



#-- here we go -------------------------------------------------------------------------

import Blender
from Blender import Draw, Material, Object, Registry, Window
import random #import a special Python module, full Python installation recommended!

print #just an empty line, enhances readability of script output
print "--- Random Color v0.4, by RedSharky (2007) ------------------------------------"





#-- registry handling ------------------------------------------------------------------

# this function updates the registry when we need to:
def update_Registry(R,G,B):
	d = {}
	d['R'] = R
	d['G'] = G
	d['B'] = B
	# cache = True: data is also saved to a file
	Blender.Registry.SetKey('Random_Color', d, False)


#-- check if they are already there (saved on a previous execution of this script)
def read_Registry():
	try:
		rdict = Registry.GetKey('Random_Color', False) # True to check on disk also
		#print "rdict:", rdict
		
		if rdict:
			R = rdict['R']
			G = rdict['G']
			B = rdict['B']
			return R, G, B
		else:
			return None, None, None
	except:
		return None, None, None
	


#--- Pop up menu -----------------------------------------------------------------------

#create the main pop up
def mainMenu(R,G,B):
	text = Blender.Draw.Create("short text")
	f = Blender.Draw.Create(1.0)
	i = Blender.Draw.Create(2)
	tog = Blender.Draw.Create(0)

	r_min = Blender.Draw.Create(R[0])
	r_max = Blender.Draw.Create(R[1])
	g_min = Blender.Draw.Create(G[0])
	g_max = Blender.Draw.Create(G[1])
	b_min = Blender.Draw.Create(B[0])
	b_max = Blender.Draw.Create(B[1])
	
	
	block = []
	
	block.append("Set color range (min/max):")
	block.append("R")
	block.append(("", r_min, 0.0, 1.0, "min"))
	block.append("G")
	block.append(("", g_min, 0.0, 1.0, "min"))
	block.append("B")
	block.append(("", b_min, 0.0, 1.0, "min"))
	block.append("")
	block.append("")
		
	block.append("")
	block.append(("", r_max, 0.0, 1.0, "max"))
	block.append("")
	block.append(("", g_max, 0.0, 1.0, "max"))
	block.append("")
	block.append(("", b_max, 0.0, 1.0, "max"))
	block.append("")
	
	retval = Blender.Draw.PupBlock("Random Color v0.4, by RedSharky (2007)", block)
		       
	if retval:
		# assign values(!) 
		R = (r_min.val, r_max.val)
		G = (g_min.val, g_max.val)
		B = (b_min.val, b_max.val)
	
		update_Registry(R, G, B)
		rndcol(R,G,B)
	else:
		print "No user input. Script aborted."


#-- main color changing function -------------------------------------------------------
def rndcol(R,G,B):
	# get objects
	ob = Blender.Object.GetSelected()


	# pick objeckts by type and pack them in specific lists
	lamp_ob_list = []
	mesh_ob_list = []


	for i in range(len(ob)):
		if ob[i].getType() == 'Lamp': 
			lamp_ob_list.append(Blender.Object.Get(ob[i].getName()))
			
		elif ob[i].getType() == 'Mesh':
			mesh_ob_list.append(Blender.Object.Get(ob[i].getName()))
	

	# sort lists
	lamp_ob_list.sort()
	mesh_ob_list.sort()


	#print "Modifiable object(s):", len(lamp_ob_list)+len(mesh_ob_list)
	print "Processing", (len(lamp_ob_list)+len(mesh_ob_list)), "of", len(ob), "selected objects:"
	print "%3s %-12s %1s %5s %5s" % ("#", "Name", "R", "G", "B")
	
	
	if len(lamp_ob_list) != 0:
		# modifiy lamp object colors
		print 
	
	
		for i in range(len(lamp_ob_list)):
			lamp_ob_list[i].getData().R = random.uniform(R[0],R[1])
			lamp_ob_list[i].getData().G = random.uniform(G[0],G[1])
			lamp_ob_list[i].getData().B = random.uniform(B[0],B[1])
			
			print "%3i %-12s %.3f %.3f %.3f" % (i+1, lamp_ob_list[i].getName(), \
				lamp_ob_list[i].getData().R, \
				lamp_ob_list[i].getData().G, \
				lamp_ob_list[i].getData().B)



	if len(mesh_ob_list) != 0:
		# modify mesh object colors
		print
		
	
		for i in range(len(mesh_ob_list)):
			
			new_mat = False
			
			ob_work_data = mesh_ob_list[i].getData()
			
			try: # modifies color if a material is already present
				ob_work_data.materials[0].R = random.uniform(R[0],R[1])
				ob_work_data.materials[0].G = random.uniform(G[0],G[1])
				ob_work_data.materials[0].B = random.uniform(B[0],B[1])
			except: # if not make a new material and alter color
				new_mat = True
				
				newmat = Material.New()	
				ob_work_data.materials.append(newmat)
			
				
				ob_work_data.materials[0].R = random.uniform(R[0],R[1])
				ob_work_data.materials[0].G = random.uniform(G[0],G[1])
				ob_work_data.materials[0].B = random.uniform(B[0],B[1])
				
				ob_work_data.update() #updates mesh
			
			# give some feedback about the material changes made
			if new_mat == True:
						print "%3i %-12s %.3f %.3f %.3f" % (i+1, mesh_ob_list[i].getName(), \
					mesh_ob_list[i].getData().materials[0].R, \
					mesh_ob_list[i].getData().materials[0].G, \
					mesh_ob_list[i].getData().materials[0].B), ' new material!'
			else:	
				print "%3i %-12s %.3f %.3f %.3f" % (i+1, mesh_ob_list[i].getName(), \
					mesh_ob_list[i].getData().materials[0].R, \
					mesh_ob_list[i].getData().materials[0].G, \
					mesh_ob_list[i].getData().materials[0].B)
	


#-- main -------------------------------------------------------------------------------

# try to read values from registry
R, G, B = read_Registry()

if R==None or G==None or B==None:
	# set color range (min, max)
	R = (0.0, 1.0)
	G = (0.0, 1.0)
	B = (0.0, 1.0)
	
	update_Registry(R,G,B)
	print "Registry updated"


mainMenu(R,G,B)
	
Window.RedrawAll() # make sure changes get visible, e. g. in buttons window

print "------------------------------------------------------------ End of script. ---"
print