#!BPY
"""
Name: 'Big Numbers Toolkit'
Blender: 2.48
Group: 'Object'
Tooltip: 'A tool designed to move, scale, randomize, etc  big numbers of objects.'
"""
__author__ = "Gwenael Le Page"
__version__ = "1.12"
__url__ = "http://wiki.blender.org/index.php/Extensions:Py/Scripts/Toolkits/Object/Big_Numbers_Toolkit", "http://www.blenderartists.org/forum/showthread.php?t108892"
#For questions and/or feature requests, contact Gwenouille at BlenderArtists.org
__email__ = "gwenael.le-page@orange.fr"
__doc__= """\
This script is here to facilitate the manipulation of big numbers of objects.
You can use it to move, scale, rotate, mimic other objects, set materials, ipos, get statistical data, etc.
For more information visit http://www.blenderartists.org/forum/showthread.php?t108892"""



# -------------------------------------------------------------------------- 
# ***** BEGIN GPL LICENSE BLOCK ***** 
# 
# 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 ***** 
# -------------------------------------------------------------------------- 


#For questions and/or feature requests, contact Gwenouille at BlenderArtists.org


import Blender
import math
from Blender.Draw import *
from Blender.BGL import *
from random import *
from Blender.Object import *
from Blender.Mesh import *
from Blender import Window,Scene,Material
from Blender import Metaball
from Blender import Ipo,IpoCurve
from Blender import Mathutils
from Blender import BezTriple
from math import *
scn=Scene.GetCurrent()

NumberLocX=Create(0.)
NumberLocY=Create(0.)
NumberLocZ=Create(0.)
RangeNumberLoc=Create(1.)
MeanNumberLoc=Create(0.)
ReplLoc=Create(1)
MulLoc=Create(0)
AddLoc=Create(0)
CursorRange=Create(0)
IntMimicLoc=Create(0)

NumberRotX=Create(0.)
NumberRotY=Create(0.)
NumberRotZ=Create(0.)
RangeNumberRot=Create(45.)
MeanNumberRot=Create(0.)
ReplRot=Create(1)
MulRot=Create(0)
AddRot=Create(0)
LocalRot=Create(0)
IntMimicRot=Create(0)

NumberSizeX=Create(1.)
NumberSizeY=Create(1.)
NumberSizeZ=Create(1.)
RangeNumberSize=Create(1.)
MeanNumberSize=Create(1.)
ReplSize=Create(1)
MulSize=Create(0)
AddSize=Create(0)
global FactorLoc,FactorRot,FactorSize
FactorLoc,FactorRot,FactorSize=0,0,0
IntMimicSize=Create(0)

RepTypeMenu=Create(0)
FallOff=Create(0)
ElementChoice=Create(0)

colTog=Create(1)
specTog=Create(0)
hardTog=Create(0)
refTog=Create(0)
speColTog=Create(0)
emitTog=Create(0)
alpTog=Create(0)
mirTog=Create(0)
traTog=Create(0)
mirColTog=Create(0)
MatFactor=Create(15)

selectDistance=Create(0.)
selectBy=Create(0)

ToX=Create(0)
ToY=Create(1)
ToZ=Create(0)
TominX=Create(0)
TominY=Create(0)
TominZ=Create(0)
UpX=Create(0)
UpY=Create(0)
UpZ=Create(1)
Unique=Create(0)
Modulo=Create(1)

functionInput=Create('x')#('sin(4*pi*x)/(4*pi*x)')

MagnetPower=Create(50.0)
MagnetFallOff=Create(0)

Task=Create(2)
ShuffleX=Create(1)
ShuffleY=ShuffleZ=Create(0)
ShuffleLoc=Create(1)
ShuffleRot=ShuffleSize=Create(0)
ShuffleStart=IndShuffle=Create(0)
ShuffleEnd=Create(50)
ShuffleRange=Create(5.0)
Delta=Create(0)
FromWhat=Create(0)
ToWhich=Create(0)
FrameStart=Create(1)
FrameEnd=Create(200)
Period=Create(1.)
Span=Create(50)
Factor=Create(1.)
ExtType=Create(0)
InterType=Create(1)
MapTo01=Create(1)
ObjectIPO=Create('')
BrownPer=Create(25.)
BrownReg=Create(.5)
BrownStr=Create(.8)
BrLocX=BrLocY=Create(1)
BrLocZ=BrRotX=BrRotY=BrRotZ=BrSizeX=BrSizeY=BrSizeZ=Create(0)
BrProp=Create(0)
BrownDelta=Create(1)

page=Create(1)

global RepStats,Stats,numSelObj,ChoiceOfStats
RepStats,Stats,numSelObj,ChoiceOfStats=[0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0],0,0

global i
i=0

global degtopi,pito180
degtopi,pito180=math.pi/180,180/math.pi

global RotMagnetTo,RotMagnetUp
RotMagnetTo,RotMagnetUp='y','z'

if Window.EditMode(): Window.EditMode(0)

def deselect():
	selObj=Blender.Object.GetSelected()
	for i in range(len(selObj)):
		SelObj[i].select(0)
	Window.RedrawAll()

def testNumSelObj(numSelObj):
	selObj=Blender.Object.GetSelected()
	if len(selObj)<numSelObj:
		PupMenu("Not enough objects selected.")
		return False
	else:
		return True
		
def listIntersect(a,b):
	commonContent=[]
	for x in a:
		if x in b:
			commonContent.append(x)
	return(commonContent)

##################################################################################################	 
#	 Objects manipulations
##################################################################################################
def function(x):
	exec('result=' + functionInput.val)
	return result
	
def PupExtrema():
	global DefaultNumExtrema,ExtremaNeg
	block2=[]
	DefaultNumExtrema=Blender.Draw.Create(4)
	ExtremaNeg=Blender.Draw.Create(0)

	block2.append(("Number:",DefaultNumExtrema,1,50,'Number of extremas between closest and furthest'))
	block2.append(" ")
	block2.append(("Negative at 0",ExtremaNeg,'-1 instead of 1 at 0'))
	numExtremas=PupBlock('Number of extremas',block2)

def LocalRotation(obj,degRot,axis):
	MatRot=Mathutils.RotationMatrix(degRot,4,axis)
	EulRot=(MatRot*obj.matrixLocal).toEuler()
	obj.RotX=EulRot[0]*degtopi
	obj.RotY=EulRot[1]*degtopi
	obj.RotZ=EulRot[2]*degtopi
	Blender.Redraw()
	
def DupliObjAxis(obj,nb,axis,dist,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10):
	scn.objects.selected=[]
	OutputObjectList=[obj]
	n=1
	print 'n',n,'list',list
	print 'obj',obj
	obj.sel=1
	while n<nb:
		Blender.Object.Duplicate(d1,d2,d3,d4,d5,d6,d7,d8,d9,d10)
		obj=scn.objects.active
		exec('obj.%s+=%f' %(axis,dist))
		OutputObjectList.append(obj)
		n+=1
	return OutputObjectList

def DupliObj():
	block=[]
	DefaultNum=Blender.Draw.Create(10)
	mesh=Blender.Draw.Create(1)
	surf=Blender.Draw.Create(0)
	curve=Blender.Draw.Create(0)
	text=Blender.Draw.Create(0)
	metaball=Blender.Draw.Create(0)
	armature=Blender.Draw.Create(0)
	lamp=Blender.Draw.Create(0)
	material=Blender.Draw.Create(0)
	texture=Blender.Draw.Create(0)
	ipo=Blender.Draw.Create(0)

	block.append(("Number:",DefaultNum,1,10000,'Number of duplicates you want to make'))
	block.append(" ")
	block.append("Link or Copy ?")
	block.append(("Mesh",mesh,'Copy mesh data'))
	block.append(("Surface",surf,'Copy surface data'))
	block.append(("Curve",curve,'Copy curves'))
	block.append(("Text",text,'Copy text data'))
	block.append(("Metaball",metaball,'Copy metaball data'))
	block.append(" ")
	block.append(" ")
	block.append(" ")
	block.append(("Armature",armature,'Copy armature data'))
	block.append(("Lamp",lamp,'Copy lamp data'))
	block.append(("Material",material,'Copy mesh data'))
	block.append(("Texture",texture,'Copy texture data'))
	block.append(("IPO",ipo,'Copy IPO data'))

	secondBlock=[]
	txt2="Repartition"
	dupliX=Create(0)
	dupliY=Create(0)
	dupliZ=Create(0)
	dupliDist=Create(1.)
	
	secondBlock.append(('X axis',dupliX,"Copy along X axis"))
	secondBlock.append(('Y axis',dupliY,"Copy along Y axis"))
	secondBlock.append(('Z axis',dupliZ,"Copy along Z axis"))
	secondBlock.append(('Distance:',dupliDist,1,100,"Distance between the objects"))

	if (testNumSelObj(1)):
		numDupl=PupBlock('Number of duplicates',block)
		reparDupl=PupBlock('Repartition of duplicates',secondBlock)
		print dupliX.val,dupliY.val,dupliZ.val,type(dupliDist)
		d=0
		selObj=Blender.Object.GetSelected()
		ListDupl=[]

		for obj in selObj:
			ListDupl.append(obj)
			print 'listDupl',ListDupl


		if dupliX.val+dupliY.val+dupliZ.val==0:
			while d<DefaultNum:
				Blender.Object.Duplicate(mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
				dupl=Blender.Object.GetSelected()
				print d,dupl
				for obj in dupl:
					ListDupl.append(obj)
				d+=1

		elif dupliX.val+dupliY.val+dupliZ.val==1:
			print '1 axis'
			for obj in selObj:
				if dupliX.val==1: newObjList=DupliObjAxis(obj,DefaultNum.val,'LocX',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
				elif dupliY.val==1: newObjList=DupliObjAxis(obj,DefaultNum.val,'LocY',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
				elif dupliZ.val==1: newObjList=DupliObjAxis(obj,DefaultNum.val,'LocZ',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
				for obj in newObjList:
					ListDupl.append(obj)
		

		elif dupliX.val+dupliY.val+dupliZ.val==2:
			print '2 axis'
			for obj in selObj:
				if dupliX.val==1:
					newObjList=DupliObjAxis(obj,DefaultNum.val,'LocX',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
					if dupliY.val==1:
						for obj in newObjList:
							ListDupl.append(obj)
							newObjList2=DupliObjAxis(obj,DefaultNum.val,'LocY',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
							for obj in newObjList2:
								ListDupl.append(obj)
					elif dupliZ.val==1:
						for obj in newObjList:
							ListDupl.append(obj)
							newObjList2=DupliObjAxis(obj,DefaultNum.val,'LocZ',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
							for obj in newObjList2:
								ListDupl.append(obj)
				else:
					newObjList=DupliObjAxis(obj,DefaultNum.val,'LocY',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
					for obj in newObjList:
						ListDupl.append(obj)
						newObjList2=DupliObjAxis(obj,DefaultNum.val,'LocZ',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
						for obj in newObjList2:
							ListDupl.append(obj)


		else:
			print '3 axis'
			for obj in selObj:
				newObjList=DupliObjAxis(obj,DefaultNum.val,'LocX',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
				for obj in newObjList:
					ListDupl.append(obj)
					newObjList2=DupliObjAxis(obj,DefaultNum.val,'LocY',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
					for obj in newObjList2:
						ListDupl.append(obj)
						newObjList3=DupliObjAxis(obj,DefaultNum.val,'LocZ',dupliDist.val,mesh.val,surf.val,curve.val,text.val,metaball.val,armature.val,lamp.val,material.val,texture.val,ipo.val)
						for obj in newObjList3:
							ListDupl.append(obj)


		for obj in ListDupl[1:]:
			obj.sel=1
		ListDupl[0].sel=1
	return

def IntMimic(arg1,arg2):
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		for obj in selObj:
			exec('obj.%s=obj.%s' %(arg1,arg2))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def CopyElement(args):
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		for obj in selObj:
			for arg in args: exec('obj.%s=selObj[0].%s' %(arg,arg))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 2 objects.")
		return

def ResetElement(args,value):
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		for obj in selObj:
			for arg in args:
				exec('obj.%s=%f' %(arg,value))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def NewValRot(args,value,add,fo):
	RotDict={'RotX':'x','RotY':'y','RotZ':'z'}
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		maxDist=getMaxDistCurs(selObj)
		if maxDist==0 and fo!=0:
			PupMenu("Maximum distance is 0: can't compute ratio (division by 0). No fall-off will be applied.")
			fo=0
		if LocalRot.val==0:################### global rotation
			if fo==7:##########damped sine
				PupExtrema()
				nEx=DefaultNumExtrema.val
				negEx=[1,-1][ExtremaNeg.val]
			elif fo==8:########input
				x=2												#A trick to test the viability of the string as a function
				try:
					exec('factor=%s' %(functionInput.val))
				except:
					PupMenu("Please correct the syntax of your input function")
					return
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				if fo==0:############no fall-off
					factor=1
				elif fo==1:##########linear
					factor=1-(objDistCurs/maxDist)
				elif fo==2:########## inverse
					factor=objDistCurs/maxDist
				elif fo==3:##########round
					factor=math.sqrt(1-(objDistCurs/maxDist)**2)
				elif fo==4:##########sharp
					factor=1-math.sqrt(1-(objDistCurs/maxDist-1)**2)
				elif fo==5:##########bell
					factor=(math.cos(math.pi/2*objDistCurs/maxDist))**2
				elif fo==6:##########torus
					factor=math.exp(-((8*(objDistCurs/maxDist)-5)**2)/2)
				elif fo==7:##########damped sine
					factor=negEx*math.sin(nEx*math.pi*objDistCurs/maxDist)/(nEx*math.pi*(objDistCurs/maxDist))
				elif fo==8:##########input
					objDistCurs=distanceCursor(obj)
					x=objDistCurs/maxDist
					exec('factor=%s' %(functionInput.val))
				for arg in args:
					if add in (0,1):
						exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
					elif add==2:
						exec('obj.%s= obj.%s * %f*%f *180/math.pi' %(arg,arg,factor,value))

			Blender.Redraw()
		else:################################## local rotation
			if fo==7:##########damped sine
				PupExtrema()
				nEx=DefaultNumExtrema.val
				negEx=[1,-1][ExtremaNeg.val]
			elif fo==8:########input
				x=2												#A trick to test the viability of the string as a function
				try:
					exec('factor=%s' %(functionInput.val))
				except:
					PupMenu("Please correct the syntax of your input function")
					return
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				if fo==0:############no fall-off
					factor=1
				elif fo==1:##########linear
					factor=1-(objDistCurs/maxDist)
				elif fo==2:########## inverse
					factor=objDistCurs/maxDist
				elif fo==3:##########round
					factor=math.sqrt(1-(objDistCurs/maxDist)**2)
				elif fo==4:##########sharp
					factor=1-math.sqrt(1-(objDistCurs/maxDist-1)**2)
				elif fo==5:##########bell
					factor=(math.cos(math.pi/2*objDistCurs/maxDist))**2
				elif fo==6:##########torus
					factor=math.exp(-((8*(objDistCurs/maxDist)-5)**2)/2)
				elif fo==7:##########damped sine
					factor=negEx*math.sin(nEx*math.pi*objDistCurs/maxDist)/(nEx*math.pi*(objDistCurs/maxDist))
				elif fo==8:##########input
					objDistCurs=distanceCursor(obj)
					x=objDistCurs/maxDist
					exec('factor=%s' %(functionInput.val))
				for arg in args:
					if add==1:
						LocalRotation(obj,factor*value*pito180,RotDict[arg])
					else:
						LocalRotation(obj,-eval('obj.'+arg)*pito180,RotDict[arg])				
						LocalRotation(obj,factor*value*pito180,RotDict[arg])
			Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def NewValLoc(args,value,add,fo):
	print add
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		maxDist=getMaxDistCurs(selObj)
		if maxDist==0 and fo!=0:
			PupMenu("Maximum distance is 0: can't compute ratio (division by 0). No fall-off will be applied.")
			fo=0
		if fo==0:
			for obj in selObj:
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f' %(arg,add,arg,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f' %(arg,arg,value))
		elif fo==1:##########linear
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-(objDistCurs/maxDist)
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==2:########## inverse
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=objDistCurs/maxDist
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==3:##########round
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.sqrt(1-(objDistCurs/maxDist)**2)
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==4:##########sharp
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-math.sqrt(1-(objDistCurs/maxDist-1)**2)
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==5:##########bell
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(math.cos(math.pi/2*objDistCurs/maxDist))**2
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==6:##########torus
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.exp(-((8*(objDistCurs/maxDist)-5)**2)/2)
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
		elif fo==7:##########damped sine
			PupExtrema()
			nEx=DefaultNumExtrema.val
			negEx=[1,-1][ExtremaNeg.val]
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=negEx*math.sin(nEx*math.pi*objDistCurs/maxDist)/(nEx*math.pi*(objDistCurs/maxDist))
				if add in (0,1):
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
				elif add==2:
					for arg in args: exec('obj.%s= obj.%s * %f*%f' %(arg,arg,factor,value))
			print 'Damped sine applied with ',nEx,' extremas chosen'
		elif fo==8:##########Input
			print 'Chosen function: f(x)=',functionInput.val,type(functionInput.val)
			x=2
			try:
				exec('factor=%s' %(functionInput.val))
				for obj in selObj:
					objDistCurs=distanceCursor(obj)
					x=objDistCurs/maxDist
					exec('factor=%s' %(functionInput.val))
					for arg in args: exec('obj.%s= %i*obj.%s + %f*%f' %(arg,add,arg,factor,value))
			except:
				PupMenu("Please correct the syntax of your input function")
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return
	
def NewValSize(args,value,mul,fo):
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		maxDist=getMaxDistCurs(selObj)
		if (maxDist==0 and fo!=0):
			PupMenu("Maximum distance is 0: can't compute ratio (division by 0). No fall-off will be applied.")
			fo=0
		if fo==0:
			for obj in selObj:
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f' %(arg,arg,value))
				elif mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f' %(arg,arg,value))
				else:
					for arg in args: exec('obj.%s=%f' %(arg,value))
		elif fo==1:############linear
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-(objDistCurs/maxDist)				
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				elif mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==2:############inverse linear
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=objDistCurs/maxDist				
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==3:############round
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.sqrt(1-(objDistCurs/maxDist)**2)		
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==4:############sharp
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-math.sqrt(1-(objDistCurs/maxDist-1)**2)			
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==5:############bell
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(math.cos(math.pi/2*objDistCurs/maxDist))**2	 
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==6:############torus
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.exp(-((8*(objDistCurs/maxDist)-5)**2)/2)
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==7:############damped sine
			PupExtrema()
			nEx=DefaultNumExtrema.val
			negEx=[1,-1][ExtremaNeg.val]
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=negEx*math.sin(nEx*math.pi*objDistCurs/maxDist)/(nEx*math.pi*(objDistCurs/maxDist))
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		elif fo==8:############input
			x=2
			try:
				exec('factor=%s' %(functionInput.val))
			except:
				PupMenu("Please correct the syntax of your input function")
				return
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				x=objDistCurs/maxDist
				exec('factor=%s' %(functionInput.val))
				if mul==2:
					for arg in args: exec('obj.%s=obj.%s * %f*%f' %(arg,arg,factor,value))
				if mul==1:
					for arg in args: exec('obj.%s=obj.%s + %f*%f' %(arg,arg,factor,value))
				else:
					for arg in args: exec('obj.%s=%f*%f' %(arg,factor,value))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return
	
def createRandomValue(mu,sigma):
	randomValue=[]
	randomValue.append(sigma*(random()-0.5)+mu)
	randomValue.append(gauss(mu,sigma))
	return randomValue

def OldRandLoc(args,add,m,r):############Random Location
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		for obj in selObj:
			for arg in args: exec('obj.%s=%i*obj.%s + %f' %(arg,add,arg,(createRandomValue(m,r)[RepTypeMenu.val])))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def RandLoc(args,add,m,r,curs):############Random Location
	selObj=Blender.Object.GetSelected()
	listOfVals,numObj=[],[]
	numSelObj=len(selObj)
	if curs==1: #if CursorStretch is active,
		add=0			#then 'add' is overruled to 'repl.'
		CursorPos=Window.GetCursorPos()
		r=[]
		r.append(CursorPos[0]-selObj[0].LocX)
		r.append(CursorPos[1]-selObj[0].LocY)
		r.append(CursorPos[2]-selObj[0].LocZ)						#the 3 ranges between activeObj and cursor
		m=[]
		m.append((CursorPos[0]+selObj[0].LocX)/2)
		m.append((CursorPos[1]+selObj[0].LocY)/2)
		m.append((CursorPos[2]+selObj[0].LocZ)/2)				#the 3 mean values between activeObj and cursor
		if (testNumSelObj(2)):
			if RepTypeMenu.val==0 or RepTypeMenu.val==1:	#for random and gaussian: easy
				for obj in selObj:
					if obj!=selObj[0]:
						if args==('LocX',):
							exec('obj.LocX=%f' %(createRandomValue(m[0],r[0])[RepTypeMenu.val]))
						elif args==('LocY',):
							exec('obj.LocY=%f' %(createRandomValue(m[1],r[1])[RepTypeMenu.val]))
						elif args==('LocZ',):
							exec('obj.LocZ=%f' %(createRandomValue(m[2],r[2])[RepTypeMenu.val]))
						elif args==('LocX','LocY','LocZ'):
							exec('obj.LocX=%f' %(createRandomValue(m[0],r[0])[RepTypeMenu.val]))
							exec('obj.LocY=%f' %(createRandomValue(m[1],r[1])[RepTypeMenu.val]))
							exec('obj.LocZ=%f' %(createRandomValue(m[2],r[2])[RepTypeMenu.val]))

			elif RepTypeMenu.val==2:											#for regular: more difficult
				listOfListOfVals=[[],[],[]]
				for n in range(1,numSelObj):
					numObj.append(n)
					shuffle(numObj)
					listOfListOfVals[0].append(m[0]-r[0]/2+n*r[0]/(numSelObj-1))		#LocXValues in the 1st list
					listOfListOfVals[1].append(m[1]-r[1]/2+n*r[1]/(numSelObj-1))		#LocYValues in the 2nd list			
					listOfListOfVals[2].append(m[2]-r[2]/2+n*r[2]/(numSelObj-1))		#LocZValues in the 2nd list
				numObj.insert(0,0)
				listOfListOfVals[0].insert(0,selObj[0].LocX)
				listOfListOfVals[1].insert(0,selObj[0].LocY)
				listOfListOfVals[2].insert(0,selObj[0].LocZ)
				for n in range(numSelObj):
					n2=numObj[0]													#Select the 1st element of the randomized list
					del(numObj[0])												#and erase it so that now the first is also random. Could use queue couldn't i ?
					if args==('LocX',):
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocX',add,'LocX',listOfListOfVals[0][n]))
					elif args==('LocY',):
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocY',add,'LocY',listOfListOfVals[1][n]))
					elif args==('LocZ',):
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocZ',add,'LocZ',listOfListOfVals[2][n]))
					elif args==('LocX','LocY','LocZ'):
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocX',add,'LocX',listOfListOfVals[0][n]))
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocY',add,'LocY',listOfListOfVals[1][n]))
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %('LocZ',add,'LocZ',listOfListOfVals[2][n]))			
			Blender.Redraw()		
		else:
			PupMenu("Please select at least 2 objects.")
			return
	else:		#in case the CursorStretch isn't active
		if (testNumSelObj(1)):
			if RepTypeMenu.val==0 or RepTypeMenu.val==1:	#for random and gaussian: easy
				for obj in selObj:
					for arg in args:
						exec('obj.%s=%i*obj.%s + %f' %(arg,add,arg,(createRandomValue(m,r)[RepTypeMenu.val])))
			elif RepTypeMenu.val==2:											#for regular: more difficult
				if numSelObj!=1:
					for n in range(numSelObj):
						listOfVals.append(m-r/2+n*r/(numSelObj-1))
						numObj.append(n)
					shuffle(numObj)
					for n in range(numSelObj):
						n2=numObj[0]
						del(numObj[0])
						for arg in args:
							exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %(arg,add,arg,listOfVals[n]))
				else:
					for obj in selObj:
						for arg in args: exec('obj.%s=%i*obj.%s + %f' %(arg,add,arg,m))
			Blender.Redraw()		
		else:
			PupMenu("Please select at least 1 object.")
			return

def RandRot(args,add,m,r):############Random Rotation
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		if RepTypeMenu.val==0 or RepTypeMenu.val==1:
			for obj in selObj:
				for arg in args: exec('obj.%s=%i*obj.%s + %f' %(arg,add,arg,math.pi/180*(createRandomValue(m,r)[RepTypeMenu.val])))
		elif RepTypeMenu.val==2:
			numSelObj=len(selObj)
			if numSelObj!=1:
				listOfVals,numObj=[],[]
				for n in range(numSelObj):
					listOfVals.append(m-r/2+n*r/(numSelObj-1))
					numObj.append(n)
				shuffle(numObj)
				for n in range(numSelObj):
					n2=numObj[0]
					del(numObj[0])
					for arg in args:
						exec('selObj[n2].%s=%i*selObj[n2].%s + %f' %(arg,add,arg,math.pi/180*listOfVals[n]))
			else:
				for obj in selObj:
					for arg in args: exec('obj.%s=%i*obj.%s + %f' %(arg,add,arg,math.pi/180*m))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def RandSca(args,mul,m,r):############Random Scale
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		if RepTypeMenu.val==0 or RepTypeMenu.val==1:
			for obj in selObj:
				for arg in args:
					if mul==0:
						exec('obj.%s=%f' %(arg,(createRandomValue(m,r)[RepTypeMenu.val])))
					elif mul==1:
						 exec('obj.%s=obj.%s * %f' %(arg,arg,(createRandomValue(m,r)[RepTypeMenu.val])))
					elif mul==2:
						 exec('obj.%s=obj.%s + %f' %(arg,arg,(createRandomValue(m,r)[RepTypeMenu.val])))
		elif RepTypeMenu.val==2:
			numSelObj=len(selObj)
			if numSelObj!=1:	
				listOfVals,numObj=[],[]
				for n in range(numSelObj):
					listOfVals.append(m-r/2+n*r/(numSelObj-1))
					numObj.append(n)
				shuffle(numObj)
				for n in range(numSelObj):
					n2=numObj[0]
					del(numObj[0])
					for arg in args:
						if mul==0:
							exec('selObj[n2].%s=%f' %(arg,listOfVals[n]))
						elif mul==1:
							 exec('selObj[n2].%s=selObj[n2].%s * %f' %(arg,arg,listOfVals[n]))
						elif mul==2:
							 exec('selObj[n2].%s=selObj[n2].%s + %f' %(arg,arg,listOfVals[n]))
						
			else:
				for obj in selObj:
					for arg in args:
						if mul==0:
							exec('obj.%s=%f' %(arg,m))
						elif mul==1:
							 exec('obj.%s=obj.%s * %f' %(arg,arg,m))
						elif mul==2:
							 exec('obj.%s=obj.%s + %f' %(arg,arg,m))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return


def Magnet(fo,pow):
	pow=float(pow)/100
	selObj=Blender.Object.GetSelected()
	CursorPos=Window.GetCursorPos()
	args=['LocX','LocY','LocZ']
	if len(selObj)==1:
		for j in range(3):
			exec('selObj[0].%s=selObj[0].%s + %f*(CursorPos[j]-selObj[0].%s)' %(args[j],args[j],pow,args[j]))				
		Blender.Redraw()
	elif len(selObj)>1:
		maxDist=getMaxDistCurs(selObj)
		minDist=getMinDistCurs(selObj)
		print minDist,maxDist
		print 'selObj:',len(selObj)
		if maxDist==0 and fo!=0:
			PupMenu("Maximum distance is 0: can't compute ratio (division by 0). No fall-off will be applied.")
			fo=0
		if fo==0:
			for obj in selObj:
				for j in range(3):
					exec('obj.%s=obj.%s + %f*(CursorPos[j]-obj.%s)' %(args[j],args[j],pow,args[j]))
		elif fo==1:##########linear
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-(objDistCurs-minDist)/(maxDist-minDist)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==2:########## inverse
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(objDistCurs-minDist)/(maxDist-minDist)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==3:##########round
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist))**2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==4:##########sharp
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist)-1)**2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==5:##########bell
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(math.cos(math.pi/2*(objDistCurs-minDist)/(maxDist-minDist)))**2
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==6:##########torus
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.exp(-((8*((objDistCurs-minDist)/(maxDist-minDist))-5)**2)/2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==7:##########damped sine
			PupExtrema()
			nEx=DefaultNumExtrema.val
			negEx=[1,-1][ExtremaNeg.val]
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				if objDistCurs!=minDist: 
					factor=negEx*math.sin(nEx*math.pi*((objDistCurs-minDist)/(maxDist-minDist))/(nEx*math.pi*((objDistCurs-minDist)/(maxDist-minDist))))
					for j in range(3):
						exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==8:##########input
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				x=((objDistCurs-minDist)/(maxDist-minDist))
				if objDistCurs!=minDist:
					try:
						exec('factor=%s' %(functionInput.val))
					except:
						PupMenu("Please correct the syntax of your input function")
						return
					for j in range(3):
						exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 2 objects.")
		return

def AntiMagnet(fo,pow):
	pow=-float(pow)
	selObj=Blender.Object.GetSelected()
	CursorPos=Window.GetCursorPos()
	args=['LocX','LocY','LocZ']
	if len(selObj)==1:
		for j in range(3):
			exec('selObj[0].%s=selObj[0].%s + %f*(CursorPos[j]-selObj[0].%s)' %(args[j],args[j],pow,args[j]))			
		Blender.Redraw()
	elif len(selObj)>1:
		maxDist=getMaxDistCurs(selObj)
		minDist=getMinDistCurs(selObj)
		if maxDist==0 and fo!=0:
			PupMenu("Maximum distance is 0: can't compute ratio (division by 0). No fall-off will be applied.")
			fo=0
		if fo==0:
			for obj in selObj:
				for j in range(3):
					exec('obj.%s=obj.%s + %f*(CursorPos[j]-obj.%s)' %(args[j],args[j],pow,args[j]))
		elif fo==1:##########linear
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-(objDistCurs-minDist)/(maxDist-minDist)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==2:########## inverse
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(objDistCurs-minDist)/(maxDist-minDist)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==3:##########round
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist))**2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==4:##########sharp
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=1-math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist)-1)**2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==5:##########bell
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=(math.cos(math.pi/2*(objDistCurs-minDist)/(maxDist-minDist)))**2
				for j in range(3):
					exec('obj.%s=obj.%s + %*f%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==6:##########torus
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				factor=math.exp(-((8*((objDistCurs-minDist)/(maxDist-minDist))-5)**2)/2)
				for j in range(3):
					exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==7:##########damped sine
			PupExtrema()
			nEx=DefaultNumExtrema.val
			negEx=[1,-1][ExtremaNeg.val]
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				if objDistCurs!=minDist:
					factor=negEx*math.sin(nEx*math.pi*((objDistCurs-minDist)/(maxDist-minDist)))/(nEx*math.pi*(((objDistCurs-minDist)/(maxDist-minDist))))
					for j in range(3):
						exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		elif fo==8:##########input
			for obj in selObj:
				objDistCurs=distanceCursor(obj)
				if objDistCurs!=minDist:
					x=((objDistCurs-minDist)/(maxDist-minDist))
					try:
						exec('factor=%s' %(functionInput.val))
					except:
						PupMenu("Please correct the syntax of your input function")
						return
					for j in range(3):
						exec('obj.%s=obj.%s + %f*%f*(CursorPos[j]-obj.%s)' %(args[j],args[j],factor,pow,args[j]))
		Blender.Redraw()
	else:
		PupMenu("Please select at least 2 objects.")
		return

def RotMagnet(fo,pow,unique,modulo):
	pow=float(pow)/100
	if (testNumSelObj(1)):
		selObj=Blender.Object.GetSelected()
		maxDist=getMaxDistCurs(selObj)
		minDist=getMinDistCurs(selObj)

		CursorPos=Window.GetCursorPos()

		if fo==7:################damped sine
			PupExtrema()
			nEx=DefaultNumExtrema.val
			negEx=[1,-1][ExtremaNeg.val]
		elif fo==8:################input
			x=2												#A trick to test the viability of the string as a function
			try:
				exec('factor=%s' %(functionInput.val))
			except:
				PupMenu("Please correct the syntax of your input function")
				return

		for obj in selObj:
			objDistCurs=distanceCursor(obj)
			if fo==0:############no fall-off
				factor=1
			elif fo==1:##########linear
				factor=1-((objDistCurs-minDist)/(maxDist-minDist))
			elif fo==2:########## inverse
				factor=((objDistCurs-minDist)/(maxDist-minDist))
			elif fo==3:##########round
				factor=math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist))**2)
			elif fo==4:##########sharp
				factor=1-math.sqrt(1-((objDistCurs-minDist)/(maxDist-minDist))**2)
			elif fo==5:##########bell
				factor=(math.cos(math.pi/2*((objDistCurs-minDist)/(maxDist-minDist))))**2
			elif fo==6:##########torus
				factor=math.exp(-((8*((objDistCurs-minDist)/(maxDist-minDist))-5)**2)/2)
			elif fo==7:##########damped sine
				if objDistCurs!=minDist:
					factor=negEx*math.sin(nEx*math.pi*((objDistCurs-minDist)/(maxDist-minDist)))/(nEx*math.pi*((objDistCurs-minDist)/(maxDist-minDist)))
				else:
					factor=1
			elif fo==8:##########input
				if objDistCurs!=minDist:
					x=((objDistCurs-minDist)/(maxDist-minDist))
					exec('factor=%s' %(functionInput.val))
				else:
					factor=1
			dx=CursorPos[0]-obj.LocX
			dy=CursorPos[1]-obj.LocY
			dz=CursorPos[2]-obj.LocZ

			vec=Mathutils.Vector([dx,dy,dz])
			if vec==Mathutils.Vector([0,0,0]):
				PupMenu('At least one of the objects is at Cursor Location: its rotation will be brought back to (0,0,0)')
			rotx=((obj.RotX+math.pi)%(2*math.pi))-math.pi
			roty=((obj.RotY+math.pi)%(2*math.pi))-math.pi
			rotz=((obj.RotZ+math.pi)%(2*math.pi))-math.pi

			if modulo==0:
				rotx,roty,rotz=obj.RotX,obj.RotY,obj.RotZ

			vecToTrack=vec.toTrackQuat(RotMagnetTo,RotMagnetUp)
			eul=vecToTrack.toEuler()

			if unique==1:	
				if UpZ.val==1:
					if ToY.val+TominY.val==1:
						obj.RotY=obj.RotY+pow*factor*(eul[1]*degtopi-roty)
						obj.RotZ=obj.RotZ+pow*factor*(eul[2]*degtopi-rotz)
					else:
						obj.RotX=obj.RotX+pow*factor*(eul[0]*degtopi-rotx)
						obj.RotZ=obj.RotZ+pow*factor*(eul[2]*degtopi-rotz)
				elif UpY.val==1:
					if ToX.val+TominX.val==1:
						obj.RotY=obj.RotY+pow*factor*(eul[1]*degtopi-roty)
						obj.RotZ=obj.RotZ+pow*factor*(eul[2]*degtopi-rotz)
					else:
						obj.RotX=obj.RotX+pow*factor*(eul[0]*degtopi-rotx)
						obj.RotY=obj.RotY+pow*factor*(eul[1]*degtopi-roty)
				elif UpX.val==1:
					if ToZ.val+TominZ.val==1:
						obj.RotX=obj.RotX+pow*factor*(eul[0]*degtopi-rotx)
						obj.RotZ=obj.RotZ+pow*factor*(eul[2]*degtopi-rotz)
					else:
						obj.RotX=obj.RotX+pow*factor*(eul[0]*degtopi-rotx)
						obj.RotY=obj.RotY+pow*factor*(eul[1]*degtopi-roty)
	
			else:
				obj.RotX=obj.RotX+pow*factor*(eul[0]*degtopi-rotx)
				obj.RotY=obj.RotY+pow*factor*(eul[1]*degtopi-roty)
				obj.RotZ=obj.RotZ+pow*factor*(eul[2]*degtopi-rotz)


		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")

##################################################################################################
#	 Statistics Functions
################################################################################################## 

def surfaceCollection(collection):	
	numNonMesh,numMesh=0,0
	for i in range (len(collection)):
		if collection[i].type!='Mesh':
			numNonMesh+=1
	numMesh=len(collection)-numNonMesh
	if numMesh==0:
		PupMenu("No mesh object selected. Can't get surface from Curves, Nurbs, Lamps etc. Convert these objects to meshs and retry.")
		colSurfs=[0]
	else:
		if numNonMesh!=0:
			PupMenu("Only mesh objects will be taken into account. Can't get surface from Curves, Nurbs, Lamps etc. Convert these objects to meshs and retry.")
		colSurfs=[]
		for obj in selObj:
			faSurfs=[]
			if obj.type=='Mesh':
				selMe=obj.getData(False,True)
				selFa=selMe.faces
				for f in selFa:
					faSurfs.append(f.area*((obj.SizeX*obj.SizeY)+(obj.SizeX*obj.SizeZ)+(obj.SizeY*obj.SizeZ))/3)
				meSurf,i=0,0
				while i in range(len(faSurfs)):
					meSurf+=faSurfs[i]
					i+=1
				print meSurf
				colSurfs.append(meSurf)
	return colSurfs

def listOfElements(objCollection,arg):
	global listElements
	listElements=[]
	if arg in ('RotX','RotY','RotZ'):
		for obj in objCollection:
			exec('a=180/(math.pi)*obj.%s' %arg)
			listElements.append(a)
	else:
		for obj in objCollection:
			exec('a=obj.%s' %arg)
			listElements.append(a)		
	return (listElements)

def distanceCursor(single):
	CursorLoc=Window.GetCursorPos()
	x01=math.fabs(single.LocX-CursorLoc[0])
	y01=math.fabs(single.LocY-CursorLoc[1])
	z01=math.fabs(single.LocZ-CursorLoc[2])
	distCurs=(x01**2+y01**2+z01**2)**(1.0/2)
	return distCurs

def distancePair(pair):
	x01=math.fabs(pair[0].LocX-pair[1].LocX)
	y01=math.fabs(pair[0].LocY-pair[1].LocY)
	z01=math.fabs(pair[0].LocZ-pair[1].LocZ)
	distPair=(x01**2+y01**2+z01**2)**(1.0/2)
	return distPair

def distanceCollection(collection):
	colDistances=[]
	numSelObj=len(collection)
	if numSelObj==0:
		PupMenu("Not enough objects selected")
		colDistances=[0]	
	elif numSelObj==1:
		single=collection[0]
		colDistances.append(distanceCursor(single))
	elif numSelObj==2:
		colDistances.append(distancePair(collection))
	else:
		A,B=0,1
		TempAB=[]
		while A<numSelObj:
			while B<numSelObj:
				colDistances.append(distancePair([collection[A],collection[B]]))
				B=B+1
			A,B=A+1,A+2
	return (colDistances)

def valueSum(collectionOfValues):
	valueSum=0.000000
	for i in collectionOfValues:
		if type(i) in [float,int,long]:
			valueSum=valueSum+i
	return (valueSum)
		
def valueMean(collectionOfValues):
	numDist=len(collectionOfValues)
	if numDist!=0:
		valueMean=(valueSum(collectionOfValues)/numDist)
	else:
		valueMean=0
	return (valueMean)
	
def valueStdDev(collectionOfValues):
	distMean=valueMean(collectionOfValues)
	Deviations=[]
	for i in collectionOfValues:
		Deviations.append((i-distMean)**2)
	Variance=valueMean(Deviations)
	StdDev=math.sqrt(Variance)
	return (StdDev)
	
def getDistStats():
	selObj=Blender.Object.GetSelected()
	global numSelObj
	numSelObj=len(selObj)
	colDist=distanceCollection(selObj)
	distSum=valueSum(colDist)
	distMean=valueMean(colDist)
	distStdDev=valueStdDev(colDist)
	distMax=max(colDist)
	distMin=min(colDist)
	return (numSelObj,distSum,distMean,distStdDev,distMax,distMin)

def getSurfStats():
	selObj=Blender.Object.GetSelected()
	colSurf=surfaceCollection(selObj)
	print colSurf
	surfMin=min(colSurf)
	surfMax=max(colSurf)
	surfMean=valueMean(colSurf)
	surfStdDev=valueStdDev(colSurf)
	surfSum=valueSum(colSurf)
	return (surfMin,surfMax,surfMean,surfStdDev,surfSum)
	
def getRepStats(ElChoice):
	if testNumSelObj(1):
		selObj=Blender.Object.GetSelected()
		if ElChoice==0:
			ElType=('LocX','LocY','LocZ')
		elif ElChoice==1:
			ElType=('RotX','RotY','RotZ')
		else:
			ElType=('SizeX','SizeY','SizeZ')
		XlistElements=listOfElements(selObj,ElType[0])
		XelMean,XelStdDev=valueMean(XlistElements),valueStdDev(XlistElements)
		XelMax,XelMin=max(XlistElements),min(XlistElements)
		YlistElements=listOfElements(selObj,ElType[1])
		YelMean,YelStdDev=valueMean(YlistElements),valueStdDev(YlistElements)
		YelMax,YelMin=max(YlistElements),min(YlistElements)
		ZlistElements=listOfElements(selObj,ElType[2])
		ZelMean,ZelStdDev=valueMean(ZlistElements),valueStdDev(ZlistElements)
		ZelMax,ZelMin=max(ZlistElements),min(ZlistElements)
		return (XelMin,XelMax,XelMean,XelStdDev,YelMin,YelMax,YelMean,YelStdDev,ZelMin,ZelMax,ZelMean,ZelStdDev)
	else:
		return (0,0,0,0,0,0,0,0,0,0,0,0)

def getMaxDistCurs(collection):
	distsCurs=[]
	if len(collection)>0:
		for obj in collection:
			distsCurs.append(distanceCursor(obj))
		maxDistCurs=max(distsCurs)
		return(maxDistCurs)
	else:
		PupMenu("Please select at least 1 object.")
		return

def getMinDistCurs(collection):
	distsCurs=[]
	if len(collection)>0:
		for obj in collection:
			distsCurs.append(distanceCursor(obj))
		minDistCurs=min(distsCurs)
		return(minDistCurs)
	else:
		PupMenu("Please select at least 1 object.")
		return

def getMaxDistActive(collection):
	distsActive=[]
	if (testNumSelObj(2)):
		active=collection[0]
		for obj in collection:
			distsActive.append(distancePair([obj,active]))
		maxDistActive=max(distsActive)
		return(maxDistActive)
	else:
		PupMenu("Please select at least 2 objects.")
		return

##################################################################################################										 
#	 Materials functions
##################################################################################################

def CopyMatMesh():
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		print selObj[0].type

		if selObj[0].type=='Mesh':							#Active object is a mesh
			selMe=selObj[0].getData(False,True)
			selMeMat=selMe.materials	
			for obj in selObj:
				if obj.type=='Mesh':
					me=obj.getData(False,True)
					me.materials=selMeMat
				elif obj.type=='Curve':
					cu=obj.data
					cu.materials=selMeMat
				elif obj.type=='MBall':
					met=obj.data
					met.materials=selMeMat
				continue
			Blender.Redraw()
		elif selObj[0].type=='Curve':						#Active object is a curve
			selCu=selObj[0].data
			selCuMat=selCu.materials	
			for obj in selObj:
				if obj.type=='Mesh':
					me=obj.getData(False,True)
					me.materials=selCuMat
				elif obj.type=='Curve':
					cu=obj.data
					cu.materials=selCuMat
				elif obj.type=='MBall':
					met=obj.data
					met.materials=selCuMat
				continue
			Blender.Redraw()
		elif selObj[0].type=='MBall':						#Active object is a metaball
			selMet=selObj[0].data
			selMetMat=selMet.materials	
			for obj in selObj:
				if obj.type=='Mesh':
					me=obj.getData(False,True)
					me.materials=selMetMat
				elif obj.type=='Curve':
					cu=obj.data
					cu.materials=selMetMat
				elif obj.type=='MBall':
					met=obj.data
					met.materials=selMetMat
				continue
			Blender.Redraw()

		else:
			PupMenu('The active object must either be a mesh or a curve.')
			print selObj[0].type
			return
	else:
		PupMenu("Please select at least 2 objects.")
		return

def CopyMatObj():
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		selObjMat=selObj[0].getMaterials()
		for obj in selObj:
			obj.setMaterials(selObjMat)
		Blender.Redraw()
	else:
		PupMenu("Please select at least 2 objects.")
		return

def GetRandomMat():								#gets a random material from all available mats in the scene.
	allMats=Material.Get()
	selObj=Blender.Object.GetSelected()
	for obj in selObj:
		r=randint(0,len(allMats)-1)
		if obj.type=='Mesh':
			selMe=obj.getData(False,True)
			selMe.materials=[allMats[r]]
		elif obj.type=='Curve':
			cu=obj.data
			cu.materials=[allMats[r]]
		elif obj.type=='MBall':
			met=obj.data
			met.materials=[allMats[r]]
		continue
	Blender.Redraw()

def CreateRandomMat():
	if colTog.val==0 and refTog.val==0 and specTog.val==0 and hardTog==0 and speColTog.val==0 and emitTog==0 and alpTog==0 and mirTog.val==0 and traTog==0 and mirColTog==0:
		PupMenu("A new material will be created, but all values will be the default values: no randomness allowed !")
	mat=Material.New('RandomMaterial')
	if colTog.val==1:
		mat.rgbCol=[round(random(),1),round(random(),1),round(random(),1)]
	if refTog.val==1:
		mat.ref=(round(random(),1))
	if specTog.val==1:
		mat.spec=(round(random(),1))
	if hardTog.val==1:
		mat.hard=randint(0,249)
	if speColTog.val==1:
		mat.specCol=(round(random(),1),round(random(),1),round(random(),1))
	if emitTog.val==1:
		mat.emit=(round(random(),1))
	if alpTog.val==1:
		mat.alpha=(round(random(),1))
	if mirTog.val==1:
		mat.mode |= Material.Modes.RAYMIRROR
		mat.setRayMirr(1-round(random(),2)**2)
#		mat.setFresnelMirr(5*round(random()**4,2))
#		mat.setFresnelMirrFac(4*round(random()**4,2)+1)
	if traTog.val==1:
		mat.mode |= Material.Modes.RAYTRANSP
#		mat.setFresnelTrans(5*round(random()**4,2))
#		mat.setFresnelTransFac(4*round(random()**4,2)+1)
		mat.IOR=5*round(random(),2)
	if mirColTog.val==1:
		mat.mirCol=(round(random(),1),round(random(),1),round(random(),1))
	Blender.Redraw()

def ModifyMat(factor):
	factor=float(factor)/100
	selObj=Blender.Object.GetSelected()
	availMats=[]
	for obj in selObj:
		selDat=obj.getData(False,True)
		selMat=selDat.materials
		for mat in selMat:
			if mat != None:
				if mat not in availMats:
					availMats.append(mat)
		objMats=obj.getMaterials()
		for mat in objMats:
			if mat != None:
				if mat not in availMats:
					availMats.append(mat)
	print availMats
	for mat in availMats:
		if colTog.val==0 and refTog.val==0 and specTog.val==0 and hardTog==0 and speColTog.val==0 and emitTog==0 and alpTog==0 and mirTog.val==0 and traTog==0 and mirColTog==0:
			PupMenu("Please select some parameter to change to the material: no randomness allowed !")
			return
		if colTog.val==1:
			R,G,B=mat.rgbCol[0],mat.rgbCol[1],mat.rgbCol[2]
			R=R+factor*(round(random(),1)-R)
			G=G+factor*(round(random(),1)-G)			
			B=B+factor*(round(random(),1)-B)
			mat.rgbCol=[R,G,B]
		if refTog.val==1:
			mat.ref=mat.ref+(round(random(),1)-mat.ref)*factor
		if specTog.val==1:
			mat.spec=mat.spec+(round(random(),1)-mat.spec)*factor
		if hardTog.val==1:
			mat.hard=mat.hard+(randint(0,249)-mat.hard)*factor
		if speColTog.val==1:
			R2,G2,B2=mat.specCol[0],mat.specCol[1],mat.specCol[2]
			R2=R2+factor*(round(random(),1)-R2)
			G2=G2+factor*(round(random(),1)-G2)			
			B2=B2+factor*(round(random(),1)-B2)
			mat.specCol=[R2,G2,B2]
		if emitTog.val==1:
			mat.emit=mat.emit+(round(random(),1)-mat.emit)*factor
		if alpTog.val==1:
			mat.alpha=mat.alpha+(round(random(),1)-mat.alpha)*factor
		if mirTog.val==1:
			mat.mode |= Material.Modes.RAYMIRROR
			mat.setRayMirr(1-round(random(),2)**2)
			mat.fresnelDepth=3*round(random()**3,2)
			mat.fresnelDepthFac=1+round(random()**3,2)
		if traTog.val==1:
			mat.mode |= Material.Modes.RAYTRANSP
	#		mat.setFresnelTrans(5*round(random()**4,2))
	#		mat.setFresnelTransFac(4*round(random()**4,2)+1)
			mat.IOR=5*round(random(),2)
		if mirColTog.val==1:
			mat.mirCol=(round(random(),1),round(random(),1),round(random(),1))
	Blender.Redraw()

##################################################################################################
#	 Selection Functions
##################################################################################################

def DistanceSelectInf(Thres):
	scn=Scene.GetCurrent()
	availObj=list(scn.objects)
	selObj=Blender.Object.GetSelected()
	if selObj==[]:
		maxDist=getMaxDistCurs(availObj)
		for obj in availObj:
			if distanceCursor(obj)<Thres:
				obj.sel=True
			else:
				obj.sel=False
	else:
		maxDist=getMaxDistCurs(selObj)
		for obj in selObj:
			if distanceCursor(obj)<Thres:
				obj.sel=True
			else:
				obj.sel=False
	Blender.Redraw()

def DistanceSelectSup(Thres):
	scn=Scene.GetCurrent()
	availObj=list(scn.objects)
	selObj=Blender.Object.GetSelected()
	if selObj==[]:
		maxDist=getMaxDistCurs(availObj)
		for obj in availObj:
			if distanceCursor(obj)>Thres:
				obj.sel=True
			else:
				obj.sel=False
	else:
		maxDist=getMaxDistCurs(selObj)
		for obj in selObj:
			if distanceCursor(obj)>Thres:
				obj.sel=True
			else:
				obj.sel=False
	Blender.Redraw()

def RandomSelect():
	selObj=Blender.Object.GetSelected()
	scn=Scene.GetCurrent()
	availObj=scn.objects
	if selObj==[]:
		for obj in availObj:
			if obj.type in ['Mesh','Curve','MBall','Text','Empty','Lattice']:
				x=random()
				if x>0.5:
					obj.sel=True
	else:
		for obj in selObj:
			x=random()
			if x>0.5:
				obj.sel=False
	Blender.Redraw()
		
def DataMaterialSelect():									#Selects objects in the scene which data shares at least one of the materials of the active object's data
	if testNumSelObj(1):		
		selObj=Blender.Object.GetSelected()
		active=selObj[0]
		scn=Scene.GetCurrent()
		availObj=list(scn.objects)
		selMat=[]
		newSelObjMat=[]
		for obj in selObj:
			if obj.type=='Mesh':							#Active object is a mesh
				selMe=obj.getData(False,True)
				selMeMat=selMe.materials
				for mat in selMeMat:
					if mat not in selMat:
						selMat.append(mat)
			elif obj.type=='Curve':						#Active object is a curve
				selCu=obj.data
				selCuMat=selCu.materials	
				for mat in selCuMat:
					if mat not in selMat:
						selMat.append(mat)	
			elif obj.type=='MBall':						#Active object is a metaball
				selMet=obj.data
				selMetMat=selMet.materials	
				for mat in selMetMat:
					if mat not in selMat:
						selMat.append(mat)			
		for obj in availObj:
			if obj.type=='Mesh':								#object is a mesh
				selMe=obj.getData(False,True)
				selMeMat=selMe.materials
				for mat in selMat:
					if mat in selMeMat:
						newSelObjMat.append(obj)
			elif obj.type=='Curve':								#object is a curve
				selCu=obj.data
				selCuMat=selCu.materials	
				for mat in selMat:
					if mat in selCuMat:
						newSelObjMat.append(obj)
			elif obj.type=='MBall':								#object is a metaball
				selMet=obj.data
				selMetMat=selMet.materials	
				for mat in selMat:
					if mat in selMetMat:
						newSelObjMat.append(obj)
		for obj in newSelObjMat:
			obj.sel=True
			active.sel=True
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def ObjectTypeSelect():
	if testNumSelObj(1):
		selObj=Blender.Object.GetSelected()
		scn=Scene.GetCurrent()
		availObj=list(scn.objects)
		actObj=selObj[0]
		for obj in availObj:
			if obj.getType()==actObj.getType():
				print 'same type found\n'
				obj.sel=1
		actObj.sel=1	
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

def ObjectMaterialSelect():									#Selects objects in the scene which share at least one of the materials of the active object
	if testNumSelObj(1):
		selObj=Blender.Object.GetSelected()
		scn=Scene.GetCurrent()
		availObj=list(scn.objects)
		selObjMat=[]
		for obj in selObj:
			mats=obj.getMaterials()
			for mat in mats:
				if mat not in selObjMat:
					selObjMat.append(mat)	
		if selObjMat==[]:
			PupMenu("The active object isn't linked with any material. Cannot proceed...")
			return
		else:
			for obj in availObj:
				objMat=obj.getMaterials()	
				if selObjMat[0] in objMat:
					obj.sel=1
				else:
					obj.sel=0
		Blender.Redraw()
	else:
		PupMenu("Please select at least 1 object.")
		return

##################################################################################################
#	 Animation Functions
##################################################################################################

def CopyCorrectLocIPO():
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		activeIPO=selObj[0].ipo

		absValues=[Ipo.OB_LOCX,Ipo.OB_LOCY,Ipo.OB_LOCZ]
		absValuesNames=['LocX','LocY','LocZ']
		if activeIPO:
			for obj in selObj:
				if obj!=selObj[0]:
					dX=selObj[0].LocX-obj.LocX
					dY=selObj[0].LocY-obj.LocY
					dZ=selObj[0].LocZ-obj.LocZ						
					dLocs=[dX,dY,dZ]
					if obj.ipo: #Check if object already has an IPO linked with it
						for n in range(3):
							if obj.ipo[absValues[n]]:								#check for existing Loc curves and systematicaly erase them
								obj.ipo[absValues[n]]=None
					else:				#For objects without IPO data, create a new IPO data named after the object
						newname=obj.getName()+'IPO'
						obj.ipo=Ipo.New('Object',newname)
					for m in range(3):													#Append Loc curves from the active object
						if activeIPO[absValues[m]]:
							newCurve=obj.ipo.addCurve(absValuesNames[m])
							for bp in activeIPO[absValues[m]].bezierPoints:
								newCurve.append(bp)
								newCurve.extend=activeIPO[absValues[m]].extend
								newCurve.interpolation=activeIPO[absValues[m]].interpolation
							for bp2 in obj.ipo[absValues[m]].bezierPoints:
								bp2.pt=[bp2.pt[0],bp2.pt[1]-dLocs[m]]
							newCurve.recalc()
		else:
			PupMenu("The active object doesn't have an IPO linked to it. Can't proceed...")
	else:
		PupMenu('Select at least 2 objects')
		return		


def CopyCorrectRotIPO():
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		activeIPO=selObj[0].ipo

		absValues=[Ipo.OB_ROTX,Ipo.OB_ROTY,Ipo.OB_ROTZ]
		absValuesNames=['RotX','RotY','RotZ']
		if activeIPO:
			for obj in selObj:
				if obj!=selObj[0]:
					dX=180/math.pi*(selObj[0].RotX-obj.RotX)
					dY=180/math.pi*(selObj[0].RotY-obj.RotY)
					dZ=180/math.pi*(selObj[0].RotZ-obj.RotZ)
					dLocs=[dX,dY,dZ]
					if obj.ipo: #Check if object already has an IPO linked with it
						for n in range(3):
							if obj.ipo[absValues[n]]:								#check for existing Loc curves and systematicaly erase them
								obj.ipo[absValues[n]]=None
					else:				#For objects without IPO data, create a new IPO data named after the object
						newname=obj.getName()+'IPO'
						obj.ipo=Ipo.New('Object',newname)
					for m in range(3):													#Append Loc curves from the active object
						if activeIPO[absValues[m]]:
							newCurve=obj.ipo.addCurve(absValuesNames[m])
							for bp in activeIPO[absValues[m]].bezierPoints:
								newCurve.append(bp)
								newCurve.extend=activeIPO[absValues[m]].extend
								newCurve.interpolation=activeIPO[absValues[m]].interpolation
							for bp2 in obj.ipo[absValues[m]].bezierPoints:
								bp2.pt=[bp2.pt[0],bp2.pt[1]-dLocs[m]/10]
							newCurve.recalc()
		else:
			PupMenu("The active object doesn't have an IPO linked to it. Can't proceed...")
	else:
		PupMenu('Select at least 2 objects')
		return


def CopyCorrectScaleIPO():
	if (testNumSelObj(2)):
		selObj=Blender.Object.GetSelected()
		activeIPO=selObj[0].ipo

		absValues=[Ipo.OB_SCALEX,Ipo.OB_SCALEY,Ipo.OB_SCALEZ]
		absValuesNames=['ScaleX','ScaleY','ScaleZ']
		if activeIPO:
			for obj in selObj:
				if obj!=selObj[0]:
					dX=selObj[0].SizeX-obj.SizeX
					dY=selObj[0].SizeY-obj.SizeY
					dZ=selObj[0].SizeZ-obj.SizeZ						
					dLocs=[dX,dY,dZ]
					if obj.ipo: #Check if object already has an IPO linked with it
						for n in range(3):
							if obj.ipo[absValues[n]]:								#check for existing Loc curves and systematicaly erase them
								obj.ipo[absValues[n]]=None
					else:				#For objects without IPO data, create a new IPO data named after the object
						newname=obj.getName()+'IPO'
						obj.ipo=Ipo.New('Object',newname)
					for m in range(3):													#Append Loc curves from the active object
						if activeIPO[absValues[m]]:
							newCurve=obj.ipo.addCurve(absValuesNames[m])
							for bp in activeIPO[absValues[m]].bezierPoints:
								newCurve.append(bp)
								newCurve.extend=activeIPO[absValues[m]].extend
								newCurve.interpolation=activeIPO[absValues[m]].interpolation
							for bp2 in obj.ipo[absValues[m]].bezierPoints:
								bp2.pt=[bp2.pt[0],bp2.pt[1]-dLocs[m]]
							newCurve.recalc()
		else:
			PupMenu("The active object doesn't have an IPO linked to it. Can't proceed...")
	else:
		PupMenu('Select at least 2 objects')
		return

def ShuffleIPO():
	selObj=Blender.Object.GetSelected()
	if testNumSelObj(1):
		if Delta.val==0:
			values=[[Ipo.OB_LOCX,Ipo.OB_LOCY,Ipo.OB_LOCZ],[Ipo.OB_ROTX,Ipo.OB_ROTY,Ipo.OB_ROTZ],[Ipo.OB_SCALEX,Ipo.OB_SCALEY,Ipo.OB_SCALEZ]]
#			curves=[['LocX','LocY','LocZ'],['RotX','RotY','RotZ'],['ScaleX','ScaleY','ScaleZ']]
		elif Delta.val==1:
			values=[[Ipo.OB_DLOCX,Ipo.OB_DLOCY,Ipo.OB_DLOCZ],[Ipo.OB_DROTX,Ipo.OB_DROTY,Ipo.OB_DROTZ],[Ipo.OB_DSCALEX,Ipo.OB_DSCALEY,Ipo.OB_DSCALEZ]]
#			curves=[['dLocX','dLocY','dLocZ'],['dRotX','dRotY','dRotZ'],['dScaleX','dScaleY','dScaleZ']]
		types=[ShuffleLoc,ShuffleRot,ShuffleSize]
		axis=[ShuffleX,ShuffleY,ShuffleZ]
		curvesToManipulate=[]
		for t in range(3):
			for t2 in range(3):
				if types[t2]==1:
					if axis[t]==1:
						curvesToManipulate.append(values[t2][t])
		for y in range(len(curvesToManipulate)):
			for obj in selObj:
				if obj.ipo:
					if obj.ipo[curvesToManipulate[y]]:
						print obj.ipo[curvesToManipulate[y]],curvesToManipulate[y],curvesToManipulate
						if IndShuffle.val==0:
							shuf=(random()-0.5)*ShuffleRange.val
						for bp in obj.ipo[curvesToManipulate[y]].bezierPoints:
							if IndShuffle.val==1:
								shuf=(random()-0.5)*ShuffleRange.val
							[ptx,pty]=bp.pt
							if ShuffleStart.val<=ptx+shuf<=ShuffleEnd.val:
								bp.pt=[ptx+shuf,pty]
						obj.ipo[curvesToManipulate[y]].recalc()
	Blender.Redraw()

def ShuffleOtherIPO():
	selObj=Blender.Object.GetSelected()
	if testNumSelObj(1):
		ChosenIPO=PupStrInput('IPO:',' ? ',28)
		print ChosenIPO,type(ChosenIPO)
		for obj in selObj:
				if obj.ipo:
					exec("if obj.ipo[IpoCurve '%s']:	test=1" %ChosenIPO)
					print test
#						shuf=(random()-0.5)*ShuffleRange.val
#						for bp in obj.ipo[ChosenIPO].bezierPoints:
#							[ptx,pty]=bp.pt
#							if ShuffleStart.val<=ptx+shuf<=ShuffleEnd.val:
#								bp.pt=[ptx+shuf,pty]
#						obj.ipo[ChosenIPO].recalc()
	Blender.Redraw()

def Animate(curve,span,sta,end,extType,interType):
	selObj=Blender.Object.GetSelected()
	listOfKeys=[]
	listOfMappedKeys=[]
	listOfValues=[]
	dict={0:'LocX',1:'LocY',2:'LocZ',3:'dLocX',4:'dLocY',5:'dLocZ',6:'RotX',7:'RotY',8:'RotZ',9:'dRotX',10:'dRotY',11:'dRotZ',12:'ScaleX',13:'ScaleY',14:'ScaleZ',15:'dScaleX',16:'dScaleY',17:'dScaleZ'}
	arg=dict[curve]

	print '\n\n######## Animate #########'
	print '',arg
	
	numberOfKeys=span
	print 'number of keys:',numberOfKeys
	
	print 'There are ',len(selObj),' objects selected'
	minDist=getMinDistCurs(selObj)
	print 'Min. dist to cursor : ',minDist
	maxDist=getMaxDistCurs(selObj)
	print 'Max. dist to cursor : ',maxDist
	
	objDistCurs=distanceCursor(obj)
	objFactor=objDistCurs/maxDist
	
	
	
	j=0
	while j<numberOfKeys:
		listOfKeys.append(sta+j)
		j+=1
	print 'list of keys: ',listOfKeys,len(listOfKeys)


	if MapTo01.val==1:
		for key in listOfKeys:
			listOfMappedKeys.append((key-listOfKeys[0])/float(span-1))
		print 'list of mapped keys :\n',listOfMappedKeys
	else:
		listOfMappedKeys=listOfKeys

	for key in listOfMappedKeys:
		listOfValues.append(function(key))
	print len(listOfValues),' values: '
	print listOfValues
	
	translate={0:Ipo.OB_LOCX,1:Ipo.OB_LOCY,2:Ipo.OB_LOCZ,3:Ipo.OB_DLOCX,4:Ipo.OB_DLOCY,5:Ipo.OB_DLOCZ,6:Ipo.OB_ROTX,7:Ipo.OB_ROTY,8:Ipo.OB_ROTZ,9:Ipo.OB_DROTX,10:Ipo.OB_DROTY,11:Ipo.OB_DROTZ,12:Ipo.OB_SCALEX,13:Ipo.OB_SCALEY,14:Ipo.OB_SCALEZ,15:Ipo.OB_DSCALEX,16:Ipo.OB_DSCALEY,17:Ipo.OB_DSCALEZ}
	translate={'LocX':Ipo.OB_LOCX,'LocY':Ipo.OB_LOCY,'LocZ':Ipo.OB_LOCZ,'dLocX':Ipo.OB_DLOCX,'dLocY':Ipo.OB_DLOCY,'dLocZ':Ipo.OB_DLOCZ,'RotX':Ipo.OB_ROTX,'RotY':Ipo.OB_ROTY,'RotZ':Ipo.OB_ROTZ,'dRotX':Ipo.OB_DROTX,'dRotY':Ipo.OB_DROTY,'dRotZ':Ipo.OB_DROTZ,'ScaleX':Ipo.OB_SCALEX,'ScaleY':Ipo.OB_SCALEY,'ScaleZ':Ipo.OB_SCALEZ,'dScaleX':Ipo.OB_DSCALEX,'dScaleY':Ipo.OB_DSCALEY,'dScaleZ':Ipo.OB_DSCALEZ}

	# absValues=[Ipo.OB_LOCX,Ipo.OB_LOCY,Ipo.OB_LOCZ]
	# absValuesNames=['LocX','LocY','LocZ']
	
	#for obj in selObj:
	
	obj=selObj[0]
	if obj.ipo:			# Tests if object has IPO and destroy the existing curve if so
		print 'object has an IPO'
		print curve,translate[dict[curve]]
		if obj.ipo[translate[dict[curve]]]:
			print 'object has this curve'
			obj.ipo[translate[dict[curve]]]=None
			print 'object hasnt it anymore'
	else:				#For objects without IPO data, create a new IPO data named after the object
		print 'object has no IPO'
		newname=obj.getName()+'IPO'
		obj.ipo=Ipo.New('Object',newname)
		print 'object has one !'
	
	print 'On en est la !##################################'
	
	object=obj
	try:
		exec("newCurve=object.ipo.addCurve('%s')" %(arg))
		print 'a new curve has been added'
	except:
		pass
	newCurve.extend=extType
	newCurve.interpolation=interType
	print 'extType,interType',extType,interType
	
	
	
	l=0
	while l<span:
		newCurve.append((listOfKeys[l],listOfValues[l]))
		l+=1
	# i=+1
	# while i <(numberOfKeys-1):
		# Ax,Bx,Cx=listOfKeys[i-1],listOfKeys[i],listOfKeys[i+1]
		# Ay,By,Cy=listOfKeyValues[i-1],listOfKeyValues[i],listOfKeyValues[i+1]
		# bt=BezTriple.New(Bx-(Bx-Ax)/3+span,fac*(By+(Cy-Ay)/(6*(Cx-Ax))),0,Bx+span,fac*By,0,Bx+(Cx-Bx)/3+span,fac*(By+(Cy-Ay)/(6*(Cx-Ax))),0)
		# bt.handleTypes=(2,2)
		# newCurve.append(bt)
		# i+=1
	# newCurve.append((listOfKeys[i]+span,fac*listOfKeyValues[i]))
	newCurve.recalc()
	Blender.Redraw()
	Blender.Redraw()

def BrownianMotion(sta,end,per,reg,str):
	selObj=Blender.Object.GetSelected()
	listOfKeys=[]
	listOfMappedKeys=[]
	listOfKeyValues=[]
	dict={0:'LocX',1:'LocY',2:'LocZ',3:'dLocX',4:'dLocY',5:'dLocZ',6:'RotX',7:'RotY',8:'RotZ',9:'dRotX',10:'dRotY',11:'dRotZ',12:'ScaleX',13:'ScaleY',14:'ScaleZ',15:'dScaleX',16:'dScaleY',17:'dScaleZ'}
	translate={'LocX':Ipo.OB_LOCX,'LocY':Ipo.OB_LOCY,'LocZ':Ipo.OB_LOCZ,'dLocX':Ipo.OB_DLOCX,'dLocY':Ipo.OB_DLOCY,'dLocZ':Ipo.OB_DLOCZ,'RotX':Ipo.OB_ROTX,'RotY':Ipo.OB_ROTY,'RotZ':Ipo.OB_ROTZ,'dRotX':Ipo.OB_DROTX,'dRotY':Ipo.OB_DROTY,'dRotZ':Ipo.OB_DROTZ,'ScaleX':Ipo.OB_SCALEX,'ScaleY':Ipo.OB_SCALEY,'ScaleZ':Ipo.OB_SCALEZ,'dScaleX':Ipo.OB_DSCALEX,'dScaleY':Ipo.OB_DSCALEY,'dScaleZ':Ipo.OB_DSCALEZ}

	
	print '\n######## Brownian Motion #########'
	print selObj
	
#Faire correspondre les boutons a une liste d'arguments#
	args=[]
	if BrownDelta.val==0:
		if BrLocX.val==1:	args.append(dict[0])
		if BrLocY.val==1:	args.append(dict[1])
		if BrLocZ.val==1:	args.append(dict[2])
		if BrRotX.val==1:	args.append(dict[6])
		if BrRotY.val==1:	args.append(dict[7])
		if BrRotZ.val==1:	args.append(dict[8])
		if BrSizeX.val==1:	args.append(dict[12])
		if BrSizeY.val==1:	args.append(dict[13])
		if BrSizeZ.val==1:	args.append(dict[14])
	else:
		if BrLocX.val==1:	args.append(dict[3])
		if BrLocY.val==1:	args.append(dict[4])
		if BrLocZ.val==1:	args.append(dict[5])
		if BrRotX.val==1:	args.append(dict[9])
		if BrRotY.val==1:	args.append(dict[10])
		if BrRotZ.val==1:	args.append(dict[11])
		if BrSizeX.val==1:	args.append(dict[15])
		if BrSizeY.val==1:	args.append(dict[16])
		if BrSizeZ.val==1:	args.append(dict[17])

	print 'args:',args
	LocArgs=listIntersect(args,('LocX','LocY','LocZ','dLocX','dLocY','dLocZ'))
	RotArgs=listIntersect(args,('RotX','RotY','RotZ','dRotX','dRotY','dRotZ'))
	ScaleArgs=listIntersect(args,('ScaleX','ScaleY','ScaleZ','dScaleX','dScaleY','dScaleZ'))
	print 'Loc arguments: ',LocArgs
	print 'Rot arguments: ',RotArgs
	print 'Scale arguments: ',ScaleArgs

#Tester si certains objects perdont leur IPO
	CurvesWillBeErased=0
	for obj in selObj:
		if obj.ipo:			# Tests if object has IPO
			for arg in args:
				if obj.ipo[translate[arg]]:
					CurvesWillBeErased=1
	if CurvesWillBeErased==1:
		PupMenu("Some Objects will have their IPO curves erased !")

#Remplacer les IPO en question
	for obj in selObj:

		# ######################################## CLEANING IPOS #############
		if obj.ipo:			# Tests if object has IPO
			print "obj has an IPO"
			for arg in args:
				if obj.ipo[translate[arg]]:
					print "obj has an ", obj.ipo[translate[arg]]," curve"
					obj.ipo[translate[arg]]=None
					print "obj hasn't it anymore"
		else:				#For objects without IPO data, create a new IPO data named after the object
			newname=obj.getName()+'IPO'
			obj.ipo=Ipo.New('Object',newname)
			
		for arg in args:
			exec("newCurve=obj.ipo.addCurve('%s')" %(arg))
			newCurve.extend=0
			newCurve.interpolation=2
		# ################################################################
		
		newFrame=sta
		currentValueLocs=newValueLocs=[0,0,0]
		currentValueRot=newValueRot=[0,0,0]
		currentValueSize=newValueSize=[0,0,0]
		a=per

		while newFrame+a<end:
			a=sqrt((createRandomValue(per,(1/(math.pi)*per*(1-reg))**2)[1])**2)		
		
			if LocArgs!=[]: #For those we use the Loc settings for range.
				
				for x in range(len(LocArgs)):
					btPre=(newFrame+str*a,currentValueLocs[x])
					obj.ipo[translate[LocArgs[x]]].append(btPre)
					
					newValueLocs[x]=createRandomValue(0,RangeNumberLoc.val)[1]
					
					btChange=(newFrame+a,currentValueLocs[x]+newValueLocs[x])
					obj.ipo[translate[LocArgs[x]]].append(btChange)
					
					currentValueLocs[x]+=newValueLocs[x]
			
			if RotArgs!=[]: #For those we use the Rot settings for range.
				
				for x in range(len(listIntersect(args,('RotX','RotY','RotZ','dRotX','dRotY','dRotZ')))):
					btPre=(newFrame+str*a,currentValueRot[x])
					obj.ipo[translate[RotArgs[x]]].append(btPre)
					
					newValueRot[x]=createRandomValue(0,RangeNumberRot.val)[1]/180*math.pi
					
					btChange=(newFrame+a,currentValueRot[x]+newValueRot[x])
					obj.ipo[translate[RotArgs[x]]].append(btChange)
					
					currentValueRot[x]+=newValueRot[x]
				
			if ScaleArgs!=[]: #For those we use the Rot settings for range.
		
				if BrProp.val==0:
					for x in range(len(listIntersect(args,('ScaleX','ScaleY','ScaleZ','dScaleX','dScaleY','dScaleZ')))):
						btPre=(newFrame+str*a,currentValueSize[x])
						obj.ipo[translate[ScaleArgs[x]]].append(btPre)
						
						newValueSize[x]=abs(createRandomValue(0,RangeNumberSize.val)[1])
						
						btChange=(newFrame+a,currentValueSize[x]+newValueSize[x])
						obj.ipo[translate[ScaleArgs[x]]].append(btChange)
						
						currentValueSize[x]+=newValueSize[x]
					newFrame+=a
				else:
					btPre=(newFrame+str*a,currentValueSize[0])
					newValueSize[0]=abs(createRandomValue(0,RangeNumberSize.val)[1])
					btChange=(newFrame+a,currentValueSize[0]+newValueSize[0])
					for x in range(len(listIntersect(args,('ScaleX','ScaleY','ScaleZ','dScaleX','dScaleY','dScaleZ')))):
						obj.ipo[translate[ScaleArgs[x]]].append(btPre)
						obj.ipo[translate[ScaleArgs[x]]].append(btChange)
						
					currentValueSize[0]+=newValueSize[0]
			newFrame+=a

		
# #################################################################################################										 
#	 GUI functions
# #################################################################################################										 
def rect(X1,Y1,X2,Y2,r,g,b):
	glColor3f(r,g,b)
	glRecti(X1,Y1,X2,Y2)
def line(X1,Y1,X2,Y2,r,g,b):
	glColor3f(r,g,b)
	glBegin(GL_LINES)
	glVertex2i(X1,Y1)
	glVertex2i(X2,Y2)
	glEnd()
def panel(posX,posY,L,H,r,g,b):
	rect(posX+4,posY-4,posX+L+4,posY-H-4,.55,.55,.55)									#1st shadow
	rect(posX+3,posY-3,posX+L+3,posY-H-3,.45,.45,.45)
	rect(posX+3,posY-3,posX+L+2,posY-H-2,.30,.30,.30)									#2nd shadow
	rect(posX,posY-H,posX+L,posY,r,g,b)													#Main
	rect(posX+3,posY-19,posX+L-3,posY-2,.75*r,.75*g,.75*b)								#Titlebar
	line(posX+3,posY-19,posX+3,posY-2,.25,.25,.25)
	line(posX+4,posY-19,posX+4,posY-2,(r+.75)/4,(g+.75)/4,(b+.75)/4)
	line(posX+4,posY-2,posX+L-3,posY-2,(r+.75)/4,(g+.75)/4,(b+.75)/4)

##################################################################################################
#		Events
##################################################################################################
def event(evt,val):
	global i
	
	if evt==QKEY:
		Exit()

	if evt==TABKEY:
		i+=1
		if i%2==0:
			page.val=1-page.val
			Redraw()
	if evt==RKEY:
		i+=1
		if i%2==0:
			RepTypeMenu.val=(RepTypeMenu.val+1)%3
			Redraw()
	if evt==FKEY:
		i+=1							#The trick to avoid doubling of the call
		if i%2==0:						#same
			FallOff.val=(FallOff.val+1)%9
			MagnetFallOff.val=(MagnetFallOff.val+1)%9
			Redraw()	
	if evt==LKEY:
		page.val=0
		i+=1
		if i%2==0:
			bevent(150)
	if evt==SKEY:
		page.val=0
		i+=1
		if i%2==0:
			bevent(151)
	if evt==CKEY:
		i+=1
		if i%2==0:
			CursorRange.val=1-CursorRange.val
			Redraw(1)
	if evt==INSERTKEY:
		i+=1
		if i%2==0:
			bevent(83)
	if evt==DELKEY:
		i+=1
		if i%2==0:
			bevent(84)
	if evt==HOMEKEY:
		i+=1
		if i%2==0:
			bevent(103)
	if evt==ENDKEY:
		i+=1
		if i%2==0:
			bevent(104)
	if evt==PAGEUPKEY:
		i+=1
		if i%2==0:
			bevent(123)	
	if evt==PAGEDOWNKEY:
		i+=1
		if i%2==0:
			bevent(124)
	if evt==LEFTARROWKEY:
		i+=1
		if i%2==0:
			bevent(53)
	if evt==DOWNARROWKEY:
		i+=1
		if i%2==0:
			bevent(63)
	if evt==RIGHTARROWKEY:
		i+=1
		if i%2==0:
			bevent(73)
	if evt==UPARROWKEY:
		i+=1
		if i%2==0:
			bevent(1)
	if evt==DKEY:
		i+=1
		if i%2==0:
			DupliObj()
	if evt==HKEY:
		i+=1
		if i%2==0:
			Help()

def bevent(evt):
	global FactorLoc,FactorRot,FactorSize,RepStats,Stats,SurfStats,selObj,numSelObj,ChoiceOfStats,RotMagnetTo,RotMagnetUp


	if evt==1:	CopyMatMesh()
	if evt==2:	CopyMatObj()
	if evt==3:	GetRandomMat()
	if evt==4:	CreateRandomMat()
	if evt==5:	ModifyMat(MatFactor.val)

	if evt==50:	 CopyElement(('LocX',))
	if evt==51:	 CopyElement(('LocY',))
	if evt==52:	 CopyElement(('LocZ',))
	if evt==53:	 CopyElement(('LocX','LocY','LocZ'))
	if evt==54:	 CopyCorrectLocIPO()

	if evt==60:	 CopyElement(('RotX',))
	if evt==61:	 CopyElement(('RotY',))
	if evt==62:	 CopyElement(('RotZ',))
	if evt==63:	 CopyElement(('RotX','RotY','RotZ'))
	if evt==64:	 CopyCorrectRotIPO()

	if evt==70:	 CopyElement(('SizeX',))
	if evt==71:	 CopyElement(('SizeY',))
	if evt==72:	 CopyElement(('SizeZ',))
	if evt==73:	 CopyElement(('SizeX','SizeY','SizeZ'))
	if evt==74:	 CopyCorrectScaleIPO()

	if evt==79:
		MulLoc.val,AddLoc.val,ReplLoc.val=0,0,1
		Redraw()
	if evt==80:	 NewValLoc(('LocX',),NumberLocX.val,FactorLoc,FallOff.val)
	if evt==85:	 NewValLoc(('LocY',),NumberLocY.val,FactorLoc,FallOff.val)
	if evt==90:	 NewValLoc(('LocZ',),NumberLocZ.val,FactorLoc,FallOff.val)
	if evt==100:		NewValRot(('RotX',),NumberRotX.val*math.pi/180,FactorRot,FallOff.val)
	if evt==105:		NewValRot(('RotY',),NumberRotY.val*math.pi/180,FactorRot,FallOff.val)
	if evt==110:		NewValRot(('RotZ',),NumberRotZ.val*math.pi/180,FactorRot,FallOff.val)
	if evt==120:		NewValSize(('SizeX',),NumberSizeX.val,FactorSize,FallOff.val)
	if evt==125:		NewValSize(('SizeY',),NumberSizeY.val,FactorSize,FallOff.val)
	if evt==130:		NewValSize(('SizeZ',),NumberSizeZ.val,FactorSize,FallOff.val)

	if evt==82:	 ResetElement(('LocX',),0)
	if evt==87:	 ResetElement(('LocY',),0)
	if evt==92:	 ResetElement(('LocZ',),0)
	if evt==84:	 ResetElement(('LocX','LocY','LocZ'),0)
	if evt==102:		ResetElement(('RotX',),0)
	if evt==107:		ResetElement(('RotY',),0)
	if evt==112:		ResetElement(('RotZ',),0)
	if evt==104:		ResetElement(('RotX','RotY','RotZ'),0)
	if evt==122:		ResetElement(('SizeX',),1)
	if evt==127:		ResetElement(('SizeY',),1)
	if evt==132:		ResetElement(('SizeZ',),1)
	if evt==124:		ResetElement(('SizeX','SizeY','SizeZ'),1)

	if evt==81:	 RandLoc(('LocX',),AddLoc.val,MeanNumberLoc.val,RangeNumberLoc.val,CursorRange.val)
	if evt==86:	 RandLoc(('LocY',),AddLoc.val,MeanNumberLoc.val,RangeNumberLoc.val,CursorRange.val)
	if evt==91:	 RandLoc(('LocZ',),AddLoc.val,MeanNumberLoc.val,RangeNumberLoc.val,CursorRange.val)
	if evt==83:	 RandLoc(('LocX','LocY','LocZ'),AddLoc.val,MeanNumberLoc.val,RangeNumberLoc.val,CursorRange.val)
	if evt==101:		RandRot(('RotX',),AddRot.val,MeanNumberRot.val,RangeNumberRot.val)
	if evt==106:		RandRot(('RotY',),AddRot.val,MeanNumberRot.val,RangeNumberRot.val)
	if evt==111:		RandRot(('RotZ',),AddRot.val,MeanNumberRot.val,RangeNumberRot.val)
	if evt==103:		RandRot(('RotX','RotY','RotZ'),AddRot.val,MeanNumberRot.val,RangeNumberRot.val)
	if evt==121:		RandSca(('SizeX',),FactorSize,MeanNumberSize.val,RangeNumberSize.val)
	if evt==126:		RandSca(('SizeY',),FactorSize,MeanNumberSize.val,RangeNumberSize.val)
	if evt==131:		RandSca(('SizeZ',),FactorSize,MeanNumberSize.val,RangeNumberSize.val)
	if evt==123:		RandSca(('SizeX','SizeY','SizeZ'),FactorSize,MeanNumberSize.val,RangeNumberSize.val)

	if evt==88:
		if IntMimicLoc.val==1:			IntMimic('LocX','LocY')
		elif IntMimicLoc.val==2:			IntMimic('LocX','LocZ')
		elif IntMimicLoc.val==3:			IntMimic('LocY','LocX')
		elif IntMimicLoc.val==4:			IntMimic('LocY','LocZ')
		elif IntMimicLoc.val==5:			IntMimic('LocZ','LocX')
		elif IntMimicLoc.val==6:			IntMimic('LocZ','LocY')
		IntMimicLoc.val=0
		Redraw(1)
	if evt==108:
		if IntMimicRot.val==1:			IntMimic('RotX','RotY')
		elif IntMimicRot.val==2:			IntMimic('RotX','RotZ')
		elif IntMimicRot.val==3:			IntMimic('RotY','RotX')
		elif IntMimicRot.val==4:			IntMimic('RotY','RotZ')
		elif IntMimicRot.val==5:			IntMimic('RotZ','RotX')
		elif IntMimicRot.val==6:			IntMimic('RotZ','RotY')
		IntMimicRot.val=0
		Redraw(1)
	if evt==128:
		if IntMimicSize.val==1:			IntMimic('SizeX','SizeY')
		elif IntMimicSize.val==2:			IntMimic('SizeX','SizeZ')
		elif IntMimicSize.val==3:			IntMimic('SizeY','SizeX')
		elif IntMimicSize.val==4:			IntMimic('SizeY','SizeZ')
		elif IntMimicSize.val==5:			IntMimic('SizeZ','SizeX')
		elif IntMimicSize.val==6:			IntMimic('SizeZ','SizeY')
		IntMimicSize.val=0
		Redraw(1)


	if evt==500:
		Magnet(MagnetFallOff.val,MagnetPower.val)
	if evt==501:
		AntiMagnet(MagnetFallOff.val,MagnetPower.val)
	if evt==502:
		RotMagnet(MagnetFallOff.val,MagnetPower.val,Unique.val,Modulo.val)

	if evt==700:
		if UpX.val==1:
			UpX.val,UpY.val,RotMagnetUp=1-UpX.val,1,'y'
		if ToX.val==1:
			ToY.val=ToZ.val=TominX.val=TominY.val=TominZ.val=1-ToX.val
		else:
			TominX.val=1-ToX.val
		RotMagnetTo='x'
		Redraw(1)
	if evt==701:
		if UpY.val==1:
			UpY.val,UpZ.val,RotMagnetUp=1-UpY.val,1,'z'
		if ToY.val==1:
			ToX.val=ToZ.val=TominX.val=TominY.val=TominZ.val=1-ToY.val
		else:
			TominY.val=1-ToY.val
		RotMagnetTo='y'
		Redraw(1)
	if evt==702:
		if UpZ.val==1:
			UpZ.val,UpX.val,RotMagnetUp=1-UpZ.val,1,'x'
		if ToZ.val==1:
			ToX.val=ToY.val=TominX.val=TominY.val=TominZ.val=1-ToZ.val
		else:
			TominZ.val=1-ToZ.val
		RotMagnetTo='z'
		Redraw(1)
	if evt==703:
		if UpX.val==1:
			UpX.val,UpY.val,RotMagnetUp=1-UpX.val,1,'y'
		if TominX.val==1:
			ToX.val=ToY.val=ToZ.val=TominY.val=TominZ.val=1-TominX.val
		else:
			ToX.val=1-TominX.val
		RotMagnetTo='-x'
		Redraw(1)
	if evt==704:
		if UpY.val==1:
			UpY.val,UpZ.val,RotMagnetUp=1-UpY.val,1,'z'
		if TominY.val==1:
			ToX.val=ToY.val=ToZ.val=TominX.val=TominZ.val=1-TominY.val
		else:
			ToY.val=1-TominY.val
		RotMagnetTo='-y'
		Redraw(1)
	if evt==705:
		if UpZ.val==1:
			UpZ.val,UpX.val,RotMagnetUp=1-UpZ.val,1,'x'
		if TominZ.val==1:
			ToX.val=ToY.val=ToZ.val=TominX.val=TominY.val=1-TominZ.val
		else:
			ToZ.val=1-TominZ.val
		RotMagnetTo='-z'
		Redraw(1)
	if evt==706:
		if ToX.val==1 or TominX==1:
			ToX.val,TominX.val,ToY.val,RotMagnetTo=0,0,1,'y'
		if UpX.val==1:
			UpY.val=UpZ.val=1-UpX.val
		else:
			UpY.val=1-UpX.val
		RotMagnetUp='x'
		Redraw(1)
	if evt==707:
		if ToY.val==1 or TominY==1:
			ToY.val,TominY.val,ToZ.val,RotMagnetTo=0,0,1,'z'
		if UpY.val==1:
			UpX.val=UpZ.val=1-UpY.val
		else:
			UpZ.val=1-UpY.val
		RotMagnetUp='y'
		Redraw(1)
	if evt==708:
		if ToZ.val==1 or TominZ==1:
			ToZ.val,TominZ.val,ToX.val,RotMagnetTo=0,0,1,'x'
		if UpZ.val==1:
			UpX.val=UpY.val=1-UpZ.val
		else:
			UpX.val=1-UpZ.val
		RotMagnetUp='z'
		Redraw(1)



	if evt==94:
		if AddLoc.val==1:
			ReplLoc.val=MulLoc.val=1-AddLoc.val
		else:
			ReplLoc.val=1-AddLoc.val
		FactorLoc=1
		Redraw(1)
	if evt==95:
		if MulLoc.val==1:
			ReplLoc.val=AddLoc.val=1-MulLoc.val
		else:
			ReplLoc.val=1-MulLoc.val
		FactorLoc=2
		Redraw(1)
	if evt==96:
		if ReplLoc.val==1:
			AddLoc.val=MulLoc.val=1-ReplLoc.val
		else:
			MulLoc.val=1-ReplLoc.val
		FactorLoc=0
		Redraw(1)

	if evt==114:
		if AddRot.val==1:
			ReplRot.val=MulRot.val=1-AddRot.val
		else:
			ReplRot.val=1-AddRot.val
		FactorRot=1
		Redraw(1)
	if evt==115:
		if MulRot.val==1:
			ReplRot.val=AddRot.val=1-MulRot.val
		else:
			ReplRot.val=1-MulRot.val
		FactorRot=2
		Redraw(1)
	if evt==116:
		if ReplRot.val==1:
			AddRot.val=MulRot.val=1-ReplRot.val
		else:
			MulRot.val=1-ReplRot.val
		FactorRot=0
		Redraw(1)	

	if evt==134:
		if AddSize.val==1:
			ReplSize.val=MulSize.val=1-AddSize.val
		else:
			ReplSize.val=1-AddSize.val
		FactorSize=1
		Redraw(1)
	if evt==135:
		if MulSize.val==1:
			ReplSize.val=AddSize.val=1-MulSize.val
		else:
			ReplSize.val=1-MulSize.val
		FactorSize=2
		Redraw(1)
	if evt==136:
		if ReplSize.val==1:
			AddSize.val=MulSize.val=1-ReplSize.val
		else:
			MulSize.val=1-ReplSize.val
		FactorSize=0
		Redraw(1)

	if evt==150:
		selObj=Blender.Object.GetSelected()
		numSelObj=len(selObj)
		Stats=getDistStats()
		ChoiceOfStats=1
		Redraw(1)
	if evt==151:
		selObj=Blender.Object.GetSelected()
		numSelObj=len(selObj)
		SurfStats=getSurfStats()
		ChoiceOfStats=2
		Redraw(1)
	if evt==152:
		RepStats=getRepStats(ElementChoice.val)
		Redraw(1)

	if evt==25:
		DataMaterialSelect()
	if evt==26:
		ObjectMaterialSelect()
	if evt==261:
		ObjectTypeSelect()
	if evt==27:
		RandomSelect()
	if evt==28:
		DistanceSelectInf(selectDistance.val)
	if evt==29:
		DistanceSelectSup(selectDistance.val)

	if evt==800:
		if ShuffleX.val+ShuffleY.val+ShuffleZ.val==0:
			ShuffleY.val=1
		Redraw(1)
	if evt==801:
		if ShuffleX.val+ShuffleY.val+ShuffleZ.val==0:
			ShuffleZ.val=1
		Redraw(1)
	if evt==802:
		if ShuffleX.val+ShuffleY.val+ShuffleZ.val==0:
			ShuffleX.val=1
		Redraw(1)
	if evt==803:
		if ShuffleLoc.val+ShuffleRot.val+ShuffleSize.val==0:
			ShuffleRot.val=1
		Redraw(1)
	if evt==804:
		if ShuffleLoc.val+ShuffleRot.val+ShuffleSize.val==0:
			ShuffleSize.val=1
		Redraw(1)
	if evt==805:
		if ShuffleLoc.val+ShuffleRot.val+ShuffleSize.val==0:
			ShuffleLoc.val=1
		Redraw(1)	
	if evt==806:
		ShuffleIPO()
	if evt==811:
		ShuffleOtherIPO()
	
	if evt==98:
		Blender.Redraw()
	
	if evt==827:
		Animate(ToWhich.val,Span.val,FrameStart.val,FrameEnd.val,ExtType.val,InterType.val)
	if evt==862:
		BrownianMotion(FrameStart.val,FrameEnd.val,BrownPer.val,BrownReg.val,BrownStr.val)
	Blender.Redraw()
##################################################################################################
#	 GUI
##################################################################################################
def Help():
	block=[]

	block.append("           Sortcuts:")
	block.append("Distances: L    Surfaces:S")
	block.append("Duplicate: D")
	block.append("Swap repartition type: R")
	block.append("Swap fall-Off type: F")
	block.append("Cursor Stretch: C")
	block.append("")
	block.append("           Links:")

	block.append("")	
	block.append("Randomize Loc Rot Scale :")
	block.append("Reset Loc Rot Scale :")
	block.append("Mimic Loc Rot Scale :")
	block.append("")
	block.append("")
	block.append("")
	block.append(" Full documentation available")
			
	block.append("")
	block.append("Ins.  Home  PageUp")
	block.append("Del.  End   PageDown")
	block.append("Left  Down  Right")
	block.append("")
	block.append("")
	block.append("")
	block.append("from Blenderartists.org")

	helpPup=PupBlock('Shortcuts and links',block)
	
def GUI():
	global page
#	global Stats,RepStats,numSelObj,distSum,distMean,distStdDev,NumberExample
	glClearColor(.80,.80,.78,1)#(.71,.7,.66,1)
	glClear(GL_COLOR_BUFFER_BIT)
	page=Menu('Page %t|Statics %x0|Animation %x1',0,200,440,180,32,page.val,'Choose the panels you display')

	if (page.val==0):
		drawTitle(7,456),drawAssign(5,434),drawMagnetic(5,156),drawFunction(5,50),drawMimic(197,88),drawStatistics(197,433),drawMaterials(197,191),drawSelection(197,256)
#		Window.RedrawAll()
	elif (page.val==1):
		drawTitle(7,456),drawAssign(5,434),drawMagnetic(5,156),drawFunction(5,50),drawAnimation(197,433),drawMimic(197,88),drawMaterials(197,191),drawSelection(197,256)


# # # # # Title # # # # # # # #
def drawTitle(X,Y):
	posX8,posY8=X,Y
	glColor3f(.6,.6,.6)
	glRasterPos2i(posX8+2,posY8-2)
	Text("Gwen's Big Numbers Toolkit 1.12")
	glColor3f(0,0,0)
	glRasterPos2i(posX8,posY8)#199,428
	Text("Gwen's Big Numbers Toolkit 1.12")
	glColor3f(.6,.6,.6)
	glRasterPos2i(posX8+17,posY8-16)
	Text("Press H for a list of shortcuts",'small')
	glColor3f(0,0,0)
	glRasterPos2i(posX8+16,posY8-15)
	Text("Press H for a list of shortcuts",'small')
	
	
# # # # # Mimic Window # # # # #
def drawMimic(X,Y):
	posX,posY,L,H=X,Y,184,81
	r,g,b=.48,.47,.51
	panel(posX,posY,L,H,r,g,b)
	
	Title='Mimic active object'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r/3,g/3,b/3)
	glRasterPos2i(posX+5+(L-6-TitleWidth)/2,posY-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX+3+(L-6-TitleWidth)/2,posY-13)
	Text(Title)

	posBX,posBY=posX+58,posY-40

	line(posBX+66,posY-21,posBX+66,posY-H+2,(.5+r)/1.5,(.5+g)/1.5,(.5+b)/1.5)

	glColor3f(.88*r,.88*g,.88*b)
	glRasterPos2i(posX+7,posBY+2)
	Text("Location:")
	glColor3f(0,0,0)
	glRasterPos2i(posX+5,posBY+4)
	Text("Location:")
	BeginAlign()
	Button("X",50,posBX,posBY+1,15,14,"Copy X location")
	Button("Y",51,posBX+15,posBY+1,13,14,"Copy Y location")
	Button("Z",52,posBX+28,posBY+1,16,14,"Copy Z location")
	EndAlign()
	Button("G",53,posBX+47,posBY+1,16,14,"Copy X,Y and Z location simultaneously. Shortcut: LeftArrowKey")
	BeginAlign()
	Button("IPO",54,posBX+70,posBY+1,27,14,"Copy the active object's location IPO curves. Takes present value into account though")
#	Button(">d",55,posBX+97,posBY+1,25,14,"Convert the selection's absolute location IPO curves into relative location IPOs")
	EndAlign()

	glColor3f(.88*r,.88*g,.88*b)
	glRasterPos2i(posX+7,posBY-16)
	Text("Rotation:")
	glColor3f(0,0,0)
	glRasterPos2i(posX+5,posBY-14)
	Text("Rotation:")
	BeginAlign()
	Button("X",60,posBX,posBY-17,15,14,"Copy X rotation")
	Button("Y",61,posBX+15,posBY-17,13,14,"Copy Y rotation")
	Button("Z",62,posBX+28,posBY-17,16,14,"Copy Z rotation")
	EndAlign()
	Button("G",63,posBX+47,posBY-17,16,14,"Copy X,Y and Z rotation simultaneously. Shortcut: DownArrowKey")
	BeginAlign()
	Button("IPO",64,posBX+70,posBY-17,27,14,"Copy the active object's rotation IPO curves. Takes present value into account though")
#	Button(">d",65,posBX+97,posBY-17,25,14,"Convert the selection's absolute rotation IPO curves into relative rotation IPOs")
	EndAlign()

	glColor3f(.88*r,.88*g,.88*b)
	glRasterPos2i(posX+7,posBY-34)
	Text("Scale:")
	glColor3f(0,0,0)
	glRasterPos2i(posX+5,posBY-32)
	Text("Scale:")
	BeginAlign()
	Button("X",70,posBX,posBY-35,15,14,"Copy X scale")
	Button("Y",71,posBX+15,posBY-35,13,14,"Copy Y scale")
	Button("Z",72,posBX+28,posBY-35,16,14,"Copy Z scale")
	EndAlign()
	Button("G",73,posBX+47,posBY-35,16,14,"Copy X,Y and Z scale simultaneously. Shortcut: RightArrowKey")
	BeginAlign()
	Button("IPO",74,posBX+70,posBY-35,27,14,"Copy the active object's scale IPO curves. Takes present value into account though")
#	Button(">d",75,posBX+97,posBY-35,25,14,"Convert the selection's absolute scale IPO curves into relative scale IPOs")
	EndAlign()



# # # # # Assign Window # # # # #
def drawAssign(X,Y):
	global NumberLocX,NumberLocY,NumberLocZ,RangeNumberLoc,MeanNumberLoc,NumberRotX,NumberRotY,NumberRotZ,RangeNumberRot,MeanNumberRot,NumberSizeX,NumberSizeY,NumberSizeZ,RangeNumberSize,MeanNumberSize
	global AddLoc,MulLoc,ReplLoc,AddRot,MulRot,ReplRot,AddSize,MulSize,ReplSize,RepTypeMenu,FallOff
	global IntMimicLoc,IntMimicRot,IntMimicSize,CursorRange,LocalRot

	posX2,posY2,L2,H2=X,Y,184,271
	r2,g2,b2=.71,.58,.43
	
	panel(posX2,posY2,L2,H2,r2,g2,b2)

	Title='Assign new values'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r2/3,g2/3,b2/3)
	glRasterPos2i(posX2+5+(L2-6-TitleWidth)/2,posY2-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX2+3+(L2-6-TitleWidth)/2,posY2-13)
	Text(Title)
	
	posBX2,posBY2=posX2+4,posY2-54

	glColor3f(.88*r2,.88*g2,.88*b2)
	glRasterPos2i(posBX2+7,posBY2+18)
	Text("Location:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX2+5,posBY2+20)
	Text("Location:")

	BeginAlign()
	GlobLocRd=Button("?",83,posBX2+69,posBY2+17,16,14,"Set random value for X, Y and Z location. Shortcut: Insert")
	GlobLocRst=Button("0",84,posBX2+85,posBY2+17,17,14,"Reset location to Origin. Shortcut: Delete")
	EndAlign()
	CursorRange=Toggle("C.",79,posBX2,posBY2,16,14,CursorRange.val,"Use cursor position to set range and mean value. Shortcut: C")	
	IntMimicLoc=Menu("Intern mimic %t|?=? %x0|X=Y %x1|X=Z %x2|Y=X %x3|Y=Z %x4|Z=X %x5|Z=Y %x6",88,posBX2+20,posBY2,45,14,IntMimicLoc.val,"Copy one coordinate value to another")
	NumberLocX=Number("X:",80,posBX2+106,posBY2,72,14,NumberLocX.val,-100.,100.,"Assign new LocX value")
	BeginAlign()
	LocXRd=Button("?",81,posBX2+69,posBY2,16,14,"Set random value for LocX")
	LocXRst=Button("0",82,posBX2+85,posBY2,17,14,"Reset LocX to 0")
	EndAlign()
	NumberLocY=Number("Y:",85,posBX2+106,posBY2-16,72,14,NumberLocY.val,-100.,100.,"Assign new LocY value")
	BeginAlign()
	LocYRd=Button("?",86,posBX2+69,posBY2-16,16,14,"Set random value for LocY")
	LocYRst=Button("0",87,posBX2+85,posBY2-16,17,14,"Reset LocY to 0")
	EndAlign()
	NumberLocZ=Number("Z:",90,posBX2+106,posBY2-32,72,14,NumberLocZ.val,-100.,100.,"Assign new LocZ value")
	BeginAlign()
	LocZRd=Button("?",91,posBX2+69,posBY2-32,16,14,"Set random value for LocZ")
	LocZRst=Button("0",92,posBX2+85,posBY2-32,17,14,"Reset LocZ to 0")
	EndAlign()
	BeginAlign()
	ReplLoc=Toggle("R.",96,posBX2+106,posBY2+17,25,14,ReplLoc.val,"Replace existing values") 
	MulLoc=Toggle("M.",95,posBX2+131,posBY2+17,22,14,MulLoc.val,"Multiply new values to existing ones")
	AddLoc=Toggle("A.",94,posBX2+153,posBY2+17,25,14,AddLoc.val,"Add new values to existing ones")
	EndAlign()

	RangeNumberLoc=Number("R",97,posBX2,posBY2-16,65,14,RangeNumberLoc.val,-100.,100.,"Specify Range or sigma value")
	MeanNumberLoc=Number("M",98,posBX2,posBY2-32,65,14,MeanNumberLoc.val,-100.,100.,"Specify Mean or mu value")

	line(posX2+2,posBY2-35,posX2+L2-2,posBY2-35,(.5+r2)/1.5,(.5+g2)/1.5,(.5+b2)/1.5)

	posBY2=posBY2-70

	glColor3f(.88*r2,.88*g2,.88*b2)
	glRasterPos2i(posBX2+7,posBY2+18)
	Text("Rotation:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX2+5,posBY2+20)
	Text("Rotation:")

	BeginAlign()
	GlobRotRd=Button("?",103,posBX2+69,posBY2+17,16,14,"Set random value for X,Y and Z rotation. Shortcut: Home")
	GlobRotRst=Button("0",104,posBX2+85,posBY2+17,17,14,"Reset RotX, RotY and RotZ to 0. Shortcut: End")
	EndAlign()
	LocalRot=Toggle("L.",99,posBX2,posBY2,16,14,LocalRot.val,"Rotations take place around local axis. Shortcut: L")	
	IntMimicRot=Menu("Intern mimic %t|?=? %x0|X=Y %x1|X=Z %x2|Y=X %x3|Y=Z %x4|Z=X %x5|Z=Y %x6",108,posBX2+20,posBY2,45,14,IntMimicRot.val,"Copy one rotation value to another")
	NumberRotX=Number("X:",100,posBX2+106,posBY2,72,14,NumberRotX.val,-180,180,"Assign new RotX value")
	BeginAlign()
	RotXRd=Button("?",101,posBX2+69,posBY2,16,14,"Set random value for RotX")
	RotXRst=Button("0",102,posBX2+85,posBY2,17,14,"Reset RotX to 0")
	EndAlign()
	NumberRotY=Number("Y:",105,posBX2+106,posBY2-16,72,14,NumberRotY.val,-180,180,"Assign new RotY value")
	BeginAlign()
	RotYRd=Button("?",106,posBX2+69,posBY2-16,16,14,"Set random value for RotY")
	RotYRst=Button("0",107,posBX2+85,posBY2-16,17,14,"Reset RotY to 0")
	EndAlign()
	NumberRotZ=Number("Z:",110,posBX2+106,posBY2-32,72,14,NumberRotZ.val,-180,180,"Assign new RotZ value")
	BeginAlign()
	RotZRd=Button("?",111,posBX2+69,posBY2-32,16,14,"Set random value for RotZ")
	RotZRst=Button("0",112,posBX2+85,posBY2-32,17,14,"Reset RotZ to 0")
	EndAlign()
	BeginAlign()
	ReplRot=Toggle("R.",116,posBX2+106,posBY2+17,25,14,ReplRot.val,"Replace existing values")
	MulRot=Toggle("M.",115,posBX2+131,posBY2+17,22,14,MulRot.val,"Multiply new values to existing ones")
	AddRot=Toggle("A.",114,posBX2+153,posBY2+17,25,14,AddRot.val,"Add new values to existing ones")
	EndAlign()
	RangeNumberRot=Number("R",117,posBX2,posBY2-16,65,14,RangeNumberRot.val,-360,360,"Specify Range or sigma value")
	MeanNumberRot=Number("M",118,posBX2,posBY2-32,65,14,MeanNumberRot.val,-180.,180.,"Specify Mean or mu value")
	
	line(posX2+2,posBY2-35,posX2+L2-2,posBY2-35,(.5+r2)/1.5,(.5+g2)/1.5,(.5+b2)/1.5)

	posBY2=posBY2-70

	glColor3f(.88*r2,.88*g2,.88*b2)
	glRasterPos2i(posBX2+7,posBY2+18) 
	Text("Scale:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX2+5,posBY2+20)
	Text("Scale:")

	BeginAlign()
	GlobSizeRd=Button("?",123,posBX2+69,posBY2+17,16,14,"Set random value for X,Y and Z scale. Shortcut: PageUp")
	GlobSizeRst=Button("1",124,posBX2+85,posBY2+17,17,14,"Reset ScaleX, ScaleY and ScaleZ to 1. Shortcut: PageDown")
	EndAlign()
	IntMimicSize=Menu("Intern mimic %t|?=? %x0|X=Y %x1|X=Z %x2|Y=X %x3|Y=Z %x4|Z=X %x5|Z=Y %x6",128,posBX2+20,posBY2,45,14,IntMimicSize.val,"Copy one scale value to another")
	NumberSizeX=Number("X:",120,posBX2+106,posBY2,72,14,NumberSizeX.val,-100.,100.,"Assign new ScaleX value")
	BeginAlign()
	SizeXRd=Button("?",121,posBX2+69,posBY2,16,14,"Set random value for scaleX")
	SizeXRst=Button("1",122,posBX2+85,posBY2,17,14,"Reset scaleX to 1")
	EndAlign()
	NumberSizeY=Number("Y:",125,posBX2+106,posBY2-16,72,14,NumberSizeY.val,-100.,100.,"Assign new ScaleY value")
	BeginAlign()
	SizeYRd=Button("?",126,posBX2+69,posBY2-16,15,14,"Set random value for scaleY")
	SizeYRst=Button("1",127,posBX2+85,posBY2-16,17,14,"Reset scaleY to 1")
	EndAlign()
	NumberSizeZ=Number("Z:",130,posBX2+106,posBY2-32,72,14,NumberSizeZ.val,-100.,100.,"Assign new ScaleZ value")
	BeginAlign()
	SizeZRd=Button("?",131,posBX2+69,posBY2-32,16,14,"Set random value for scaleZ")
	SizeZRst=Button("1",132,posBX2+85,posBY2-32,17,14,"Reset scaleZ to 1")
	EndAlign()
	BeginAlign()
	ReplSize=Toggle("R.",136,posBX2+106,posBY2+17,25,14,ReplSize.val,"Replace existing values")
	MulSize=Toggle("M.",135,posBX2+131,posBY2+17,22,14,MulSize.val,"Multiply new values to existing ones")
	AddSize=Toggle("A.",134,posBX2+153,posBY2+17,25,14,AddSize.val,"Add new values to existing ones")
	EndAlign()
	RangeNumberSize=Number("R",137,posBX2,posBY2-16,65,14,RangeNumberSize.val,-100.,100.,"Specify Range or sigma value")
	MeanNumberSize=Number("M",138,posBX2,posBY2-32,65,14,MeanNumberSize.val,-100.,100.,"Specify Mean or mu value")

	line(posX2+2,posBY2-36,posX2+L2-2,posBY2-36,(.5+r2)/1.5,(.5+g2)/1.5,(.5+b2)/1.5)

	glColor3f(.88*r2,.88*g2,.88*b2)
	glRasterPos2i(posX2+6,posY2-H2+8)
	Text("Fall-off Type :")
	glColor3f(0,0,0)
	glRasterPos2i(posX2+4,posY2-H2+10)
	Text("Fall-off Type :")
	FallOff=Menu("Fall-off type %t|No fall-off %x0|Linear %x1|Inverse linear %x2|Round %x3|Sharp %x4|Bell %x5|Torus %x6|Damped sine %x7|Input %x8",140,posBX2+83,posY2-H2+5,92,15,FallOff.val,"Choose fall-off Type for randomization. Press F to cycle through the possibilities")

	glColor3f(.88*r2,.88*g2,.88*b2)
	glRasterPos2i(posX2+6,posY2-H2+24)
	Text("Repartion Type :")
	glColor3f(0,0,0)
	glRasterPos2i(posX2+4,posY2-H2+26)
	Text("Repartion Type :")		
	RepTypeMenu=Menu("Repartition Type %t|Random %x0|Gaussian %x1|Regular %x2",141,posBX2+100,posY2-H2+22,75,15,RepTypeMenu.val,"Choose the repartition type of the randomize tools")


# # # # # Statistics Window # # # # #
def drawStatistics(X,Y):
	global ElementChoice
	posX3,posY3,L3,H3=X,Y,184,170
	r3,g3,b3=.49,.51,.52
	panel(posX3,posY3,L3,H3,r3,g3,b3)

	Title='Statistics'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r3/3,g3/3,b3/3)
	glRasterPos2i(posX3+5+(L3-6-TitleWidth)/2,posY3-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX3+3+(L3-6-TitleWidth)/2,posY3-13)
	Text(Title)

	posBX3,posBY3=posX3+5,posY3-102

	a,Q1,Q2=0,posX3+L3-50,posY3-35
	while a<5:
		rect(Q1+1,Q2-1,Q1+45,Q2+9,.8*r3,.8*g3,.8*b3)
		rect(Q1,Q2,Q1+44,Q2+10,(.5+r3)/1.5,(.5+g3)/1.5,(.5+b3)/1.5)	 
		a,Q2=a+1,Q2-12

	glColor3f(0,0,0)

	if ChoiceOfStats==0:
		glRasterPos2i(posX3+5,posBY3+69)
		Text("The surface utility presents",'small')
		glRasterPos2i(posX3+5,posBY3+57)
		Text(" certain restrictions:",'small')
		glRasterPos2i(posX3+5,posBY3+45)
		Text(" use mesh objects only and",'small')
		glRasterPos2i(posX3+5,posBY3+33)
		Text(" apply scale and rotation",'small')
		glRasterPos2i(posX3+5,posBY3+21)
		Text(" whenever possible.",'small')
	elif ChoiceOfStats==1:
		if numSelObj==0:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("No selected object.",'small')
#		if numSelObj!=0:
#			glRasterPos2i(posX3+5,posBY3+69)
#			Text("Number of selected objects:",'small')
#			glRasterPos2i(posX3+140,posBY3+69)
#			Text(str(Stats[0]),'small')
		if numSelObj==1:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("Distance to 3D cursor:",'small')
			glRasterPos2i(posX3+140,posBY3+69)
			Text(str(round(Stats[1],3)),'small')
		elif numSelObj==2:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("Distance:",'small')
			glRasterPos2i(posX3+140,posBY3+69)
			Text(str(round(Stats[1],3)),'small')
		elif numSelObj>2:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("Minimum distance:",'small')
			glRasterPos2i(posX3+140,posBY3+69)
			Text(str(round(Stats[5],3)),'small')
			glRasterPos2i(posX3+5,posBY3+57)
			Text("Maximum distance:",'small')
			glRasterPos2i(posX3+140,posBY3+57)
			Text(str(round(Stats[4],3)),'small')
			glRasterPos2i(posX3+5,posBY3+45)
			Text("Mean distance:",'small')
			glRasterPos2i(posX3+140,posBY3+45)
			Text(str(round(Stats[2],3)),'small')
			glRasterPos2i(posX3+5,posBY3+33)
			Text("Standard deviation:",'small')
			glRasterPos2i(posX3+140,posBY3+33)
			Text(str(round(Stats[3],3)),'small')

	elif ChoiceOfStats==2:
		if numSelObj==0:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("No selected object.",'small')
		elif numSelObj==1:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("Surface:",'small')
			glRasterPos2i(posX3+140,posBY3+69)
			Text(str(round(SurfStats[4],2)),'small')			
		else:
			glRasterPos2i(posX3+5,posBY3+69)
			Text("Minimum surface:",'small')
			glRasterPos2i(posX3+140,posBY3+68)
			Text(str(round(SurfStats[0],3)),'small')
			glRasterPos2i(posX3+5,posBY3+57)
			Text("Maximum surface:",'small')
			glRasterPos2i(posX3+140,posBY3+57)
			Text(str(round(SurfStats[1],3)),'small')
			glRasterPos2i(posX3+5,posBY3+45)
			Text("Mean surface",'small')
			glRasterPos2i(posX3+140,posBY3+45)
			Text(str(round(SurfStats[2],3)),'small')
			glRasterPos2i(posX3+5,posBY3+33)
			Text("Standard deviation:",'small')
			glRasterPos2i(posX3+140,posBY3+33)
			Text(str(round(SurfStats[3],3)),'small')
			glRasterPos2i(posX3+5,posBY3+21)
			Text("Total surface:",'small')
			glRasterPos2i(posX3+140,posBY3+21)
			Text(str(round(SurfStats[4],2)),'small')

	posBY3-=7

	line(posX3+2,posY3-113,posX3+90,posY3-113,(.5+r3)/1.5,(.5+g3)/1.5,(.5+b3)/1.5)
	line(posX3+90,posY3-113,posX3+L3-60,posY3-93,(.5+r3)/1.5,(.5+g3)/1.5,(.5+b3)/1.5)
	line(posX3+L3-60,posY3-93,posX3+L3-2,posY3-93,(.5+r3)/1.5,(.5+g3)/1.5,(.5+b3)/1.5)
	BeginAlign()
	Button("Dists.",150,posBX3+2,posBY3,40,14,"Recalculates statistical data: distances between the selected objects. Shortcut: L")
	Button("Surfs.",151,posBX3+42,posBY3,40,14,"Recalculates statistical data: areas of the selected objects. Shortcut: S")
	EndAlign()
	ElementChoice=Menu("Data Group %t|Loc %x0|Rot %x1|Size %x2",152,posBX3+125,posBY3-3,50,15,ElementChoice.val,"Choose the type of data to be analysed")

	glRasterPos2i(posX3+25,posY3-125)
	Text("Min:	 Max:	 Mean:	StdDev:",'small')
	a,Q1,Q2=0,posX3+17,posBY3-30
	while a<3:
		b,Q1=0,posX3+17
		while b<4:
			rect(Q1+1,Q2-1,Q1+39,Q2+9,.8*r3,.8*g3,.8*b3)
			rect(Q1,Q2,Q1+38,Q2+10,(.5+r3)/1.5,(.5+g3)/1.5,(.5+b3)/1.5)	 
			Q1=Q1+42
			b=b+1
		a,Q2=a+1,Q2-13

	glColor3f(0,0,0)
	glRasterPos2i(posX3+3,posBY3-28)
	Text("X:",'small')
	glRasterPos2i(posX3+18,posBY3-28)
	Text(str(round(RepStats[0],2)),'small')
	glRasterPos2i(posX3+60,posBY3-28)
	Text(str(round(RepStats[1],2)),'small')
	glRasterPos2i(posX3+102,posBY3-28)
	Text(str(round(RepStats[2],2)),'small')
	glRasterPos2i(posX3+144,posBY3-28)
	Text(str(round(RepStats[3],2)),'small')
			
	glRasterPos2i(posX3+3,posBY3-41)
	Text("Y:",'small')
	glRasterPos2i(posX3+18,posBY3-41)
	Text(str(round(RepStats[4],2)),'small')
	glRasterPos2i(posX3+60,posBY3-41)
	Text(str(round(RepStats[5],2)),'small')
	glRasterPos2i(posX3+102,posBY3-41)
	Text(str(round(RepStats[6],2)),'small')
	glRasterPos2i(posX3+144,posBY3-41)
	Text(str(round(RepStats[7],2)),'small')

	glRasterPos2i(posX3+3,posBY3-54)
	Text("Z:",'small')
	glRasterPos2i(posX3+18,posBY3-54)
	Text(str(round(RepStats[8],2)),'small')
	glRasterPos2i(posX3+60,posBY3-54)
	Text(str(round(RepStats[9],2)),'small')
	glRasterPos2i(posX3+102,posBY3-54)
	Text(str(round(RepStats[10],2)),'small')
	glRasterPos2i(posX3+144,posBY3-54)
	Text(str(round(RepStats[11],2)),'small')

# # # # # Materials Window # # # # #
def drawMaterials(X,Y):
	global colTog,mirColTog,speColTog,alpTog,specTog,hardTog,refTog,emitTog,mirTog,traTog,MatFactor
	posX4,posY4,L4,H4=X,Y,184,96
	r4,g4,b4=.45,.5,.6
	panel(posX4,posY4,L4,H4,r4,g4,b4)

	Title='Materials'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r4/3,g4/3,b4/3)
	glRasterPos2i(posX4+5+(L4-6-TitleWidth)/2,posY4-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX4+3+(L4-6-TitleWidth)/2,posY4-13)
	Text(Title)

	posBX4,posBY4=posX4+4,posY4-38

	line(posBX4+37,posY4-21,posBX4+37,posY4-H4+2,(.5+r4)/1.5,(.5+g4)/1.5,(.5+b4)/1.5)

	BeginAlign()
	Button('Data',1,posBX4,posBY4-27,34,21,"Copy the data-related materials from the active object to the selected object's data. Shortcut: UpArrowKey")
	Button('Obj.',2,posBX4,posBY4-48,34,21,"Copy the object-related materials from the active object to the selected objects")
	EndAlign()
	glColor3f(.88*r4,.88*g4,.88*b4)
	glRasterPos2i(posBX4+4,posBY4+2) 
	Text("Copy:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX4+2,posBY4+4)
	Text("Copy:")

	BeginAlign()
	Button('Get',3,posBX4+92,posBY4,25,14,'Randomly select a material from the available materials in the scene')
	Button('New',4,posBX4+117,posBY4,29,14,'Create new random materials. Amount is entered in the Number field next')
	Button('Mod',5,posBX4+146,posBY4,31,14,'Randomly modifies existing materials. Use the toggles below to select which values will be modified')
	EndAlign
	glColor3f(.88*r4,.88*g4,.88*b4)
	glRasterPos2i(posBX4+44,posBY4+2) 
	Text("Random:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX4+42,posBY4+4)
	Text("Random:")

	BeginAlign()
	colTog=Toggle('Col',10,posBX4+40,posBY4-20,27,14,colTog.val,'Enable the color setting to be modified. If disabled, the "new" button creates a grey material with values .8,.8,.8')	
	refTog=Toggle('Ref',11,posBX4+66,posBY4-20,26,14,traTog.val,'Enable the reflection setting to be modified. If disabled, the "new" button creates a material with a reflection value of 0.80')
	specTog=Toggle('Spec',12,posBX4+92,posBY4-20,26,14,specTog.val,'Enable the specularity setting to be modified. If disabled, the "new" button creates a material with a specularity of 0.80')	
	hardTog=Toggle('Hrd',13,posBX4+118,posBY4-20,25,14,hardTog.val,'Enable the hardness setting to be modified. If disabled, the "new" button creates a material with a hardness value of 0.80')	
	speColTog=Toggle('SpeC',14,posBX4+143,posBY4-20,34,14,speColTog.val,'Enable the specular color setting to be modified. If disabled, the "new" button creates a material with white specular color')
	emitTog=Toggle('Emit',15,posBX4+40,posBY4-34,27,14,emitTog.val,'Enable the emit setting to be modified. If disabled, the "new" button creates a non-emitting material')	
	alpTog=Toggle('Alp',16,posBX4+66,posBY4-34,26,14,alpTog.val,'Enable the alpah setting to be modified. If disabled, the "new" button creates an opaque material ')	
	mirTog=Toggle('Mir',17,posBX4+92,posBY4-34,26,14,mirTog.val,'Enable the Ray Mirror settings to be modified. If disabled, the "new" button creates a material with "Mirror" left off')	
	traTog=Toggle('Tra',18,posBX4+118,posBY4-34,25,14,traTog.val,'Enable the Ray Transparency settings to be modified. If disabled, the "new" button creates a material without transparency')
	mirColTog=Toggle('MirC',19,posBX4+143,posBY4-34,34,14,mirColTog.val,'Enable the mirror color setting to be modified. If disabled, the "new" button creates a material with white mirror color')
	EndAlign()

	glColor3f(.88*r4,.88*g4,.88*b4)
	glRasterPos2i(posBX4+44,posY4-H4+7) 
	Text("Rand.factor:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX4+42,posY4-H4+9)
	Text("Rand. factor:")
	MatFactor=Number('',20,posBX4+120,posY4-H4+5,50,14,MatFactor.val,0,100,"Specify the amount of randomness for the modification of parameters.")

# # # # # Selection Window # # # # #
def drawSelection(X,Y):
	global selectDistance,selectBy
	posX5,posY5,L5,H5=X,Y,184,58
	r5,g5,b5=.57,.58,.5
	panel(posX5,posY5,L5,H5,r5,g5,b5)

	Title='Selection'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r5/3,g5/3,b5/3)
	glRasterPos2i(posX5+5+(L5-6-TitleWidth)/2,posY5-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX5+3+(L5-6-TitleWidth)/2,posY5-13)
	Text(Title)

	posBX5,posBY5=posX5+4,posY5-37

	selectBy=Menu("How do you select ? %t|Type %x0|Material %x1",505,posBX5,posBY5+2,60,15,selectBy.val,"Toggle between the selection modes. Either by material, or by type.")

	if selectBy.val==1:
		BeginAlign()
		Button('Data',25,posBX5,posBY5-17,30,14,"Select all objects which data shares at least one of the active's data materials.")		
		Button('Obj.',26,posBX5+30,posBY5-17,30,14,"Select all objects that share at least one of the active's materials.")		
		EndAlign()
	else:
		Button('Sel. same',261,posBX5,posBY5-17,60,14,"Select all objects with the same type as the selected object")

	line(posBX5+64,posY5-21,posBX5+64,posY5-H5+2,(.5+r5)/1.5,(.5+g5)/1.5,(.5+b5)/1.5)

	glColor3f(.88*r5,.88*g5,.88*b5)
	glRasterPos2i(posBX5+74,posBY5+2) 
	Text("Objects:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX5+72,posBY5+4) 
	Text("Objects:")

	Button('Rand.',27,posBX5+68,posBY5-17,50,14,"Randomly selects objects in the scene, among selected ones if there are some")

	selectDistance=Number("",506,posBX5+126,posBY5,50,14,selectDistance.val,-100.,100.,"Specify the distance threshold")	
	BeginAlign()
	Button('<',28,posBX5+126,posBY5-17,25,14,"Selects objects which distance to the 3D cursor is less than set above")
	Button('>',29,posBX5+151,posBY5-17,25,14,"Selects objects which distance to the 3D cursor is superior than set above")
	EndAlign()

# # # # # Magnetic Window # # # # #
def drawMagnetic(X,Y):
	global ToX,ToY,ToZ,TominX,TominY,TominZ,UpX,UpY,UpZ,Unique,Modulo,MagnetPower,MagnetFallOff
	posX6,posY6,L6,H6=X,Y,184,99
	r6,g6,b6=.6,.4,.4
	panel(posX6,posY6,L6,H6,r6,g6,b6)

	Title='Magnetics'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r6/3,g6/3,b6/3)
	glRasterPos2i(posX6+5+(L6-6-TitleWidth)/2,posY6-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX6+3+(L6-6-TitleWidth)/2,posY6-13)
	Text(Title)
	
	posBX6,posBY6=posX6+4,posY6-36
	
	glColor3f(.88*r6,.88*g6,.88*b6)
	glRasterPos2i(posBX6+7,posBY6+1)
	Text("Location:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX6+5,posBY6+3)
	Text("Location:")

	BeginAlign()
	Button('Magnet',500,posBX6+73,posBY6,53,15,"Move the selected objects toward the 3D Cursor depending on their distance to it")
	Button('AntiM',501,posBX6+126,posBY6,47,15,"Move the selected objects away the 3D Cursor depending on their distance to it")
	EndAlign()

	line(posX6+2,posBY6-3,posX6+L6-2,posBY6-3,(.5+r6)/1.5,(.5+g6)/1.5,(.5+b6)/1.5)

	posBX6,posBY6=posBX6,posBY6-38

	glColor3f(.88*r6,.88*g6,.88*b6)
	glRasterPos2i(posBX6+7,posBY6+18)
	Text("Rotation:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX6+5,posBY6+20)
	Text("Rotation:")

	BeginAlign()
	Unique=Toggle('1',499,posBX6+130,posBY6+17,15,14,Unique.val,'Objects are rotated around just one of the 3 axis')
	Modulo=Toggle('Mod',498,posBX6+145,posBY6+17,30,14,Modulo.val,"Doesn't 'unwind' the object fully if this one has several turns, just so that it looks right")
	EndAlign()

	Button('Magnet',502,posBX6+73,posBY6+17,53,15,"Move the selected objects toward the 3D Cursor depending on their distance to it")

	BeginAlign()
	ToX=Toggle('X',700,posBX6,posBY6,15,14,ToX.val,'Objects are rotated solely around their X axis')
	ToY=Toggle('Y',701,posBX6+15,posBY6,15,14,ToY.val,'Objects are rotated solely around their Y axis')
	ToZ=Toggle('Z',702,posBX6+30,posBY6,15,14,ToZ.val,'Objects are rotated solely around their Z axis')
	TominX=Toggle('-X',703,posBX6+44,posBY6,21,14,TominX.val,'Objects are rotated solely around the viewing angle')
	TominY=Toggle('-Y',704,posBX6+62,posBY6,21,14,TominY.val,'Objects are rotated solely around their Z axis')
	TominZ=Toggle('-Z',705,posBX6+83,posBY6,23,14,TominZ.val,'Objects are rotated solely around the viewing angle')
	EndAlign()

	glColor3f(.88*r6,.88*g6,.88*b6)
	glRasterPos2i(posBX6+113,posBY6+1)
	Text("Up:")
	glColor3f(0,0,0)
	glRasterPos2i(posBX6+111,posBY6+3)
	Text("Up:")

	BeginAlign()
	UpX=Toggle('X',706,posBX6+130,posBY6,15,14,UpX.val,'Objects are rotated solely around their X axis')
	UpY=Toggle('Y',707,posBX6+145,posBY6,15,14,UpY.val,'Objects are rotated solely around their Y axis')
	UpZ=Toggle('Z',708,posBX6+160,posBY6,15,14,UpZ.val,'Objects are rotated solely around their Z axis')
	EndAlign()

	line(posX6+2,posBY6-3,posX6+L6-2,posBY6-3,(.5+r6)/1.5,(.5+g6)/1.5,(.5+b6)/1.5)

	MagnetFallOff=Menu("Fall-off type %t|No fall-off %x0|Linear %x1|Inverse linear %x2|Round %x3|Sharp %x4|Bell %x5|Torus %x6|Damped sine %x7|Input %x8",140,posBX6,posBY6-21,92,15,MagnetFallOff.val,"Choose fall-off Type for randomization. Press F to cycle through the possibilities")
	MagnetPower=Number("P:",602,posBX6+100,posBY6-21,75,15,MagnetPower.val,0,100,"Specify the power of the magnetic field")

# # # # # Function input Window # # # # # # # #
def drawFunction(X,Y):
	global functionInput
	posX8,posY8,L8,H8=X,Y,184,43
	r8,g8,b8=.6,.6,.6
	panel(posX8,posY8,L8,H8,r8,g8,b8)

	Title='Function input'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r8/3,g8/3,b8/3)
	glRasterPos2i(posX8+5+(L8-6-TitleWidth)/2,posY8-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX8+3+(L8-6-TitleWidth)/2,posY8-13)
	Text(Title)

	posBX8,posBY8=posX8+4,posY8-38

	functionInput=String('f(x)=',810,posBX8,posBY8,177,15,functionInput.val,399,'Type your function to drive the "Input" fall-off type. Syntax must comply with Python standard.')
	
# # # # # Animation Window # # # # #
def drawAnimation(X,Y):
	global ShuffleX,ShuffleY,ShuffleZ,ShuffleLoc,ShuffleRot,ShuffleSize,ShuffleStart,ShuffleEnd,ShuffleRange,Delta,IndShuffle
	global FromWhat,ToWhich,FrameStart,FrameEnd,Factor,Span,Period,WaveObject,ExtType,InterType,MapTo01
	global Task
	global BrownPer,BrownReg,BrownStr,BrLocX,BrLocY,BrLocZ,BrRotX,BrRotY,BrRotZ,BrSizeX,BrSizeY,BrSizeZ,BrProp,BrownDelta
	posX7,posY7,L7,H7=X,Y,184,170
	r7,g7,b7=.35,.35,.35
	panel(posX7,posY7,L7,H7,r7,g7,b7)

	Title='Animation'
	TitleWidth=GetStringWidth(Title,'normal')
	glColor3f(r7/3,g7/3,b7/3)
	glRasterPos2i(posX7+5+(L7-6-TitleWidth)/2,posY7-14)
	Text(Title)
	glColor3f(.8,.8,.8)
	glRasterPos2i(posX7+3+(L7-6-TitleWidth)/2,posY7-13)
	Text(Title)

	posBX7,posBY7=posX7+4,posY7-35

	glColor3f(1.4*r7,1.4*g7,1.4*b7)
	glRasterPos2i(posBX7+5,posBY7)
	Text("Task :")
	glColor3f(2.1*r7,2.1*g7,2.1*b7)
	glRasterPos2i(posBX7+3,posBY7+2)
	Text("Task :")
	
	Task=Menu("Choose a task %t|Shuffle/Stretch IPOs %x0|Brownian motion %x1|Animate %x2",818,posBX7+40,posBY7-2,137,15,Task.val,"What task do you want to execute ?")

	#The three choice#
	if Task.val==0:
		posBY7-=25
	
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7)
		Text("From")
		ShuffleStart=Number('',807,posBX7+38,posBY7-3,45,14,ShuffleStart.val,-10000,10000,'The starting frame of the effect')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+96,posBY7)
		Text("to")
		ShuffleEnd=Number('',808,posBX7+114,posBY7-3,45,14,ShuffleEnd.val,-10000,10000,'The last frame of the effect')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-15)
		Text("over")
		ShuffleRange=Number('',809,posBX7+38,posBY7-18,45,14,ShuffleRange.val,0,10000,"Range: the amount of frames the IPO's can be shuffled")
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+96,posBY7-15)
		Text("frames.")

		IndShuffle=Toggle('Ind',812,posBX7+140,posBY7-18,29,14,IndShuffle.val,"Eligible points are shuffled on an individualy randomized basis, ie all points don't move by the same amount")

		posBY7-=37
		
		BeginAlign()
		ShuffleX=Toggle('X',800,posBX7,posBY7,27,14,ShuffleX.val,'Enable X-axis data shuffle')
		ShuffleY=Toggle('Y',801,posBX7+27,posBY7,27,14,ShuffleY.val,'Enable Y-axis data shuffle')
		ShuffleZ=Toggle('Z',802,posBX7+54,posBY7,29,14,ShuffleZ.val,'Enable Z-axis data shuffle')
		ShuffleLoc=Toggle('Loc',803,posBX7,posBY7-14,27,14,ShuffleLoc.val,'Enable location data shuffle')
		ShuffleRot=Toggle('Rot',804,posBX7+27,posBY7-14,27,14,ShuffleRot.val,'Enable rotation data shuffle')
		ShuffleSize=Toggle('Size',805,posBX7+54,posBY7-14,29,14,ShuffleSize.val,'Enable size data shuffle')
		EndAlign()
		
		posBX7+=90
		
		BeginAlign()
		Delta=Toggle('d',810,posBX7,posBY7,22,14,Delta.val,'Applies to the relative IPOs instead of absolute IPOs')
		Button('Other...',811,posBX7+22,posBY7,56,14,'If you want to affect other IPOs...')
		EndAlign()	
		Button('Shuffle',806,posBX7+4,posBY7-20,78,14,"Shuffle the selected object's IPO's specified by the toggles")

		line(posX7+2,posBY7-28,posX7+L7-2,posBY7-28,(.5+r7)/1.5,(.5+g7)/1.5,(.5+b7)/1.5)
	
	elif Task.val==2:
		posBX7,posBY7=posX7+4,posY7-60
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7)
		Text("From")
		FrameStart=Number('',820,posBX7+38,posBY7-3,46,14,FrameStart.val,1,10000,'The starting frame of the effect')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+96,posBY7)
		Text("to")		
		FrameEnd=Number('',821,posBX7+114,posBY7-3,46,14,FrameEnd.val,FrameStart.val+1,10000,'The last frame of the effect')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-15)
		Text("over")
		Span=Number('',809,posBX7+38,posBY7-18,46,14,Span.val,0,10000,"The range of the effect for a particular object")

		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+96,posBY7-15)
		Text("frames.")

		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-33)
		Text("Import from:")
		FromWhat=Menu("Import curve from %t|Function %x0|IPO %x1",818,posBX7+96,posBY7-36,80,14,FromWhat.val,"What input drives your effect?")
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-48)
		Text("Import to:")
		ToWhich=Menu("Bake to what IPO ? %t|LocX %x0|LocY %x1|LocZ %x2|dLocX %x3|dLocY %x4|dLocZ %x5|RotX %x6|RotY %x7|RotZ %x8|dRotX %x9|dRotY %x10|dRotZ %x11|SizeX %x12|SizeY %x13|SizeZ %x14|dSizeX %x15|dSizeY %x16|dSizeZ %x17",819,posBX7+96,posBY7-51,80,14,ToWhich.val,"The IPO you want to bake to")
		
		
		# #Factor=Number('Factor:',823,posBX7+87,posBY7-32,92,14,Factor.val,0,10000,"Range: the amount of frames over which the effect takes place for a given object")
		# #Period=Number('Period:',824,posBX7+87,posBY7-47,92,14,Period.val,0,10000,"Range: the amount of frames over which the effect takes place for a given object")

		if FromWhat.val==1:
			WaveObject=String('OB:',825,posBX7,posBY7-32,83,14,'',39,"The Object from which you want to import an IPO curve")
			WaveIPO=String('IPO:',826,posBX7,posBY7-47,83,14,'',39,"The IPO you want to import from the above-selected object")
		else:
	#		MapTo01=Toggle('Map to [0,1]',828,posBX7,posBY7-107,83,14,MapTo01.val,'Map the function values to the [0;1] domain')
			glColor3f(2.1*r7,2.1*g7,2.1*b7)
			glRasterPos2i(posBX7+3,posBY7-64)
			Text("Extend :")
			ExtType=Menu('Extend %t|Constant %x0|Extrapolate %x1|Cyclic %x2|Cycl. Extr. %x3',827,posBX7+96,posBY7-67,80,14,ExtType.val,"The type of extend you want to give")
			glColor3f(2.1*r7,2.1*g7,2.1*b7)
			glRasterPos2i(posBX7+3,posBY7-78)
			Text("Interpolation :")
			InterType=Menu('Interpolation %t|Constant %x0|Linear %x1|Bezier %x2',828,posBX7+96,posBY7-81,80,14,InterType.val,"The type of interpolation you want your curve to have")
		Button('Animate',827,posBX7+96,posBY7-107,80,14,"Proceed to the animation")


	else:
		posBY7-=15

		posBX7,posBY7=posX7+4,posY7-60
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7)
		Text("From")
		FrameStart=Number('',820,posBX7+38,posBY7-3,51,14,FrameStart.val,1,10000,'The starting frame of the effect')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+98,posBY7)
		Text("to")		
		FrameEnd=Number('',821,posBX7+125,posBY7-3,51,14,FrameEnd.val,FrameStart.val+1,10000,'The last frame of the effect')

		posBY7-=17
		
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7)
		Text("Per.")
		BrownPer=Number('',849,posBX7+38,posBY7-5,51,14,BrownPer.val,0,100,'The period of the impulses (in frames)')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+98,posBY7)
		Text("Reg.")
		BrownReg=Number('',849,posBX7+125,posBY7-5,51,14,BrownReg.val,0,1,'The regularity of the impulses (1=perfectly regular)')
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-18)
		Text("Strength (nervosity):")
		BrownStr=Number('',851,posBX7+125,posBY7-23,51,14,BrownStr.val,0.,1.,'The quickness of the impulses')
		glColor3f(1.4*r7,1.4*g7,1.4*b7)
		glRasterPos2i(posBX7+5,posBY7-38)
		Text("Domain:")
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7+3,posBY7-36)
		Text("Domain:")
		posBY7-=55
		posBX7+=10


		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7,posBY7+3)
		Text("Location:")
		BeginAlign()
		BrLocX=Toggle('X',852,posBX7+53,posBY7,15,14,BrLocX.val,'Enable X-axis motion')
		BrLocY=Toggle('Y',853,posBX7+68,posBY7,13,14,BrLocY.val,'Enable Y-axis motion')
		BrLocZ=Toggle('Z',854,posBX7+81,posBY7,16,14,BrLocZ.val,'Enable Z-axis motion')
		EndAlign()
		
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7,posBY7-15)
		Text("Rotation:")
		BeginAlign()
		BrRotX=Toggle('X',855,posBX7+53,posBY7-18,15,14,BrRotX.val,'Enable X-axis rotation')
		BrRotY=Toggle('Y',856,posBX7+68,posBY7-18,13,14,BrRotY.val,'Enable Y-axis rotation')
		BrRotZ=Toggle('Z',857,posBX7+81,posBY7-18,16,14,BrRotZ.val,'Enable Z-axis rotation')
		EndAlign()
		
		glColor3f(2.1*r7,2.1*g7,2.1*b7)
		glRasterPos2i(posBX7,posBY7-33)
		Text("Scale:")
		BeginAlign()
		BrSizeX=Toggle('X',858,posBX7+53,posBY7-36,15,14,BrSizeX.val,'Enable X-axis scaling')
		BrSizeY=Toggle('Y',859,posBX7+68,posBY7-36,13,14,BrSizeY.val,'Enable Y-axis scaling')
		BrSizeZ=Toggle('Z',860,posBX7+81,posBY7-36,16,14,BrSizeZ.val,'Enable Z-axis scaling')
		EndAlign()

		BrownDelta=Toggle('d',861,posBX7+105,posBY7-36,30,50,BrownDelta.val,'Applies to the relative IPOs instead of absolute IPOs')
		Button('Go',862,posBX7+135,posBY7-36,30,50,"Proceed to the animation")
		BrProp=Toggle('P',860,posBX7+35,posBY7-36,15,14,BrProp.val,'Toggle proportionnal scaling')
Register(GUI,event,bevent)
