#!BPY
"""
Name: 'Asteroid Belt-Script'
Blender: 248
Group: 'Wizards'
Tooltip: 'Generates a asteroid belt'
"""
__author__ = "Raphael 'Rabanti' Stoeckli"
__url__ = ("http://www.rabanti.ch/download.php?file=asteroid_0.2.py")
__version__ = "asteroid belt-script v0.2 2009-07-18"
__bpydoc__ = """\
This scrip generates meteor-like objects in a predefined space. You can define the amount of objects, rotation- and move-parameters, material, randoimzation-parameters and several other values.
<br>
ToDo:<br>
- Fix of the hard trial-function
- Simplification of distant objects (outgoing from a viewpoint or a path)
- Memory optimization (if possible)
- Speed enhancement while placing objects (OK/ More possible, dep. on the hard trial-function)
- Soft border zones (less object around the field borders)
- Collision interaction
"""

# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
# Copyright (C) Raphael Stoeckli (alias Rabanti)
#
# 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 *****
# --------------------------------------------------------------------------
# ORIGIN AUTHOR:
# Name: Raphael Stoeckli (alias Rabanti)
# Mail: <<blender 'AT' rabanti 'DOT' ch>>
# Date: 2009-06-04

# ... Have fun

import math
import time

import bpy
import Blender
from Blender import *
from Blender import Mathutils
from Blender.Mathutils import *

from Blender.Draw import *  # for GUI
from Blender.BGL import *
#from Blender import Draw, BGL

from Blender.Noise import random

# PRESETS
DEBUG = False # Debug-switch for developing
# -------------------------------------------------------
sect0_switch = Create(1)
sect1_switch = Create(0)
sect2_switch = Create(0)
sect3_switch = Create(0)
sect01_switch = Create(1)
sect02_switch = Create(0)
f_mesh_src = Create("")
f_subsurf_p1 = Create(1)
f_subsurf_p2 = Create(1)
f_subsurf_p3 = Create(2)
f_subsurf_p4 = Create(False)
f_subsurf_p5 = Create(True)

f_seed1 = Create(0.15)
f_seed_sel1 = Create(3)
f_seed_iter = Create(2)
mat_menu = Create(1)
f_ratio = Create(1.5)
f_rpm = Create(0.2)
f_movement = Create(0.05)
shale_switch = Create(1)
f_maxsize = Create(5.0)
f_minsize = Create(0.25)
f_seed_meta = Create(11)
f_threshold = Create(0.2)
f_stiff = Create(2.0)
f_comp = Create(0.75)
if DEBUG == True:
	f_brad_min = Create(1.1)
	f_brad_max = Create(1.1)
	subsurf_switch = Create(0)
	smooth_switch = Create(0)
else:
	f_brad_min = Create(1.0)
	f_brad_max = Create(6.0)
	subsurf_switch = Create(1)
	smooth_switch = Create(1)

rand_switch = Create(1)
ipo_switch = Create(1)
simple_switch = Create(0)
field_menu = Create(1)
ss1_switch = Create(1)
ss2_switch = Create(1)
ss3_switch = Create(1)
ss4_switch = Create(0)
salt_mat_menu = Create(1)
se1_switch = Create(0)
se2_switch = Create(0)
se3_switch = Create(0)
se4_switch = Create(0)
ealt_mat_menu = Create(1)

f_cx = Create(0)
f_cy = Create(0)
f_cz = Create(0)
f_dx = Create(60)
f_dy = Create(70)
f_dz = Create(40)
f_sx = Create(0)
f_sy = Create(0)
f_sz = Create(0)
f_radius1 = Create(30)
f_radius2 = Create(6)
f_radius3 = Create(20)
f_sradius1 = Create(10)
f_sradius2 = Create(20)

f_amount = Create(50)
f_mindist = Create(0.8)
f_maxtrial = Create(100)
hard_trial_switch = Create(0) # Was 1; Diabled per default, until it is fixed
met_list = {}
quadrants = {}
quadrant_border = [0,0,0]



def start1():
	print "WARNING! This is a Alpha, resp. early Beta-Version.\nThe hard trial-function is buggy (yet) and the whole 'view' section is not implemented yet."
	if DEBUG == True: # DEBUG-SWITCH ---->>>
		print "\aWARNING!\nDebug-Mode is enabled!\nInstead of regular messages you will get 'strange' Debug-messages (for developing)\n---------------------------------------\n"
		
	t_time = time.time()
	Window.EditMode(0) # exit Edit-Modus
	Blender.Noise.setRandomSeed(0)
	define_quadrant()
	for i in range(0,f_amount.val,1):
		met_list[i] = ["",0,0,0,0,0,0,0,1]
		if sect02_switch.val == True:
			check_object()
			ob = copy_from_object()
			if ob == -1: return -1 # STOP
		else:
			iter = int(Rand(2,f_seed_meta.val)) # Iteration seed for meta ball creation
			ob = create_mesh(iter,1,f_threshold.val,f_stiff.val,f_brad_min.val,f_brad_max.val,f_comp.val) # creates Mesh
		me = Mesh.Get(ob.getData(True))
		ob.select(1)
		centernew(ob) # sets the object-center into the mesh-center
		met_list[i][0] = ob
		if rand_switch.val == True:
			randomize_mesh(ob) # randomizing of the base-mesh
			detect_free_triangle(ob) # Detect plane-like trinagles and joins all verts to one point
			rdb = me.remDoubles(0)
		size_object(i) # sets size and ratio of the object
		
		for j in me.faces:
			if smooth_switch.val == True:
				j.smooth = 1
			else:
				j.smooth = 0
			j.sel = 0
		if subsurf_switch == True:
			subsurf1(ob)
		if ipo_switch == True:
			IPO_object(ob)
			
		mat_list = Material.Get()
		if mat_list:
			tex1 = bpy.data.materials[mat_list[mat_menu.val - 1].name]
			me.materials = [tex1]
			
		place_object(i) # Placement
		if DEBUG == True: # --> DEBUG-Switch
			print "Object: ", i, "\n------------------\n[0]", met_list[i][0], "\n[1]", met_list[i][1], "\n[2]", met_list[i][2], "\n[3]", met_list[i][4], "\n[4]", met_list[i][5], "\n[5]", met_list[i][6], "\n[7]", met_list[i][7], "\n[8]", met_list[i][8]
		
	temp = time.time() - t_time
	print "Time: ", temp, " sec."
	Window.RedrawAll() # update windows


def start2():
	if DEBUG == True: # DEBUG-SWITCH ---->>>
		print "\aWARNING!\nDebug-Mode is enabled!\nInstead of regular messages you will get 'strange' Debug-messages (for developing)\n---------------------------------------\n\n"
		
	t_time = time.time()
	Window.EditMode(0) # exit Edit-Modus
	Blender.Noise.setRandomSeed(0)
	met_list[0] = ["",0,0,0,0,0,0,0,1]
	if sect02_switch.val == True:
		check_object()
		ob = copy_from_object()
		if ob == -1: return -1 # STOP
	else:
		iter = int(Rand(2,f_seed_meta.val)) # Iteration seed for meta ball creation
		ob = create_mesh(iter,1,f_threshold.val,f_stiff.val,f_brad_min.val,f_brad_max.val,f_comp.val) # creates Mesh
	me = Mesh.Get(ob.getData(True))
	ob.select(1)
	centernew(ob) # sets the object-center into the mesh-center
	met_list[0][0] = ob
	if rand_switch.val == True:
		randomize_mesh(ob) # randomizing of the base-mesh
		detect_free_triangle(ob) # Detect plane-like trinagles and joins all verts to one point
		rdb = me.remDoubles(0)
	size_object(0) # sets size and ratio of the object
		
	for j in me.faces:
		if smooth_switch.val == True:
			j.smooth = 1
		else:
			j.smooth = 0
		j.sel = 0
	if subsurf_switch == True:
		subsurf1(ob)
	if ipo_switch == True:
		IPO_object(ob)
			
	mat_list = Material.Get()
	if mat_list:
		tex1 = bpy.data.materials[mat_list[mat_menu.val - 1].name]
		me.materials = [tex1]
		
	#print "CURSOR:", Window.GetCursorPos()
	met_list[0][0].setLocation(Window.GetCursorPos())
		
	temp = time.time() - t_time
	print "Time: ", temp, " sec."
	if DEBUG == True: # --> DEBUG-Switch
		print "[0]", met_list[0][0], "\n[1]", met_list[0][1], "\n[2]", met_list[0][2], "\n[3]", met_list[0][4], "\n[4]", met_list[0][5], "\n[5]", met_list[0][6], "\n[7]", met_list[0][7], "\n[8]", met_list[0][8]
	Window.RedrawAll() # update windows
			
		
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def subsurf1(ob):
	mods = ob.modifiers
	mod = mods.append(Blender.Modifier.Type.SUBSURF)
	mod[Blender.Modifier.Settings.TYPES] = f_subsurf_p1.val - 1 # Offset + 1 to the menu-item
	mod[Blender.Modifier.Settings.LEVELS] = f_subsurf_p2.val
	mod[Blender.Modifier.Settings.RENDLEVELS] = f_subsurf_p3.val
	mod[Blender.Modifier.Settings.OPTIMAL] = f_subsurf_p4.val
	mod[Blender.Modifier.Settings.UV] = f_subsurf_p5.val
	#ob.makeDisplayList()
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def IPO_object(ob): 
	if f_rpm.val > 0.:
		ipo = Blender.Ipo.New("Object", "ast_ipo")
		x = ipo.addCurve("RotX")
		offset = Rand(0,1)*36
		x.addBezier((1,offset))
		pre = int(Rand(0,2))
		if pre == 0: pre = -1
		x.addBezier((1500, (36*Rand(0,1)*f_rpm.val*pre)+offset))
		y = ipo.addCurve("RotY")
		offset = Rand(0,1)*36
		y.addBezier((1,offset))
		pre = int(Rand(0,2))
		if pre == 0: pre = -1
		y.addBezier((1500, (36*Rand(0,1)*f_rpm.val*pre)+offset))
		z = ipo.addCurve("RotZ")
		offset = Rand(0,1)*36
		z.addBezier((1,offset))
		pre = int(Rand(0,2))
		if pre == 0: pre = -1
		z.addBezier((1500, (36*Rand(0,1)*f_rpm.val*pre)+offset))
		ob.setIpo(ipo)
		x.setExtrapolation("Extrapolation")
		y.setExtrapolation("Extrapolation")
		z.setExtrapolation("Extrapolation")
		
	if f_movement.val > 0.:
	    x = ipo.addCurve("dLocX")
	    x.addBezier((1,0))
	    pre = int(Rand(0,2))
	    if pre == 0: pre = -1
	    x.addBezier((1500, Rand(0,1)*f_movement.val*pre))
	    y = ipo.addCurve("dLocY")
	    y.addBezier((1,0))
	    pre = int(Rand(0,2))
	    if pre == 0: pre = -1
	    y.addBezier((1500, Rand(0,1)*f_movement.val*pre))
	    z = ipo.addCurve("dLocZ")
	    z.addBezier((1,0))
	    pre = int(Rand(0,2))
	    if pre == 0: pre = -1
	    z.addBezier((1500, Rand(0,1)*f_movement.val*pre))
	    ob.setIpo(ipo)
	    x.setExtrapolation("Extrapolation")
	    y.setExtrapolation("Extrapolation")
	    z.setExtrapolation("Extrapolation")
	    x.recalc()
	    y.recalc()
	    z.recalc()

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def place_object(met_number):
	type = field_menu.val
	xyz = get_rand_pos(type)
	lx = xyz[0]
	ly = xyz[1]
	lz = xyz[2]
	mindist = f_mindist.val
	bb_size = getBBox(met_list[met_number][0])
	max_size = (met_list[met_number][5]/bb_size[0]) / 2
	if (met_list[met_number][6]*bb_size[1]) / 2 > max_size: max_size = (bb_size[1]*met_list[met_number][6]) / 2
	if (met_list[met_number][7]*bb_size[2]) / 2 > max_size: max_size = (bb_size[2]*met_list[met_number][7]) / 2
	max_size = max_size + (mindist/2)
	temp_list = {}
	flag2 = True
	for j in range(1,f_maxtrial.val,1):
		flag = True
		if flag2 == False:
			#lx = (f_cx.val - (f_dx.val / 2)) + Rand(0,1) * f_dx.val
			#ly = (f_cy.val - (f_dy.val / 2)) + Rand(0,1) * f_dy.val
			#lz = (f_cz.val - (f_dz.val / 2)) + Rand(0,1) * f_dz.val
			xyz = get_rand_pos(type)
			lx = xyz[0]
			ly = xyz[1]
			lz = xyz[2]
			flag2 = True
		
		temp_coord = assign_quadrant(met_number,lx,ly,lz)
		temp_list = quadrants[(temp_coord[0],temp_coord[1],temp_coord[2])]
		#print "***"
		#print temp_list
		#for i in range(0,len(temp_list),1):
		#	j = quadrants[temp_list[i]][6][0]
		for k in temp_list:
			#print "---", temp_list[i]
			#print "----", j
			if met_list[k][8] == 0: continue # Don't handle disabled 
			flag_count = 0
			max_size2 = met_list[k][1] + (mindist/2)
			if (lx + max_size) > (met_list[k][2] - max_size2) and (lx - max_size) < (met_list[k][2] + max_size2): flag_count += 1#flag = False
			if (ly + max_size) > (met_list[k][3] - max_size2) and (ly - max_size) < (met_list[k][3] + max_size2): flag_count += 1#flag = False
			if (lz + max_size) > (met_list[k][4] - max_size2) and (lz - max_size) < (met_list[k][4] + max_size2): flag_count += 1#flag = False
			if flag_count > 2: #and j <= f_maxtrial.val:
				flag2 = False
				break
		if flag2 == True:
			break
			
	if hard_trial_switch.val == 1 and flag2 == False:
		#flag2 = hard_trial(met_number,max_size,type)
		ret_list = hard_trial(met_number,max_size,type)
		if ret_list[0] == False:
			flag2 = False
		else:
			lx = ret_list[1]
			ly = ret_list[2]
			lz = ret_list[3]
			flag2 = True
	if flag2 == False: #and (j+1) == f_maxtrial.val:
		if DEBUG == False: # DEBUG-SWITCH ---->>>
			print "DEL Object: ", met_list[met_number][0].name, " because no space was found for it (trials:", f_maxtrial.val, ")"
		#v = x * a
		sc = Scene.GetCurrent()
		sc.unlink(met_list[met_number][0])
		met_list[met_number][8] = 0
		
	else:
		met_list[met_number][1] = max_size - (mindist/2)
		met_list[met_number][2] = lx
		met_list[met_number][3] = ly
		met_list[met_number][4] = lz	
		met_list[met_number][0].setLocation(lx, ly, lz)
		assign_quadrant(met_number,lx,ly,lz)
		if DEBUG == False: # DEBUG-SWITCH ---->>>
			print "OK! OB:", met_list[met_number][0].name, " is placed (OB ", met_number + 1, " of ", f_amount.val, ")"	

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def get_rand_pos(type):
	xyz = [0.0,0.0,0.0]
	tRdeg1 = Rand(0,360) # Polar angle
	tRdeg2 = Rand(0,360) # Azimuth angle
	tHyp2 = Rand(0,f_radius2.val) # Ring/Edge radius
	tz = Rand(0,1) * f_dz.val
	if type == 1:
		tx = Rand(0,1) * f_dx.val
		ty = Rand(0,1) * f_dy.val
	elif type == 2 or type == 5: tHyp = Rand(0,f_radius1.val) # Radius
	elif type == 3: tHyp = f_radius1.val # Radius of Torus (non variable)
	elif type == 4:
		if f_radius1.val < f_radius3.val:
			tR1 = f_radius1.val
			tR2 = f_radius3.val
		else:
			tR1 = f_radius3.val
			tR2 = f_radius1.val
		tHyp = Rand(tR1,tR2) # O-Radius - I-Radius
	elif type == 6: tHyp = Rand(0,(f_radius1.val - 2*f_radius2.val)) # Radius
		
	if type == 1: # Cuboidal
		xyz[0] =  tx - f_dx.val / 2
		xyz[1] =  ty - f_dy.val / 2
		xyz[2] =  tz - f_dz.val / 2
	if type == 2: # Sphere
		xyz[0] = tHyp * math.sin(tRdeg1) * math.cos(tRdeg2)
		xyz[1] = tHyp * math.sin(tRdeg1) * math.sin(tRdeg2)
		xyz[2] = tHyp * math.cos(tRdeg1)
	if type == 3: # Torus
		xyz[0] = (tHyp + tHyp2 * math.cos(tRdeg2)) * math.cos(tRdeg1) 
		xyz[1] = (tHyp + tHyp2 * math.cos(tRdeg2)) * math.sin(tRdeg1) 
		xyz[2] = tHyp2 * math.sin(tRdeg2)
	if type == 4: # Flat Ring
		xyz[0] = math.cos(tRdeg1) * tHyp
		xyz[1] = math.sin(tRdeg1) * tHyp
		xyz[2] = tz # Height
	if type == 5: # Disk
		xyz[0] = math.cos(tRdeg1) * tHyp
		xyz[1] = math.sin(tRdeg1) * tHyp
		xyz[2] = tz # Height
	if type == 6: # Rounded Disk
		xyz[0] = (tHyp + tHyp2 * math.cos(tRdeg2)) * math.cos(tRdeg1) 
		xyz[1] = (tHyp + tHyp2 * math.cos(tRdeg2)) * math.sin(tRdeg1) 
		xyz[2] = tHyp2 * math.sin(tRdeg2)

	xyz[0] += f_cx.val
	xyz[1] += f_cy.val
	xyz[2] += f_cz.val
	return xyz

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def check_border(type,x,y,z):
	#dx = x - f_cx.val
	#dy = y - f_cy.val
	#dz = z - f_cz.val
	cx = f_cx.val
	cy = f_cy.val
	cz = f_cz.val
	dx = f_dx.val
	dy = f_dy.val
	dz = f_dz.val
	r1 = f_radius1.val
	r2 = f_radius2.val
	r3 = f_radius3.val
	flag = True
	if type == 1:
		if x < (cx - (dx/2)) or x > (cx + (dx/2)) or y < (cy - (dy/2)) or y > (cy + (dy/2)) or z < (cz - (dz/2)) or z > (cz + (dz/2)): flag = False
	elif type == 2: # Sphere
		ract = math.sqrt(math.pow(x-cx,2)+math.pow(y-cy,2)+math.pow(z-cz,2))
		#print "x:", x , " y:", y," z:", z
		#print "cx:", cx , " cy:", cy," cz:", cz
		#print "R-MAX:", r1, " - RAct:", ract
		if ract > r1: flag = False
	elif type == 3: # Torus (approx shape)
		rmin = r1 - r2
		rmax = r1 + r2
		ract = math.sqrt(math.pow(x-cx,2)+math.pow(y-cy,2)+math.pow(z-cz,2))
		if ract > rmax or ract < rmin or x > (cx+r2) or x < (cx-r2): flag = False
	elif type == 4: # Flat Ring
		ract = math.sqrt(math.pow(x-cx,2)+math.pow(y-cy,2)+math.pow(z-cz,2))
		#if ract > r1 or ract < r2 or x > (cx+r2) or x < (cx-r2) or z < (cz - (dz/2)) or z > (cz + (dz/2)): flag = False
		if ract > r1 or ract < r2 or z < (cz - (dz/2)) or z > (cz + (dz/2)): flag = False
	elif type == 5 or type == 6: # Rounded Disk (approx shape) /Disk 
		ract = math.sqrt(math.pow(x-cx,2)+math.pow(y-cy,2)+math.pow(z-cz,2))
		if ract > r1 or z > (cz+r2) or z < (cz-r2): flag = False
	#if flag == False: print "Border checked: Type=", type, " - return=", flag # DEBUG
	return flag
		
		
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def hard_trial(met_number,max_size,type):
	flag2 = True
	mindist = f_mindist.val
	rand_array = random_array(0,len(met_list))
	bux = f_cx.val - (f_dx.val / 2)
	buy = f_cy.val - (f_dy.val / 2)
	buz = f_cz.val - (f_dz.val / 2)
	blx = f_cx.val + (f_dx.val / 2)
	bly = f_cy.val + (f_dy.val / 2)
	blz = f_cz.val + (f_dz.val / 2)
	lx = ly = lz = 0
	

	for i in range(0,len(rand_array),1):
		x = rand_array[i]
		tflag = True
		for j in range(1,6,1):
			flag = True
			if met_number == x or met_list[x][8] == 0: continue # Don't handle SELF or erased
			"""
			if j == 1:
				lx = met_list[x][2] + met_list[x][1] + mindist + max_size
			elif j == 2:
				lx = met_list[x][2] - met_list[x][1] - mindist - max_size
			elif j == 3:
				ly = met_list[x][3] + met_list[x][1] + mindist + max_size
			elif j ==  4:
				ly = met_list[x][3] - met_list[x][1] - mindist - max_size
			elif j == 5:
				lz = met_list[x][4] + met_list[x][1] + mindist + max_size
			elif j == 6:
				lz = met_list[x][4] - met_list[x][1] - mindist - max_size
			flag_count = 0
			if lx > bux or lx < blx or ly > buy or ly < bly or lz > buz or lz < blz:
				flag = False
				break  # Out of range
			"""
			lx = met_list[x][2]
			ly = met_list[x][3]
			lz = met_list[x][4]
			if j == 1: lx = met_list[x][2] + met_list[x][1] + mindist + max_size # + max_size??? Do we need this addition --> BUGGY
			if j == 2: lx = met_list[x][2] - met_list[x][1] - mindist - max_size
			if j == 3: ly = met_list[x][3] + met_list[x][1] + mindist + max_size
			if j == 4: ly = met_list[x][3] - met_list[x][1] - mindist - max_size
			if j == 5: lz = met_list[x][4] + met_list[x][1] + mindist + max_size
			if j == 6: lz = met_list[x][4] - met_list[x][1] - mindist - max_size
			
			tflag = True
			tflag = check_border(type,lx,ly,lz) # Check border of the field
			if tflag == False:  continue #flag = False; #print "OUT OF RANGE!!!"
	
			flag_count = 0	
			max_size2 = met_list[x][1] + (mindist/2) # OBSOLOTE!?!?!
			# DEBUG - BLOCK / Experimental
			"""
			print "---CHECK to OB:", met_list[x][0].name ," STEP:", j, "---"
			print "maxsize(ob):", met_list[x][1], " / max_size:", max_size, " / max_size2:", max_size2
			print "x=", met_list[x][2], " y=", met_list[x][3], " z=",met_list[x][4]
			print "sx=", met_list[x][5], " sy=", met_list[x][6], " sz=",met_list[x][7]
			print "lx=", lx, " ly=", ly, " lz=",lz
			print "--------------------------------------------"
			print "lx+max:", lx + max_size, " > x-max2:", met_list[x][2] #- max_size2
			print "lx-max:", lx - max_size, " < x+max2:", met_list[x][2] #+ max_size2
			print "ly+max:", ly + max_size, " > y-max2:", met_list[x][3] #- max_size2
			print "ly-max:", ly - max_size, " < y+max2:", met_list[x][3] #+ max_size2
			print "lz+max:", lz + max_size, " > z-max2:", met_list[x][4] #- max_size2
			print "lz-max:", lz - max_size, " < z+max2:", met_list[x][4] #+ max_size2
			print "---CHECK-END---"
			"""
			#if (lx + max_size) > met_list[x][2] and (lx - max_size) < met_list[x][2]: flag_count += 1#flag = False
			#if (ly + max_size) > met_list[x][3] and (ly - max_size) < met_list[x][3]: flag_count += 1#flag = False
			#if (lz + max_size) > met_list[x][4] and (lz - max_size) < met_list[x][4]: flag_count += 1#flag = False
			
			if (lx + max_size) > (met_list[x][2] - max_size2) and (lx - max_size) < (met_list[x][2] + max_size2): flag_count += 1#flag = False
			if (ly + max_size) > (met_list[x][3] - max_size2) and (ly - max_size) < (met_list[x][3] + max_size2): flag_count += 1#flag = False
			if (lz + max_size) > (met_list[x][4] - max_size2) and (lz - max_size) < (met_list[x][4] + max_size2): flag_count += 1#flag = False
			
			if flag_count > 2: #and j <= f_maxtrial.val:
				#print "FLAG-COUNT:", flag_count
				flag = False
				break

		if tflag == False: flag = False # Out of range
		if flag == True: break
	#tflag = check_border(type,lx,ly,lz) # Check border of the field
	#if tflag == False: flag = False#print "OUT OF RANGE!!!"
		
	if flag == True:
		flag2 = True
		print "Hard trial was successful!"
	else:
		flag2 = False
		print "Hard trial failed!"
	ret_list = [flag2, lx, ly, lz]
	return ret_list# flag2
		
			
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# 
def size_object(met_number):
	ob = met_list[met_number][0]
	x = Rand(f_minsize.val,f_maxsize.val)
	y = Rand(f_minsize.val,f_maxsize.val)
	z = Rand(f_minsize.val,f_maxsize.val)
	ob.setSize(1,1,1) # Default
	bbox = getBBox(ob)
	bbox2 = ob.getSize('worldspace')
	rx = bbox2[0] / bbox[0]
	ry = bbox2[1] / bbox[1]
	rz = bbox2[2] / bbox[2]
	
	
	
	if shale_switch.val == 1:
		check1 = True
		m_ratio = {}
		if f_ratio.val == 1: # 1:1:1
			x = Y = z = Rand(f_minsize.val,f_maxsize.val)
			check1 = False
		while check1:
			if x < y:
				m_ratio[0] = y / x
			else:
				m_ratio[0] = x / y
			if x < z:
				m_ratio[1] = z / x
			else:
				m_ratio[1] = x / z
			if y < z:
				m_ratio[2] = z / y
			else:
				m_ratio[2] = y / z  
			if m_ratio[0] > f_ratio.val or m_ratio[1] > f_ratio.val or m_ratio[2] > f_ratio.val:
				x = Rand(f_minsize.val,f_maxsize.val)
				y = Rand(f_minsize.val,f_maxsize.val)
				z = Rand(f_minsize.val,f_maxsize.val)
			else: check1 = False
	ob.setSize(x*rx,y*ry,z*rz)
	met_list[met_number][5] = x*rx
	met_list[met_number][6] = y*ry
	met_list[met_number][7] = z*rz
	

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def getBBox(ob):
	bb = ob.getBoundBox(1)
	w = bb[7].x - bb[1].x
	h = bb[1].z - bb[7].z
	d = bb[1].y - bb[7].y
	wdh = [w,d,h]
	return wdh
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def randomize_mesh(ob):
	me = Mesh.Get(ob.getData(True))
	for j in range(0,f_seed_iter.val,1):
		x = Rand(f_minsize.val,f_maxsize.val)
		y = Rand(f_minsize.val,f_maxsize.val)
		z = Rand(f_minsize.val,f_maxsize.val)
		ob.size = (x,y,z)
	
		for i in me.verts:
			x = int(Rand(0,f_seed_sel1.val))
			if x == 0:
				i.sel = 1
				i.co[0] += Rand(0,1) * f_seed1.val 
				i.co[1] += Rand(0,1) * f_seed1.val
				i.co[2] += Rand(0,1) * f_seed1.val
			else:	i.sel = 0	
		for i in me.edges:
			x = int(Rand(0,f_seed_sel1.val))
			if x == 0:	i.sel = 1
			else:		i.sel = 0
		me.subdivide()

		for i in me.edges:
			x = int(Rand(0,f_seed_sel1.val))
			if x == 0:
				i.v1.co[0] = (i.v1.co[0] + i.v2.co[0])/2
				i.v2.co[0] = i.v1.co[0]
				i.v1.co[1] = (i.v1.co[1] + i.v2.co[1])/2
				i.v2.co[1] = i.v1.co[1]
				i.v1.co[2] = (i.v1.co[2] + i.v2.co[2])/2
				i.v2.co[2] = i.v1.co[2]
			i.sel = 1
	
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# COPY FROM EXISTING MESH
def copy_from_object():
	if len(f_mesh_src.val) == 0: # STOP
		block = []
		#block.append(("Name: ", Blender.Draw.Create("short text"), 0, 30, "Error"))
		block.append("No Object spified!")
		retval = Blender.Draw.PupBlock("Error", block)
		return -1
	ob = Object.Get (f_mesh_src.val)
	sc = Scene.GetCurrent()
	sc.objects.selected = []
	ob.sel = 1
	test = Object.Duplicate(True)
	ob2 = Object.GetSelected()[0]
	return ob2
#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#  CERATION WITH META BALLS
def create_mesh(b_count,wiresize,thresh,stiff,brad_min,brad_max,comp): # Creates a mesh out of meta balls
	xpos = 0
	ypos = 0
	zpos = 0

	sc = Scene.GetCurrent()          # get current scene
	ob_name = 'O_' + str(int(Rand(0,9999))) + '_' + str(int(Rand(0,9999))) + '_' + str(int(Rand(0,9999))) + '_rnd'
	# Randomizing the temporary name of the meta object is important for further calls
	mb = Blender.Metaball.New()
	ob = sc.objects.new(mb,ob_name)  
	ob.link(mb)
	mb.wiresize = wiresize
	mb.thresh = thresh


	for i in range(1,b_count,1):
		mel= mb.elements.add()
		brad = Rand(brad_min,brad_max)
		mel.radius = brad
		xpos = xpos + Rand(0-brad,brad)*comp
		ypos = ypos + Rand(0-brad,brad)*comp
		zpos = zpos + Rand(0-brad,brad)*comp
		mel.co = Vector(xpos,ypos,zpos)
		mel.stiffness = stiff
	me = Mesh.New()
	Window.RedrawAll() # VERY IMPORTANT
	me.getFromObject(ob.name,1,0)
	ob2 = sc.objects.new(me,'metamesh')
	sc.unlink(ob)
	return ob2
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#	
def centernew(ob): # equiv. to function 'Center New'
	sc = Scene.GetCurrent() 
	me = Mesh.Get(ob.getData(True))

	bound = [None,None,None,None,None,None] # X-min, X-max, Y-min, Y-max, Z-min, Z-max
	for ve in me.verts: # [0]x[1]y[2]z
		pos = ve.co
		if ve.co[0] < bound[0] or bound[0] == None:
			bound[0] = ve.co[0]
		if ve.co[0] > bound[1] or bound[1] == None:
			bound[1] = ve.co[0]
		if ve.co[1] < bound[2] or bound[2] == None:
			bound[2] = ve.co[1]
		if ve.co[1] > bound[3] or bound[3] == None:
			bound[3] = ve.co[1]
		if ve.co[2] < bound[4] or bound[4] == None:
			bound[4] = ve.co[2]
		if ve.co[2] > bound[5] or bound[5] == None:
			bound[5] = ve.co[2]
	cx = (bound[0] + bound[1])/2
	cy = (bound[2] + bound[3])/2
	cz = (bound[4] + bound[5])/2
	loc = ob.loc
	ob.loc = [loc[0]+cx,loc[1]+cy,loc[2]+cz]
	for ve in me.verts:
		ve.co[0] -= cx
		ve.co[1] -= cy
		ve.co[2] -= cz
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def detect_free_triangle(ob):
	me = Mesh.Get(ob.getData(True))
	edgelist = {}
	for i in me.verts:
		edgelist[i] = []
	for i in me.edges:
		edgelist[i.v1].append(i)
		edgelist[i.v2].append(i)
	
	for i in me.verts:
		if len(edgelist[i]) == 2:
			edgelist[i][0].v2.co[0] = edgelist[i][0].v1.co[0]
			edgelist[i][0].v2.co[1] = edgelist[i][0].v1.co[1]
			edgelist[i][0].v2.co[2] = edgelist[i][0].v1.co[2]
			edgelist[i][1].v1.co[0] = edgelist[i][0].v1.co[0]
			edgelist[i][1].v1.co[1] = edgelist[i][0].v1.co[1]
			edgelist[i][1].v1.co[2] = edgelist[i][0].v1.co[2]
			edgelist[i][1].v2.co[0] = edgelist[i][0].v1.co[0]
			edgelist[i][1].v2.co[1] = edgelist[i][0].v1.co[1]
			edgelist[i][1].v2.co[2] = edgelist[i][0].v1.co[2]
		if len(edgelist[i]) == 1:
			edgelist[i][0].v2.co[0] = edgelist[i][0].v1.co[0]
			edgelist[i][0].v2.co[1] = edgelist[i][0].v1.co[1]
			edgelist[i][0].v2.co[2] = edgelist[i][0].v1.co[2]
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def simplificate(ob, amount): # NOT YET FINISHED/... OR STARTED
	x = 1
	"""
	me = Mesh.Get(ob.getData(True))
	wFlag = True
	sFlag = 0
	while wFlag:
		sFlag += 1
		if sFlag > 100: break
		pointcloud = {}
		facelist = {}
		print "Faces:", len(me.faces), " (amount:", amount, ")"
		if len(me.faces) <= amount:
			wFlag = False
			break;
		for i in me.faces:
			tx = ty = tz = 0
			for j in i.verts:
				tx += j.co[0]
				ty += j.co[1]
				tz += j.co[2]
			pointcloud[x][0]  = tx/len(i.verts)
			pointcloud[x][1]  = ty/len(i.verts)
			pointcloud[x][2]  = tz/len(i.verts)
			x += 1
		me2 = bpy.data.meshes.new('s_mesh')
		me2.verts.extend(pointcloud)
		
		x = 0
		for i in range(0,len(pointcloud),1):
			if len(pointcloud) - i < 4:
			print "LAST"
			facelist[x] = []
	"""
			
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def simplificate_old(ob, amount): # OBSOLOTE?!?!?!
	me = Mesh.Get(ob.getData(True))
	wFlag = True
	sFlag = 0
	while wFlag:
		sFlag += 1
		if sFlag > 100: break
		facelist = {}
		#x = 0
		#for i in me.faces:
		#	facelist[x] = i
		#	x += 1
		
		print "Faces:", len(me.faces), " (amount:", amount, ")"
		if len(me.faces) <= amount:
			wFlag = False
			break;
		
		"""
		for i in range(0,len(facelist),2):
			print i
			#facelist[i].edges.v1.co[0] = (facelist[i].edges.v1.co[0] + facelist[i].edges.v2.co[0])/2
			#facelist[i].edges.v1.co[1] = (facelist[i].edges.v1.co[1] + facelist[i].edges.v2.co[1])/2
			#facelist[i].edges.v1.co[2] = (facelist[i].edges.v1.co[2] + facelist[i].edges.v2.co[2])/2
			
			if len(facelist[i].verts) > 3:
				facelist[i].verts[2].co[0] = facelist[i].verts[1].co[0]
				facelist[i].verts[2].co[1] = facelist[i].verts[1].co[1]
				facelist[i].verts[2].co[2] = facelist[i].verts[1].co[2]
			else:
				facelist[i].verts[2].co[0] = facelist[i].verts[1].co[0]
				facelist[i].verts[2].co[1] = facelist[i].verts[1].co[1]
				facelist[i].verts[2].co[2] = facelist[i].verts[1].co[2]
		"""
		switch = 0
		for i in me.edges:
			#x = int(Rand(0,f_seed_sel1.val))
			#if x == 0:
			if switch == 0:
				i.v1.co[0] = (i.v1.co[0] + i.v2.co[0])/2
				i.v2.co[0] = i.v1.co[0]
				i.v1.co[1] = (i.v1.co[1] + i.v2.co[1])/2
				i.v2.co[1] = i.v1.co[1]
				i.v1.co[2] = (i.v1.co[2] + i.v2.co[2])/2
				i.v2.co[2] = i.v1.co[2]
				switch = 1
			else:
				switch = 0
			i.sel = 1
			
			#facelist[i].sel = 1
		
		rdb = me.remDoubles(0)
		print "removed:", rdb
		detect_free_triangle(ob)

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def define_quadrant():
	if field_menu.val == 1: # Cuboidal
		quadrant_border[0] =  f_dx.val
		quadrant_border[1] =  f_dx.val
		quadrant_border[2] =  f_dx.val
	if field_menu.val == 2: # Sphere
		quadrant_border[0] = f_radius1.val * 2
		quadrant_border[1] = f_radius1.val * 2
		quadrant_border[2] = f_radius1.val * 2
	if field_menu.val == 3 or field_menu.val == 6: # Torus/Rounded Ring
		quadrant_border[0] = f_radius1.val * 2
		quadrant_border[1] = f_radius1.val * 2
		quadrant_border[2] = f_radius3.val * 2
	if field_menu.val == 4 or field_menu.val == 5: # Flat Ring/Disk
		quadrant_border[0] = f_radius1.val * 2
		quadrant_border[1] = f_radius1.val * 2
		quadrant_border[2] = f_dz.val

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def assign_quadrant(met_number,x,y,z):
	cx = f_cx.val
	cy = f_cy.val
	cz = f_cz.val
	dx = quadrant_border[0]#f_dx.val
	dy = quadrant_border[1]#f_dy.val
	dz = quadrant_border[2]#f_dz.val
	max = f_maxsize.val
	q = max * 3
	if dx > q: qx = int(math.ceil((dx/max))) - 2
	else: qx = 1
	if dy > q: qy = int(math.ceil((dy/max))) - 2
	else: qy = 1
	if dz > q: qz = int(math.ceil((dz/max))) - 2
	else: qz = 1
	ax = int(math.ceil((x-(cx-(dx/2)))/max))
	ay = int(math.ceil((y-(cy-(dy/2)))/max))
	az = int(math.ceil((z-(cz-(dz/2)))/max))
	temp_list = [ax,ay,az]
	for i in range(0,6,1):
		if i == 0: tax = ax; tay = ay; taz = az
		if i == 1:
			if ax > 1: tax = ax-1 ; tay = ay; taz = az
			else: continue
		if i == 2:
			if ax < qx: tax = ax+1 ; tay = ay; taz = az
			else: continue
		if i == 3:
			if ay > 1: tax = ax ; tay = ay-1; taz = az
			else: continue
		if i == 4:
			if ay < qy: tax = ax ; tay = ay+1; taz = az
			else: continue
		if i == 5:
			if az > 1: tax = ax ; tay = ay; taz = az-1
			else: continue
		if i == 6:
			if az < qz: tax = ax ; tay = ay; taz = az+1
			else: continue
		
		if (tax,tay,taz) in quadrants:
			list = quadrants[(tax,tay,taz)]
			list.append(met_number)
		else: list = [met_number]
		quadrants[(tax,tay,taz)] = list
	return temp_list	
		
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def random_array(l_range,u_range):
	list = []
	for i in range(l_range + 1,u_range,1):
		x = Rand(0,1)
		list.append({x:i})
	list.sort()
	list2 = []
	for i in list:
		list2.append(i.values()[0])
	return list2		

# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#	
def check_object():
	if len(f_mesh_src.val) == 0: return
	obj = Object.Get()
	switch = False
	preset = f_mesh_src.val
	for i in obj:
		if i.getType() == "Mesh" and  i.getName() == preset:
			switch = True
			break
	if switch == False:
		f_mesh_src.val = ""
# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
def gui():
	global sect0_switch, sect1_switch, sect2_switch, sect3_switch, sect01_switch, sect02_switch
	global f_subsurf_p1, f_subsurf_p2,f_subsurf_p3, f_subsurf_p4, f_subsurf_p5, menu_subsurf, f_mesh_src, menu_field, field_menu, f_seed1, f_seed_sel1, f_seed_iter, f_ratio, f_rpm, shale_switch, f_maxsize, f_minsize, f_movement, mat_menu, f_cx, f_cy, f_cz, f_dx, f_sx, f_sy, f_sz, f_dx, f_dy, f_dz, f_amount, f_mindist, f_maxtrial, f_seed_meta, f_threshold, f_stiff, f_comp, f_brad_min, f_brad_max, smooth_switch, subsurf_switch, rand_switch, ipo_switch, simple_switch, hard_trial_switch, f_radius1, f_radius2, f_radius3, f_sradius1, f_sradius2, ss1_switch, ss2_switch, ss3_switch, ss4_switch, se1_switch, se2_switch, se3_switch, se4_switch, salt_mat_menu, ealt_mat_menu#, f_seed2
	ofs = 360 # Offset Y
	#sect0_val = sect1_val = sect2_val = sect3_val = 0
	#if sect0_val.val == 1: sect1_val.val = 0
	#if sect1_val.val == 1: sect0_val.val = 0
	sect0_switch = Toggle("Object", 2, 10, ofs, 70, 20, sect0_switch.val, "Section for creating and randomizing objects")
	sect1_switch = Toggle("Space", 3, 190, ofs, 70, 20, sect1_switch.val, "Section for sizing, placing, field structure and amount of objects")
	sect2_switch = Toggle("Material & IPO", 4, 85, ofs, 100, 20, sect2_switch.val, "Section for Material and IPO")
	sect3_switch = Toggle("View", 5, 265, ofs, 70, 20, sect3_switch.val, "Section for simplification")
	
	BGL.glEnable(BGL.GL_BLEND)
	BGL.glColor3i(0,0,0)
	BGL.glBegin(BGL.GL_LINES)
	BGL.glVertex2i(400, ofs-5)
	BGL.glVertex2i(5, ofs-5)
	BGL.glVertex2i(5, ofs-5)
	BGL.glVertex2i(5, ofs-325)
	BGL.glVertex2i(5, ofs-325)
	BGL.glVertex2i(400, ofs-325)
	BGL.glVertex2i(400, ofs-325)
	BGL.glVertex2i(400, ofs-5)
	BGL.glEnd()
	
	#BGL.glBegin(BGL.GL_LINES)
	#BGL.glVertex2i(5, ofs-320)
	#BGL.glVertex2i(400, ofs-320)
	#BGL.glEnd()	
	
	BGL.glDisable( BGL.GL_BLEND )
	
	mat_list = Material.Get()
	mat2 = 'Material %t'
	t_x = 1
	for mat in mat_list:
		mat2 = mat2 +  '|MA:' + mat.getName() + ' %x' + str(t_x)
		t_x = t_x + 1
	mat_name = mat2
	if sect0_switch == True:
		Blender.Draw.Label('Mesh source:', 10,ofs-25, 100, 20)
		sect01_switch = Toggle("Meta balls", 21, 10, ofs-45, 80, 20, sect01_switch.val, "Use randomized meta balls for mesh creation")
		sect02_switch = Toggle("Object", 22, 100, ofs-45, 80, 20, sect02_switch.val, "Use existing Object form your scene for mesh creation")
		f_mesh_src = String("OB:", 23, 190, ofs-45, 100, 20,f_mesh_src.val,100,"Select the source object")
		Blender.Draw.Label('Meta ball settings:', 10,ofs-70, 120, 20)
		f_seed_meta = Number("Meta ball seed: ", 99, 10, ofs-90, 160, 20, f_seed_meta.val, 2, 99,'Higher values cause more complex and quirky base mesh')
		f_threshold = Number("Threshold: ", 99, 170, ofs-90, 160, 20, f_threshold.val, 0., 5.,'Higher values make meta balls more sticky to each other')
		f_stiff = Number("Stiffness: ", 99, 10, ofs-110, 120, 20, f_stiff.val, 0., 10.,'Higher values make meta balls more stiff in relation to each other')
		f_comp = Number("Compactness: ", 99, 130, ofs-110, 140, 20, f_comp.val, 0., 2.,'Higher values make the single meta balls more divergent')
		f_brad_min = Number("Min.rad: ", 99, 10, ofs-130, 90, 20, f_brad_min.val, 1.0, 99.,'Minimal size of a meta ball')
		f_brad_max = Number("Max.rad: ", 99, 100, ofs-130, 90, 20, f_brad_max.val, 1.0, 99.,'Maximal size of a meta ball')			
		Blender.Draw.Label('Smoothing settings:', 10,ofs-155, 120, 20)
		smooth_switch = Toggle("Smooth", 99, 10, ofs-175, 80, 20, smooth_switch.val, "Enables 'Set Smooth' for all faces")
		subsurf_switch = Toggle("Subsurf", 99, 90, ofs-175, 80, 20, subsurf_switch.val, "Adds a Subsurf-modifier to every object")
		
		menu_subsurf = 'Subsurf algorithm %t|Catmull-Clark %x1|Simple Subdiv. %x2' # Offset + 1 to the real settings
		f_subsurf_p1 = Menu(menu_subsurf, 99, 10, ofs-205, 150, 20, f_subsurf_p1.val, 'Select the algorithm of the subsurf modifier')
		f_subsurf_p2 = Number("Levels: ", 99, 160, ofs-205, 100, 20, f_subsurf_p2.val, 1, 6,'Number subdivisions to perform')
		f_subsurf_p3 = Number("Render Levels: ", 99, 260, ofs-205, 130, 20, f_subsurf_p3.val, 1, 6,'Number subdivisions to perform when rendering')
		f_subsurf_p4 = Toggle("Optimal Draw", 99, 10, ofs-225, 100, 20, f_subsurf_p4.val, "Skip drawing/rendering of interior subdivided edges")
		f_subsurf_p5 = Toggle("Subsurf UV", 99, 110, ofs-225, 100, 20, f_subsurf_p5.val, "Use Subsurf to subdivide UVs")
		
		Blender.Draw.Label('Randomizing settings:', 10,ofs-250, 160, 20)
		rand_switch = Toggle("Enable Randomizing", 99, 10, ofs-270, 160, 20, rand_switch.val, "Enables randomizing for meta-generated or object-based meshes")
  
		f_seed_iter = Number("Randomizing iterations: ", 99, 10, ofs-295, 160, 20, f_seed_iter.val, 1., 10.,'Higher values cause more vertices and deformed shapes',)  
		f_seed_sel1 = Number("Selectionquote 1: ", 99, 10, ofs-315, 160, 20, f_seed_sel1.val, 1., 100.,'Higher values cause less selected vertices for randomization')  
		f_seed1 = Number("Displacement seed: ", 99, 170, ofs-315, 160, 20, f_seed1.val, 0., 99.,'Higher values cause more bumpy surface')
  
	elif sect1_switch == True:
		Blender.Draw.Label('Field settings:', 10,ofs-25, 100, 20)
		menu_field = 'Field geometry %t|Cuboidal %x1|Sphere %x2|Torus %x3|Flat Ring %x4|Flat Disk %x5|Rounded Disk %x6'
		field_menu = Menu(menu_field, 99, 10, ofs-45, 150, 20, field_menu.val, 'Select the field geometry')
		
		Label('Center of field:', 170, ofs-25, 180, 20)
		f_cx = Number("x: ", 99, 170, ofs-45, 50, 20, f_cx.val, -10000., 10000.)
		f_cy = Number("y: ", 99, 220, ofs-45, 50, 20, f_cy.val, -10000., 10000.)
		f_cz = Number("z: ", 99, 270, ofs-45, 50, 20, f_cz.val, -10000., 10000.)
		
		if field_menu.val == 1: # Cube
			param1 = 'Dimension of field'
			f_dx = Number("x: ", 99, 10, ofs-90, 50, 20, f_dx.val, 0, 10000., 'Width of field')
			f_dy = Number("y: ", 99, 60, ofs-90, 50, 20, f_dy.val, 0, 10000., 'Heighth of field')
			f_dz = Number("z: ", 99, 110, ofs-90, 50, 20, f_dz.val, 0, 10000., 'Depth of field')
		elif field_menu.val == 2: # Sphere
			param1 = 'Radius'
			f_radius1 = Number("R: ", 99, 10, ofs-90, 100, 20, f_radius1.val, 0, 10000., 'Radius of field')
		elif field_menu.val == 3: # Ring/torus
			param1 = 'Radius of torus'
			f_radius1 = Number("R: ", 99, 10, ofs-90, 100, 20, f_radius1.val, 0, 10000., 'Mainradius of field')
			Label('Ringradius', 120, ofs-70, 180, 20)
			f_radius2 = Number("r: ", 99, 120, ofs-90, 100, 20, f_radius2.val, 0, 10000., 'Radius of the ring')
		elif field_menu.val == 4: # Flat Ring
			param1 = 'Outher Radius'
			f_radius1 = Number("Ro: ", 99, 10, ofs-90, 100, 20, f_radius1.val, 0, 10000., 'Outher radius of field')
			Label('Inner Radius', 120, ofs-70, 180, 20)
			f_radius3 = Number("Ri: ", 99, 120, ofs-90, 100, 20, f_radius3.val, 0, 10000., 'Inner radius of field')
			Label('Height', 230, ofs-70, 180, 20)
			f_dz = Number("z: ", 99, 230, ofs-90, 100, 20, f_dz.val, 0, 10000., 'Height (z) of field')
		elif field_menu.val == 5: # Disk
			param1 = 'Radius'
			Label('Height', 120, ofs-70, 180, 20)
			f_radius1 = Number("R: ", 99, 10, ofs-90, 100, 20, f_radius1.val, 0, 10000., 'Outher radius of field')
			f_dz = Number("z: ", 99, 120, ofs-90, 100, 20, f_dz.val, 0, 10000., 'Height (z) of field')
		elif field_menu.val == 6: # Rounded Disk
			param1 = 'Radius of disk'
			f_radius1 = Number("R: ", 99, 10, ofs-90, 100, 20, f_radius1.val, 0, 10000., 'Mainradius of field')
			Label('Edgeradius', 120, ofs-70, 200, 20)
			f_radius2 = Number("r: ", 99, 120, ofs-90, 100, 20, f_radius2.val, 0, 10000., 'Edgeradius of the disk (radius * 2 = Height)')
			
			
		Label(param1, 10, ofs-70, 180, 20)
		Blender.Draw.Label('Objectsize settings:', 10,ofs-115, 160, 20)
		
		shale_switch = Toggle("prevent 'shale'", 99, 10, ofs-135, 100, 20, shale_switch.val, "Prevents flat geometries like 'cigars' or 'shale-plates'")
		f_ratio = Number("(x:y:z): ", 99, 110, ofs-135, 80, 20, f_ratio.val, 1., 99.,'Max.Ratio-variance')
		f_maxsize = Number("Max.size: ", 99, 10, ofs-155, 100, 20, f_maxsize.val, 0.1, 50.,'Max. size (X,Y or Z) of the objects')
		f_minsize = Number("Min.size: ", 99, 110, ofs-155, 100, 20, f_minsize.val, 0.001, 50., 'Min. size (X,Y or Z) of the objects')
		
		Blender.Draw.Label('Amount and placement:', 10,ofs-180, 160, 20)
		f_amount = Number("approx. amount ", 99, 10, ofs-200, 150, 20, f_amount.val, 1, 10000., 'approximately amount of objects, depending on colision and trials')
		hard_trial_switch = Toggle("hard trial", 99, 170, ofs-240, 60, 20, hard_trial_switch.val, "Try to place object nearby other objects after the last trial")
		f_mindist = Number("Min.distance ", 99, 10, ofs-220, 150, 20, f_mindist.val, 0, 99., 'Min. allowed distance between two objects')
		f_maxtrial = Number("Max.trials ", 99, 10, ofs-240, 150, 20, f_maxtrial.val, 1, 10000, 'Max. trials to place an object, before breaking the process: WARNING! Slow!!!')
		
	elif sect2_switch == True:
		Blender.Draw.Label('Material settings:', 10,ofs-25, 100, 20)
		mat_menu = Menu(mat_name, 2, 10, ofs-45, 150, 20, mat_menu.val, 'Select the Material')
		
		Blender.Draw.Label('IPO settings:', 10,ofs-70, 120, 20)
		ipo_switch = Toggle("Enable IPO", 31, 10, ofs-90, 100, 20, ipo_switch.val, "Enables IPO for every object")
		f_rpm = Number("Max.rpm: ", 5, 10, ofs-115, 130, 20, f_rpm.val, 0.000, 99.,'Max. revolutions in X-, Y- and Z-axis per minute')
		f_movement = Number("Max.movement: ", 5, 10, ofs-135, 180, 20, f_movement.val, 0.000, 99.,'Max. untits movement per minute')

	else:
		simple_switch = Toggle("Enable Simplification", 41, 10, ofs-30, 160, 20, simple_switch.val, "Enables simplification for rendering-optimization")
		Blender.Draw.Label('Center (Startpoint):', 10,ofs-50, 180, 20)
		f_sx = Number("x: ", 99, 10, ofs-70, 50, 20, f_sx.val, -10000., 10000.)
		f_sy = Number("y: ", 99, 60, ofs-70, 50, 20, f_sy.val, -10000., 10000.)
		f_sz = Number("z: ", 99, 110, ofs-70, 50, 20, f_sz.val, -10000., 10000.)
		Button("Camera", 42, 165, ofs-70, 70, 20, "Get Position of active Camera") 
		Blender.Draw.Label('Start of simplification:', 10,ofs-90, 180, 20)
		f_sradius1 = Number("Radius: ", 99, 10, ofs-110, 100, 20, f_sradius1.val, 0, 10000., 'Begin with simplification at this distance')
		Blender.Draw.Label('Still use from here...:', 10,ofs-130, 250, 20)
		ss1_switch = Toggle("Randomization", 43, 10, ofs-150, 90, 20, ss1_switch.val, "Use still randomization till endpoint")
		ss2_switch = Toggle("Subsurf", 44, 100, ofs-150, 50, 20, ss2_switch.val, "Use still subsurf till endpoint")
		ss3_switch = Toggle("Smooth", 45, 150, ofs-150, 50, 20, ss3_switch.val, "Use still smooth till endpoint")
		ss4_switch = Toggle("IPO", 46, 200, ofs-150, 30, 20, ss4_switch.val, "Use still IPO till endpoint")
		salt_mat_menu = Menu(mat_name, 47, 230, ofs-150, 150, 20, salt_mat_menu.val, 'Select the alternative material using from this point')
		
		
		Blender.Draw.Label('End of simplification:', 10,ofs-180, 180, 20)
		f_sradius2 = Number("Radius: ", 99, 10, ofs-200, 100, 20, f_sradius2.val, 0, 10000., 'End with simplification at this distance')
		Blender.Draw.Label('Still use after here...:', 10,ofs-220, 250, 20)
		se1_switch = Toggle("Randomization", 48, 10, ofs-240, 90, 20, se1_switch.val, "Use still randomization till endpoint")
		se2_switch = Toggle("Subsurf", 49, 100, ofs-240, 50, 20, se2_switch.val, "Use subsurf after endpoint")
		se3_switch = Toggle("Smooth", 410, 150, ofs-240, 50, 20, se3_switch.val, "Use smooth after endpoint")
		se4_switch = Toggle("IPO", 411, 200, ofs-240, 30, 20, se4_switch.val, "Use IPO after endpoint")
		ealt_mat_menu = Menu(mat_name, 412, 230, ofs-240, 150, 20, ealt_mat_menu.val, 'Select the alternative material using from this point')
		
	Button("Run", 100, 10, ofs-350, 100, 20, "Run")
	Button("Give me one!", 101, 120, ofs-350, 120, 20, "Returns one object at the cursor position") 
	Button("Exit", 1, 250, ofs-350, 100, 20, "Exit Script")
  

def event(evt, val):
	if (evt == QKEY and not val): Exit()
def bevent(evt):
	if evt == 1: Exit()
	if evt == 100: start1()
	if evt == 101: start2()
	
	if evt == 2:
		sect0_switch.val = True
		sect1_switch.val = False
		sect2_switch.val = False
		sect3_switch.val = False
	if evt == 3:
		sect0_switch.val = False
		sect1_switch.val = True
		sect2_switch.val = False
		sect3_switch.val = False
		
	if evt == 4:
		sect0_switch.val = False
		sect1_switch.val = False
		sect2_switch.val = True
		sect3_switch.val = False
		
	if evt == 5:
		sect0_switch.val = False
		sect1_switch.val = False
		sect2_switch.val = False
		sect3_switch.val = True
		
	if evt == 21:
		sect01_switch.val = True
		sect02_switch.val = False
	if evt == 22:
		sect01_switch.val = False
		sect02_switch.val = True
		
	if evt == 23: # Input object
		check_object()
		
	Window.Redraw(Window.Types.SCRIPT)
	
Register(gui, event, bevent)