#!BPY

"""
Name: 'PGR-Meandering-Paths'
Blender: 248
Group: 'Wizards'
Tooltip: 'Make meandering paths for 3D-patterns'
"""
__name__ = "PGR-Meandering-Paths"
__version__ = "0.1.5"
__author__ = ["Patrick Grochowy"]
__url__ = ("http://www.grochowy.de")
__bpydoc__ = """\
PGR-Meandering-Paths

This script creates meandering paths within a selected mesh as bounding-box.
The paths will meander along the x-axis, from left to right. The script uses
cross-sections of that mesh (calculated by dividing the total x-width by the
numver of steps) as bounding-area for the points to set. Depending on the
form of that mesh the result may be not as expected, because the script doesn't
actually "follow" the mesh, it just goes through it from left to right.<br>
So I advise to to keep the mesh form simple and avoid "curvyness".

To let you see the result instantly the script sets the drawType of that bb-mesh
to 'wire' (you'll find that under the blender objects-button "F7", panel "draw").
But that's just in the blender editor-windows, if your bb-mesh is a closed box
you will just see a closed form as render result, because the meandering paths
are inside that form.

All created objects are parented to an empty, the script creates (to keep the
outliner tidy).

- You can set the count of paths to create. The paths will have their
starting-points on the Y-Z-Plane of the bounding-box. You can also set the DefResolU-Value
for the paths, this will set the "smoothness" of the resulting curve. Blenders preset
is 12, the higher the number, the smoother the result, but the more Faces have to be
rendered.

- When you press the "Just Paths" button, it will create just the meandering 3D-paths.

- The "Startpoint distribution" buttons will set the type of distribution of the
starting points on the Y-Z-Plane of the bounding-box:<br>
<br>

  - "#1" will set the first point in the center of the Y-Z-Plane and distribute the
rest of points evenly on a circlish/oval circumference, which is half the bevelSize
away from the borders of the bounding-box

  - "#2" trys to stack the starting-points from bottom to top; this is still not optimal,
the count of paths may differ. If someone knows a solution for that, please tell me ...

  - "#3" distributes the starting points randomly and afterwards moves them away from
each other if their distance is less than the square root of ((Y*Z) / number of paths).
This can take some time, depending on your computer quite some time. After 10.000
rearrangements it gives up (then there are still overlappings), else the points sit far
away enough from each other. If you use this type of distribution and nothing seems to
happen, take a look at the console and you can watch the script working.

  - "#4" distributes the starting-points randomly. Because the script tries to avoid
overlapping, it first checks if the amount of paths by given bevelSize can fit into
the Y-Z-Plane. If not, it reduces the number of paths. It then distributes the starting
points randomly and afterwards moves them away from each other if their distance is less
than the bevel size (plus a buffer of 0.002). Again this can take quite some time.
If you use this type of distribution and nothing seems to happen, take a look at the
console and you can watch the script working.<br>

- The skript will also create a 2D-curve, which is then used as bevelObject for
the meandering paths. You can choose between a simple bezier-4-point-circle, a
vector-4-point-rectangle and a vector-six-point-hexagon.

This bevel-object will be placed 0.5 blender-units to the right of the bounding-area.
You can edit it afterwards to get a "extrusion-profile" that fits your needs. Just
press numpad-3 to have a plain look onto it.

You can set the diameter of this bevel-object with the "Bevel Size" slider and
again the DefResolU-value.

- The "Steps along x-axis" slider sets the number of steps in x-direction (the total
x-area-width divided by this number will be the step-size)

- The button "Paths end oppositely" will set the last point of each path oppositely
to its starting point (same Y and Z position).

- The "Type of meander" buttons set the type of meandering, just try the different types.

- You can select a material from the existing materials in your scene to be applied
to the resulting objects.

- The script will make a shape-key-driven animation for the paths, when you activate one
of the two buttons for Animation Type. '#1' animates the curves randomly on Y-Z-axis,
'#2' animates the curves randomly on X-Y-Z-axis.
- 'dmp' (damping) sets a value which divides the relocation-amount (10 * bevelSize).
The higher the value, the less movement. The lower the value, the more movement.
Paths may even leave the bounding-box partly then. Range is 1 to 50.
- 'frStps' sets the keyframe-rate of the animation: every
n'th frame an ipo-keyframe will be set on which the animated values will be newly set.
The lower the number the more hectic the paths will be.

- 'Sta' and 'End' set the start- and end-frame of the animation.

For each point of each curve a shape-key will be made on each keyframe and each key
gets it's ipo-curve. You can view (and edit) the ipo-curves in Blenders 'IPO-Curve-Editor'
(IPO-Type 'Shape').

When the 'Paths end oppositely' button is active, the start- and end-points of
the curves are not animated.

- If you deactivate the "Keep BB-Object" button, your selected BB-Object will be
unlinked (deleted) after the finishing of the meandering paths.

- The "Reset Values" button will reset the settings to the "delivery state" of the script.

- When you are not happy with the result, you can press "Erase all created objs"
which will unlink all objects, that were created during the scripts run-time. Don't get
confused when that count raises each time, Blender can not really delete objects, they
are just 'unlinked' from the scene and are not really gone, until you save and reopen
the Blender-file. The skript remembers all objects it created during it's run-time.

- The "Erase last created objs" button erases (unlinks) just the objects, that were
created during the last creation-run of the skript.

- When you've set all parameters, just press the "Make it so!" button, and the script
will create the meandering 3D-paths.

If you like the script, drop me a line and maybe you'll send me also some of your
resulting images/movies, where the meandering paths take part in ... ;-)

Patrick Grochowy, 14.11.2007
--

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, version 3 of the License.

See http://www.gnu.org/licenses/ for details or contact me:
patrick@grochowy.de - www.grochowy.de - gadgets.grochowy.de
"""
#################################################################################
# PGR-Meandering-Paths								#
#										#
# copyright October 2007 Patrick Grochowy						#
# PGR - Kommunikationsdesign - www.grochowy.de					#
#										#
# The most currrent version of PGR-Meandering-Paths is hosted at:		#
# http://gadgets.grochowy.de/pgr-meandering-paths/				#
#										#
# 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, version 3 of the License.			#
#										#
# 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, see http://www.gnu.org/licenses/.		#
#										#
#################################################################################
# History									#
# V0.0.1 - 23.10.2007:	- 1st release (needed something to create curvy paths	#
#			  quickly for a background-image)			#
# V0.0.2 - 24.10.2007:	- set the BB-Mesh drawType to wire, so that the		#
#			  user can see the result instantly even when a		#
#			  closed object was used as BB-mesh			#
# V0.0.3 - 24.10.2007:	- user can now preset the DevResolU for the		#
#			  bevelObject and the meandering paths			#
#			- added two types of erasing created objects; the user	#
#			- can now decide to erase all created objects or just	#
#			  the last created objects				#
# V0.0.4 - 25.10.2007:	- material assignment now works				#
#			- all created objects are now parented to an empty	#
#			- Blender.Window.RedrawAll() now Redraws all, after	#
#			  everything has been created				#
# V0.1.0 - 26.10.2007:	- changed positioning and rotation of bevelObject. It	#
#			  now sits 0.5 blender-units to the right of the	#
#			  bounding-box, so the user can see it in the		#
#			  right-view (numpad 3) in front of the meandering and	#
#			  the editing of the bevelObject does not result in 	#
#			  mirrored motions on the meandering-paths		#
#			- Optimized startpoint-distribution #2 a little		#
#			- changed meanderType buttons to display the names	#
#			  instead of numbers					#
#			- added shape-key-driven animation			#
# V0.1.1 - 26.10.2007:	- fixed the deformation problem when bb is offset	#
#			  on Y-axis or Z-axis; reason was, that the bevelobject	#
#			  was created on it's final position which led to	#
#			  totally deformed bevelPaths, when the bevelObject was	#
#			  then relocated to the final position. Now it's	#
#			  created at the scene-center and relocated afterwards	#
# V0.1.2 - 27.10.2007:	- changed the curve creation, so that the origin of 	#
#			  each curve sits in the center of the bound-box, not	#
#			  in the scenes 0,0,0 anymore				#
#			- fixed the meandertype values for screwy/screwy2	#
#			- changed the animation-damping-method			#
# V0.1.3 - 30.10.2007:	- Optimized startpoint-distribution #2 again		#
#			- Optimized startpoint-distribution #3; now tries to	#
#			  avoid overlapping					#
#			- when something went wrong, remainders are now		#
#			  silently erased (unlinked)				#
#			- removed "Paths may intersect" Toggle ;-)		#
# V0.1.4 - 10.11.2007:	- the meandering now can happen within deformed		#
#			  meshes, not just cubes/boxes				#
#			- the script now remembers it's last settings using	#
#			  Blenders "Registry" module.				#
# v0.1.5 - 14.11.2007:	- renamed startpoint-distribution #3 to #4 		#
#			  and optimized	it again (count-reducing)		#
#			  min. distance is bevelSize plus 0.002			#
#			- made new startpoint-distribution #3			#
#			  min. distance is sqrt((areaY*areaZ)/numbPaths)	#
#			- fixed wrong registry key-name (changed '-' to '_')	#
#################################################################################
# todo-list:									#
# - GUI ubersichtlicher machen							#
# - den Nutzer ein eigenes bevelObjekt auswahlen lassen				#
# - Pfaduberschneidungen optional unterbinden ;-)				#
#################################################################################
#################################################################################
# Import Stuff									#
#################################################################################

import Blender
import math

from Blender.Draw import *
from Blender.BGL import *
from Blender.Mathutils import *
from Blender import *

from math import *
import sys, traceback

#################################################################################
# Vars										#
#################################################################################
debug		= False # set to true to get lot of reporting
name		= __name__
version		= __version__

numbPaths	= Create(5)
numbPathsMin	= 1
numbPathsMax	= 250

numbSteps	= Create(5)
numbStepsMin	= 2
numbStepsMax	= 250

bevelSize	= Create(0.2)
bevelSizeMin	= 0.005
bevelSizeMax	= 10

defResolPaths	= Create(12)
defResolBObj	= Create(12)

animType	= 0
animTypeToggles	= ['',0,0]
animStepSize	= Create(25)
animDamp	= Create(10)

animStart	= Create(Scene.GetCurrent().getRenderingContext().sFrame)
animEnd		= Create(Scene.GetCurrent().getRenderingContext().eFrame)

keepBbToggle	= 1
justPathsToggle = 0
assignMat	= 0

distrType	= 1
distToggles	= ['', 1, 0, 0, 0]
distToggles[distrType] = 1

meanderType	= 3
tToggles	= ['', 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
typeNames	= ['','Straight','Tidy','Curvy','Edgy','Edgy2','Jumbled','Screwy','Screwy2','#9','#10','#11','#12']

intersectToggle = 1
oppositeToggle	= 0

bevObjType	= 1 #1: Circle, #2: Rectangle, #3: Hexagon)
bevObjToggles	= ['', 1, 0, 0]

createdObjs	= []
lastCreatedObjs	= []

vertsResetted = False

#################################################################################
# Console Print									#
#################################################################################
print ""
print "########################################################################"
print "# " + name + " - V" + version + "                                        #"
print "########################################################################"
print "#                                                                      #"
print "# This program is free software: you can redistribute it and/or modify #"
print "# it under the terms of the GNU General Public License as published by #"
print "# the Free Software Foundation, version 3 of the License.              #"
print "#                                                                      #"
print "# See http://www.gnu.org/licenses/ for more details or contact me.     #"
print "# patrick@grochowy.de - www.grochowy.de - gadgets.grochowy.de          #"
print "#                                                                      #"
print "########################################################################"
print ""
#################################################################################
# reset_settings() -- resets the settings to "delivery state" when called	#
#################################################################################
def reset_settings():
	print "reset settings"
	global numbPaths, numbSteps, bevelSize, defResolPaths,	defResolBObj
	global animType, animStepSize, animDamp
	global keepBbToggle, justPathsToggle, assignMat
	global distrType, meanderType
	global intersectToggle, oppositeToggle, bevObjType

	numbPaths.val	= 5
	numbSteps.val	= 5
	bevelSize.val	= 0.2
	defResolPaths.val = 12
	defResolBObj.val = 12

	animType	= 0
	animStepSize.val = 25
	animDamp.val	= 10

	keepBbToggle	= 1
	justPathsToggle = 0
	assignMat	= 0

	distrType	= 1

	meanderType	= 3

	intersectToggle = 1
	oppositeToggle	= 0

	bevObjType	= 1

	store_settings()
	Draw.Redraw(1)
#################################################################################
# store_settings() -- stores the actual settings to blenders "registry"		#
#################################################################################
def store_settings():
	print "store settings"
        d = {}
	d['numbPaths'] = numbPaths.val
	d['numbSteps'] = numbSteps.val
	d['bevelSize'] = bevelSize.val
	d['defResolPaths'] = defResolPaths.val
	d['defResolBObj'] = defResolBObj.val
	d['animType'] = animType
	d['animStepSize'] = animStepSize.val
	d['animDamp'] = animDamp.val
	d['keepBbToggle'] = keepBbToggle
	d['justPathsToggle'] = justPathsToggle
	d['assignMat'] = assignMat
	d['distrType'] = distrType
	d['meanderType'] = meanderType
	d['intersectToggle'] = intersectToggle
	d['oppositeToggle'] = oppositeToggle
	d['bevObjType'] = bevObjType
	Blender.Registry.SetKey('pgr_meandering_paths', d, True)
#################################################################################
# Get stored settings if any							#
#################################################################################
rdict = Registry.GetKey('pgr_meandering_paths', True) # True to check on disk also
if rdict: # if found, get the values saved there
	try:
		numbPaths.val = rdict['numbPaths']
		numbSteps.val = rdict['numbSteps']
		bevelSize.val = rdict['bevelSize']
		defResolPaths.val = rdict['defResolPaths']
		defResolBObj.val = rdict['defResolBObj']
		animType = rdict['animType']
		animStepSize.val= rdict['animStepSize']
		animDamp.val= rdict['animDamp']
		keepBbToggle = rdict['keepBbToggle']
		justPathsToggle = rdict['justPathsToggle']
		assignMat = rdict['assignMat']
		distrType = rdict['distrType']
		meanderType = rdict['meanderType']
		intersectToggle = rdict['intersectToggle']
		oppositeToggle = rdict['oppositeToggle']
		bevObjType = rdict['bevObjType']

		for i in range(1,13):
			if (i == meanderType):
				tToggles[i] = 1
			else:
				tToggles[i] = 0
		for i in range(1,5):
			if (i == distrType):
				distToggles[i] = 1
			else:
				distToggles[i] = 0
		for i in range(1,4):
			if (i == bevObjType):
				bevObjToggles[i] = 1
			else:
				bevObjToggles[i] = 0
		for i in range(3):
			if (i == animType):
				animTypeToggles[i] = 1
			else:
				animTypeToggles[i] = 0
	except:
		# if data isn't valid rewrite it
		print "no settings found or invalid; rewriting them ..."
		reset_settings()
#################################################################################
# GUI										#
#################################################################################
def gui():
	global numbPaths, defResolPaths, bevelSize, defResolBObj, numbSteps, materialSelect, assignMat
	global animStart, animEnd, animStepSize, animDamp
	### Build the Panel Header ###
	scrMaxX = 355
	glClearColor(0.5,0.5,0.5, 0.0)
	glColor3f(0.0,0.0,0.0)
	glClear(GL_COLOR_BUFFER_BIT)
	glRasterPos2i(10, 410)
	Draw.Text(".oO|", "large")
	glRasterPos2i(scrMaxX - GetStringWidth("|Oo.", "large"), 410)
	Draw.Text("|Oo.", "large")
	titleText = name + " - V" + version
	glRasterPos2i((scrMaxX / 2) - (GetStringWidth(titleText, "large") / 2), 410)
	Draw.Text(titleText, "large")
	glRasterPos2i(10, 407)
	Draw.Text("___________________________________________", "large")

	### Now the controls ###
	numbPaths = Slider("Count of paths: ", 10, 10, 380, 230, 18, numbPaths.val, numbPathsMin, numbPathsMax, 1, "Number of Paths")
	defResolPaths = Number("DefResolU: ", 10, 245, 380, 110, 18, defResolPaths.val, 1, 128, "Set the DefResolU of the Paths")

	Draw.Toggle("Just Paths", 13, 10, 355, 70, 18, justPathsToggle, "Just create the paths/curves")

	Label("Startpt. distribution:", 90, 355, 110, 18)
	BeginAlign()
	Draw.Toggle("#1", 25, 205, 355, 30, 18, distToggles[1], "Distribute starting points on Y-Z-Plane circlish (1st in the center)")
	Draw.Toggle("#2", 26, 245, 355, 30, 18, distToggles[2], "Distribute starting points on Y-Z-Plane stacked (count may differ)")
	Draw.Toggle("#3", 27, 285, 355, 30, 18, distToggles[3], "Distribute starting points on Y-Z-Plane randomly (paths may overlap)")
	Draw.Toggle("#4", 28, 325, 355, 30, 18, distToggles[4], "Distribute starting points on Y-Z-Plane randomly (reduces count of paths if too big)")
	EndAlign()

	Label("BevelObject Type:", 10, 330, 125, 18)
	BeginAlign()
	Draw.Toggle("Circle", 20, 125, 330, 70, 18, bevObjToggles[1], "Use circle as bevelObject")
	Draw.Toggle("Rectangle", 21, 205, 330, 70, 18, bevObjToggles[2], "Use rectangle as bevelObject")
	Draw.Toggle("Hexagon", 22, 285, 330, 70, 18, bevObjToggles[3],"Use hexagon as bevelObject")
	EndAlign()

	bevelSize = Slider("bvObj size: ", 11, 10, 305, 230, 18, bevelSize.val, bevelSizeMin, bevelSizeMax, 1, "Diameter of bevelObject")
	defResolBObj = Number("DefResolU: ", 11, 245, 305, 110, 18, defResolBObj.val, 1, 128, "Set the DefResolU of the bevelObject")

	numbSteps = Slider("Steps along x-axis: ", 12, 10, 280, 345, 18, numbSteps.val, numbStepsMin, numbStepsMax, 1, "Number of steps in x-direction")

	#Draw.Toggle("Paths may intersect", 16, 10, 255, 170, 18, intersectToggle, "Yes/No")
	Draw.Toggle("Paths end oppositely", 17, 185, 255, 170, 18, oppositeToggle, "Yes/No")

	Label("Type of meander:", 10, 230, 345, 19)
	Draw.Toggle(typeNames[1], 31, 10, 207, 53, 20, tToggles[1], "Type 1: Straight from left to right")
	Draw.Toggle(typeNames[2], 32, 68, 207, 53, 20, tToggles[2], "Type 2: Tidy")
	Draw.Toggle(typeNames[3], 33, 126, 207, 53, 20, tToggles[3], "Type 3: Curvy")
	Draw.Toggle(typeNames[4], 34, 184, 207, 53, 20, tToggles[4], "Type 4: Edgy")
	Draw.Toggle(typeNames[5], 35, 241, 207, 53, 20, tToggles[5], "Type 5: Edgy2")
	Draw.Toggle(typeNames[6], 36, 300, 207, 55, 20, tToggles[6], "Type 6: Jumbled")

	Draw.Toggle(typeNames[7], 37, 10, 182, 53, 20, tToggles[7], "Type 7: Screwy")
	Draw.Toggle(typeNames[8], 38, 68, 182, 53, 20, tToggles[8], "Type 8: Screwy2")
	#Draw.Toggle(typeNames[9], 39, 126, 182, 53, 20, tToggles[9], "Type 9: no function yet")
	#Draw.Toggle(typeNames[10], 40, 184, 182, 53, 20, tToggles[10], "Type 10: no function yet")
	#Draw.Toggle(typeNames[11], 41, 241, 182, 53, 20, tToggles[11], "Type 11: no function yet")
	#Draw.Toggle(typeNames[12], 42, 300, 182, 55, 20, tToggles[12], "Type 12: no function yet")

	Label("Material for objects:", 10, 157, 120, 18)
	materialSelect = Blender.Draw.Menu(getMaterials(), 19, 128, 157, 227, 18, assignMat, "Select material to assign to resulting objects")

	Label("Animation Type (no animation if not selected):", 10, 133, 275, 18)
	BeginAlign()
	Draw.Toggle("#1", 50, 280, 133, 35, 18, animTypeToggles[1], "Animation Type #1: animate Y-Z-Positions")
	Draw.Toggle("#2", 51, 320, 133, 35, 18, animTypeToggles[2], "Animation Type #2: animate X-Y-Z-Positions")
	EndAlign()

	animDamp = Number("dmp: ", 52, 10, 108, 80, 20, animDamp.val, 1, 50, "Damping; the higher, the less movement (1 to 50)")
	animStepSize = Number("frStps: ", 52, 95, 108, 80, 20, animStepSize.val, 1, 500, "Keyframe-Rate: every nth frame a keyframe will be set")
	animStart = Number("Sta: ", 60, 180, 108, 85, 20, animStart.val, 1, 18000, "The start frame of the animation")
	animEnd = Number("End: ", 60, 270, 108, 85, 20, animEnd.val, 1, 18000, "The end frame of the animation")

	Draw.Toggle("Keep preselected BB-Object", 18, 10, 80, 285, 18, keepBbToggle, "Keep your preselected BB-Object")
	PushButton("Reset", 7, 300, 80, 55, 18, "Reset values")

	PushButton("Erase all created objs", 5, 10, 55, 140, 18, "Delete all created objects. Count will raise each time, because blender can just unlink objects")
	PushButton("Erase last created objs", 6, 155, 55, 140, 18, "Delete objects that were created the last time.")
	PushButton("Help", 4, 300, 55, 55, 18, "Help")

	PushButton("Make it so!", 1, 10, 10, 285, 40, "Create meandering")
	PushButton("Exit", 2, 300, 10, 55, 40, "Exit script")
#################################################################################
# event(evt,val) -- catch ESC-key						#
#################################################################################
def event(evt, val):
	if (evt == QKEY and not val):
		store_settings()
		Exit()
#################################################################################
# bevent (evt) -- Button Events							#
#################################################################################
def bevent(evt):
	global keepBbToggle, justPathsToggle, intersectToggle, bevelSize, numbSteps
	global bevObjToggles, bevObjType, oppositeToggle, materialSelect, assignMat
	global tToggles, meanderType, distToggles, distrType
	global animTypeToggles, animType, animStepSize, animDamp
	if (evt == 1):
		makeMeander()
		Draw.Redraw(1)
	elif (evt == 2):
		store_settings()
		print "\nbye-bye ...\n"
		Exit()
	elif (evt == 4):
		print "\nHelp ...\n"
		show_help()
	elif (evt == 5):
		delete_all_objs()
		Draw.Redraw(1)
	elif (evt == 6):
		delete_last_objs(False)
		Draw.Redraw(1)
	elif (evt == 7):
		reset_settings()
		Draw.Redraw(1)
	elif (evt == 10):
		if (debug):
			print "\nnumbPaths:",numbPaths
			print "\ndefResolPaths:",defResolPaths
	elif (evt == 11):
		if (debug):
			print "\nbevelSize:",bevelSize
			print "\ndefResolBObj:",defResolBObj
	elif (evt == 12):
		if (debug):
			print "\nnumbSteps:",numbSteps
	elif (evt == 13):
		justPathsToggle = 1 - justPathsToggle
		Draw.Redraw(1)
		if (debug):
			print "\njustPathsToggle:",justPathsToggle
	elif (evt == 16):
		intersectToggle = 1 # out of function at the moment ;-)
		Draw.Redraw(1)
	elif (evt == 17):
		oppositeToggle = 1 - oppositeToggle
		Draw.Redraw(1)
		if (debug):
			print "\noppositeToggle:",oppositeToggle
	elif (evt == 18):
		keepBbToggle = 1 - keepBbToggle
		Draw.Redraw(1)
		if (debug):
			print "\nkeepBbToggle:",keepBbToggle
	elif (evt == 19):
		assignMat = materialSelect.val
	elif (evt == 20):
		bevObjType = 1
	elif (evt == 21):
		bevObjType = 2
	elif (evt == 22):
		bevObjType = 3
	elif (evt == 25):  # Startpoint distrib.#1
		distrType = 1
	elif (evt == 26):  # Startpoint distrib.#2
		distrType = 2
	elif (evt == 27):  # Startpoint distrib.#3
		distrType = 3
	elif (evt == 28):  # Startpoint distrib.#4
		distrType = 4
	elif (evt == 31):  # meandering Type 1
		meanderType = 1
	elif (evt == 32): # meandering Type 2
		meanderType = 2
	elif (evt == 33): # meandering Type 3
		meanderType = 3
	elif (evt == 34): # meandering Type 4
		meanderType = 4
	elif (evt == 35): # meandering Type 5
		meanderType = 5
	elif (evt == 36): # meandering Type 6
		meanderType = 6
	elif (evt == 37): # meandering Type 7
		meanderType = 7
	elif (evt == 38): # meandering Type 8
		meanderType = 8
	elif (evt == 39): # meandering Type 9
		meanderType = 9
	elif (evt == 40): # meandering Type 10
		meanderType = 10
	elif (evt == 41): # meandering Type 11
		meanderType = 11
	elif (evt == 42): # meandering Type 12
		meanderType = 12
	elif (evt == 50): # animation Type 1
		if (animType == 0):
			animType = 1
		elif (animType == 1):
			animType = 0
		else:
			animType = 1
	elif (evt == 51): # animation Type 2
		if (animType == 0):
			animType = 2
		elif (animType == 2):
			animType = 0
		else:
			animType = 2
	elif (evt == 52): # keyframe-rate and animation damping
		if (debug):
			print "animStepSize:",animStepSize.val
			print "animDamp:",animDamp.val

	# Set Toggles to their actual states

	for i in range(1,13):
		if (i == meanderType):
			tToggles[i] = 1
		else:
			tToggles[i] = 0

	for i in range(1,5):
		if (i == distrType):
			distToggles[i] = 1
		else:
			distToggles[i] = 0

	for i in range(1,4):
		if (i == bevObjType):
			bevObjToggles[i] = 1
		else:
			bevObjToggles[i] = 0
	for i in range(3):
		if (i == animType):
			animTypeToggles[i] = 1
		else:
			animTypeToggles[i] = 0

	Draw.Redraw(1)
#################################################################################
# show_help (script ...) -- display help					#
#################################################################################
def show_help(script = 'pgr_meandering_paths.py'):
	print script
	Blender.ShowHelp(script)
#################################################################################
# createParentEmpty() - creates an Empty as parent to all created stuff		#
#################################################################################
def parentObjs2Empty():
	global parentEmpty
	scn = Scene.GetCurrent()
	parentEmpty = scn.objects.new('Empty','MeanderObjsParent')
	parentEmpty.setLocation(centerX,centerY,centerZ)
	parentEmpty.makeParent(lastCreatedObjs, 0, 0)
	createdObjs.append(parentEmpty)
	lastCreatedObjs.append(parentEmpty)
	print ""
	print "made all just created Objects childs of:",parentEmpty.getName()
	print ""
	Draw.Redraw(1)
#################################################################################
# getMaterials() - get existing materials from Blender into into matMenu	#
#################################################################################
def getMaterials():
	matMenuTemp = ""
	bMaterials = Blender.Material.Get()
	i = 1
	for mat in bMaterials:
		newMat = str(mat.name)
		matMenuTemp = matMenuTemp + newMat + "%x" + str(i) + "|"
		i += 1
	matMenu = "Material menu %t|%l|No Material %x0|" + matMenuTemp
	return matMenu
#################################################################################
# delete_all_objs() - deletes allt created objects if any exists		#
#################################################################################
def delete_all_objs():
	if(createdObjs == []):
		print "no objects found"
		Draw.PupMenu("No objects found%t|OK")
	else:
		name = "Really delete all created objects?%t|Yes|No"
		result = Draw.PupMenu(name)
		if (result == 1):
			print ""
			scn = Scene.GetCurrent()
			i = 1
			for ob in createdObjs:
				if (debug):
					print "unlinking:",ob
				scn.objects.unlink(ob)
				i +=1
			print str(i) + " objects unlinked"
			Draw.PupMenu(str(i) + " objects unlinked%t|OK")
	Draw.Redraw(1)
#################################################################################
# delete_last_objs(silent) - deletes the just created objects if any exists	#
# if silent is True, do it without popup-menus					#
#################################################################################
def delete_last_objs(silent):
	global lastCreatedObjs, vertsResetted
	if(lastCreatedObjs == []):
		if (silent):
			print "something went wrong, but no remainders to erase"
		else:
			print "no objects found"
			Draw.PupMenu("No objects found%t|OK")
	else:
		if (silent):
			print "something went wrong, erasing remainders"
			scn = Scene.GetCurrent()
			i = 1
			for ob in lastCreatedObjs:
				if (debug):
					print "unlinking:",ob
				scn.objects.unlink(ob)
				i +=1
			lastCreatedObjs = []
		else:
			name = "Really delete last created objects?%t|Yes|No"
			result = Draw.PupMenu(name)
			if (result == 1):
				print ""
				scn = Scene.GetCurrent()
				i = 1
				for ob in lastCreatedObjs:
					if (debug):
						print "unlinking:",ob
					scn.objects.unlink(ob)
					i +=1
				print str(i) + " objects unlinked"
				Draw.PupMenu(str(i) + " objects unlinked%t|OK")
				lastCreatedObjs = []

	if (vertsResetted == False):
		bbObjMesh.verts = verts # Restore verts to original state.
		vertsResetted = True # set this to true. If it's false the cleanup will reset them
	Draw.Redraw(1)
#################################################################################
# leadZeros() - prefixes zeros and returns a string				#
#################################################################################
def leadZeros(number):
	numberStr = str(number)
	totalStr = str(numbPaths.val)
	nStrLen = len(numberStr)
	tStrLen = len(totalStr)
	while (tStrLen - nStrLen > 0):
		numberStr = "0" + numberStr
		nStrLen = len(numberStr)
	return numberStr
#################################################################################
# makeMeander()									#
#################################################################################
def makeMeander():
	try:
		if (getBB()):
			global selBbObject, lastCreatedObjs
			store_settings()
			lastCreatedObjs = []
			makeStepsBB()
			makeBevObj()
			makePaths()
			print ""
			print "setting drawType of BB-Mesh to wire"
			selBbObject[0].setDrawType(2)
			if (keepBbToggle == 0):
				scn = Scene.GetCurrent()
				print "deleting BB-Object:",selBbObject[0]
				scn.objects.unlink(selBbObject[0])
			parentObjs2Empty()
			if (animType != 0):
				animatePaths()
			Draw.Redraw(1)
	except:
		print ""
		print "Uups ... something went wrong ..."
		print ""
		traceback.print_exc(file=sys.stdout)
		delete_last_objs(True)
		store_settings()
		Draw.Redraw(1)
	Blender.Window.RedrawAll()
#################################################################################
# makePaths() -- create the meandering paths					#
#################################################################################
def makePaths():
	print ""
	print "numbPaths:",numbPaths
	print "bevelSize:",bevelSize
	print "intersectToggle:",intersectToggle

## Startpointdistribution Start ##
	moveMaxCount = 9999 # change this, if the script should try more often in #3 and #4
	startingPoints = [] # define list of starting points

	if (distrType == 1): # circlish distribution
		print ""
		print "... distribute startpoints circlish (1st at center)"
		radiusY = (baStepY[0] / 2) - bevelSize.val
		radiusZ = (baStepZ[0] / 2) - bevelSize.val

		# create first startingPoint in the center
		startingPoints.append(Vector(bbMinX - selBbLocX,centerStepY[0],centerStepZ[0])) # 1st starting point is center of BoundingArea

		# calculate the rest of starting points evenly set on a circle/oval within the Y-Z-Plane
		for i in range(1, numbPaths.val): # start with 1 because 0 is already created as 1st point
			angle = i * ( (math.pi*2) / (numbPaths.val - 1) )
			Y = math.cos(angle) * radiusY + centerStepY[0]
			Z = math.sin(angle) * radiusZ + centerStepZ[0]
			startingPoints.append(Vector(bbMinX - selBbLocX,Y,Z))
	elif (distrType == 2): # stacked distribution - don't know how to calculate that optimal :-(
		print ""
		print "... distribute startpoints stacked; count can differ"
		sqrtN = sqrt(numbPaths.val)
		stepsY = round(sqrtN * (baStepY[0] / baStepZ[0]))
		stepsZ = round(sqrtN * (baStepZ[0] / baStepY[0]))
		if (stepsZ < 1):
			stepsZ = 1
		stepsizeY = baStepY[0] / stepsY
		stepsizeZ = baStepZ[0] / stepsZ
		currZ = bbMinStepZ[0] + (stepsizeZ / 2)
		stepsYinitial = stepsY
		while (stepsZ > 0):
			stepsY = stepsYinitial
			currY = bbMinStepY[0] + (stepsizeY / 2)
			while (stepsY > 0):
				Y = currY
				Z = currZ
				startingPoints.append(Vector(bbMinX - selBbLocX,Y,Z))
				currY = currY + stepsizeY
				stepsY -= 1
			currZ = currZ + stepsizeZ
			stepsZ -= 1
	elif (distrType == 3): # random distribution optDist = sqrt((Y*Z) / numbPaths)
		print ""
		print "... distribute startpoints randomly #3"

		bevelRadius = bevelSize.val / 2

		for i in range(0, numbPaths.val): # now scatter the points
			rndY = Rand((bbMinStepY[0] + bevelRadius), (bbMaxStepY[0] - bevelRadius))
			rndZ = Rand((bbMinStepZ[0] + bevelRadius), (bbMaxStepZ[0] - bevelRadius))
			startingPoints.append(Vector(bbMinX - selBbLocX,rndY,rndZ))
		print ""
		print "checking distances:"

		optDist = math.sqrt( ( (baStepY[0] - bevelSize.val + 0.002) * (baStepZ[0] - bevelSize.val + 0.002) ) / numbPaths.val )

		if (debug):
			print "optDist:",optDist

		checkOK = False
		rearranged = False
		pointCount = len(startingPoints)
		moveCount = 0
		while (checkOK == False):
			tooOften = False
			i = 0
			while (i < pointCount):
				checkOK = True
				iInside = 0
				while (iInside < pointCount):
					if (startingPoints[i] != startingPoints[iInside]): # we don't want to check the point against itself
						distY = startingPoints[iInside][1] - startingPoints[i][1]
						distZ = startingPoints[iInside][2] - startingPoints[i][2]
						actDist = math.sqrt((distY * distY) + (distZ*distZ))
						if (actDist < optDist):
							rearranged = True
							checkOK = False

							print " point[" + str(i) + "] is too close to point[" + str(iInside) + "]"
							if (debug):
								print "   actDist:",actDist
							print "  moving startpoints ..."
							print "  moved startpoints " + str(moveCount + 1) + " times"

							targetY = startingPoints[i][1] + distY / actDist * optDist
							targetZ = startingPoints[i][2] + distZ / actDist * optDist
							moveY = targetY - startingPoints[iInside][1]
							moveZ = targetZ - startingPoints[iInside][2]

							startingPoints[i][1] -= moveY
							startingPoints[i][2] -= moveZ
							startingPoints[iInside][1] += moveY
							startingPoints[iInside][2] += moveZ

							if ( startingPoints[i][1] < bbMinStepY[0] + bevelRadius ):
								startingPoints[i][1] += bevelRadius
							elif ( startingPoints[i][1] > bbMaxStepY[0] - bevelRadius ):
								startingPoints[i][1] -= bevelRadius
							if ( startingPoints[i][2] < bbMinStepZ[0] + bevelRadius ):
								startingPoints[i][2] += bevelRadius
							elif ( startingPoints[i][2] > bbMaxStepZ[0] - bevelRadius ):
								startingPoints[i][2] -= bevelRadius

							if ( startingPoints[iInside][1] < bbMinStepY[0] + bevelRadius ):
								startingPoints[iInside][1] += bevelRadius
							elif ( startingPoints[iInside][1] > bbMaxStepY[0] - bevelRadius ):
								startingPoints[iInside][1] -= bevelRadius
							if ( startingPoints[iInside][2] < bbMinStepZ[0] + bevelRadius ):
								startingPoints[iInside][2] += bevelRadius
							elif ( startingPoints[iInside][2] > bbMaxStepZ[0] - bevelRadius ):
								startingPoints[iInside][2] -= bevelRadius

							moveCount += 1
							iInside = 0
							i = 0

						## have to check again for boundaries, so no point is left over
						if ( startingPoints[i][1] < bbMinStepY[0] + bevelRadius ):
							startingPoints[i][1] += bevelRadius
							moveCount += 1
						elif ( startingPoints[i][1] > bbMaxStepY[0] - bevelRadius ):
							startingPoints[i][1] -= bevelRadius
							moveCount += 1
						if ( startingPoints[i][2] < bbMinStepZ[0] + bevelRadius ):
							startingPoints[i][2] += bevelRadius
							moveCount += 1
						elif ( startingPoints[i][2] > bbMaxStepZ[0] - bevelRadius ):
							startingPoints[i][2] -= bevelRadius
							moveCount += 1

						if ( startingPoints[iInside][1] < bbMinStepY[0] + bevelRadius ):
							startingPoints[iInside][1] += bevelRadius
							moveCount += 1
						elif ( startingPoints[iInside][1] > bbMaxStepY[0] - bevelRadius ):
							startingPoints[iInside][1] -= bevelRadius
							moveCount += 1
						if ( startingPoints[iInside][2] < bbMinStepZ[0] + bevelRadius ):
							startingPoints[iInside][2] += bevelRadius
							moveCount += 1
						elif ( startingPoints[iInside][2] > bbMaxStepZ[0] - bevelRadius ):
							startingPoints[iInside][2] -= bevelRadius

						if (moveCount > moveMaxCount):
							tooOften = True
							break
					iInside += 1

				i += 1

			if (checkOK == True or tooOften == True):
				if (tooOften == True):
					print ""
					print "tried rearranging the points for " + str(moveCount) + " times. Giving up ... :-("
				elif (rearranged == True):
					print ""
					print "rearrangement of points succeeded ... :-)"
				else:
					print ""
					print "rearrangement of points wasn't necessary ... ;-)"
				break
	elif (distrType == 4): # random distribution optDist = bevelSize + 0.001
		print ""
		print "... distribute startpoints randomly #4"
		print "... checking if curves can fit into Y-Z-Plane"
		objFl = (bevelSize.val + 0.002) * (bevelSize.val + 0.002) # the area of one bevelobject plus a buffer
		yzSqr = (baStepY[0] - (bevelSize.val + 0.002)) * (baStepZ[0] - (bevelSize.val + 0.002)) # the Y-Z-Area we have to put them in
		if ( (numbPaths.val + 1) * objFl > yzSqr ):
			print ""
			print "  too many paths for Y-Z-Plane!"
			print "  reducing number of paths ..."
			numbPaths.val -= 1
			while ( (numbPaths.val + 1) * objFl > yzSqr ):
				numbPaths.val -= 1
			if (numbPaths.val < 1):
				numbPaths.val = 1

			print ""
			print "... had to reduce the number of paths to:",numbPaths.val

		bevelRadius = bevelSize.val / 2

		for i in range(0, numbPaths.val): # now scatter the points
			rndY = Rand((bbMinStepY[0] + bevelRadius), (bbMaxStepY[0] - bevelRadius))
			rndZ = Rand((bbMinStepZ[0] + bevelRadius), (bbMaxStepZ[0] - bevelRadius))
			startingPoints.append(Vector(bbMinX - selBbLocX,rndY,rndZ))
		print ""
		print "checking for overlapping:"

		optDist = bevelSize.val + 0.002

		if(debug):
			print "optDist:",optDist

		checkOK = False
		rearranged = False
		pointCount = len(startingPoints)
		moveCount = 0
		while (checkOK == False):
			tooOften = False
			i = 0
			while (i < pointCount):
				checkOK = True
				iInside = 0
				while (iInside < pointCount):
					if (startingPoints[i] != startingPoints[iInside]): # we don't want to check the point against itself
						distY = startingPoints[iInside][1] - startingPoints[i][1]
						distZ = startingPoints[iInside][2] - startingPoints[i][2]
						actDist = math.sqrt((distY * distY) + (distZ*distZ))
						if (actDist < optDist):
							rearranged = True
							checkOK = False

							print " point[" + str(i) + "] is too close to point[" + str(iInside) + "]"
							if (debug):
								print "  actDist:",actDist
							print "  moving startpoints ..."
							print "  moved startpoints " + str(moveCount + 1) + " times"

							targetY = startingPoints[i][1] + distY / actDist * optDist
							targetZ = startingPoints[i][2] + distZ / actDist * optDist
							moveY = targetY - startingPoints[iInside][1]
							moveZ = targetZ - startingPoints[iInside][2]

							startingPoints[i][1] -= moveY
							startingPoints[i][2] -= moveZ
							startingPoints[iInside][1] += moveY
							startingPoints[iInside][2] += moveZ

							if ( startingPoints[i][1] < bbMinStepY[0] + bevelRadius ):
								startingPoints[i][1] += bevelRadius
							elif ( startingPoints[i][1] > bbMaxStepY[0] - bevelRadius ):
								startingPoints[i][1] -= bevelRadius
							if ( startingPoints[i][2] < bbMinStepZ[0] + bevelRadius ):
								startingPoints[i][2] += bevelRadius
							elif ( startingPoints[i][2] > bbMaxStepZ[0] - bevelRadius ):
								startingPoints[i][2] -= bevelRadius

							if ( startingPoints[iInside][1] < bbMinStepY[0] + bevelRadius ):
								startingPoints[iInside][1] += bevelRadius
							elif ( startingPoints[iInside][1] > bbMaxStepY[0] - bevelRadius ):
								startingPoints[iInside][1] -= bevelRadius
							if ( startingPoints[iInside][2] < bbMinStepZ[0] + bevelRadius ):
								startingPoints[iInside][2] += bevelRadius
							elif ( startingPoints[iInside][2] > bbMaxStepZ[0] - bevelRadius ):
								startingPoints[iInside][2] -= bevelRadius

							moveCount += 1
							iInside = 0
							i = 0

						if (moveCount > moveMaxCount):
							tooOften = True
							break
					iInside += 1

				i += 1

			if (checkOK == True or tooOften == True):
				if (tooOften == True):
					print ""
					print "tried rearranging the points for " + str(moveCount) + " times. Giving up ... :-("
				elif (rearranged == True):
					print ""
					print "rearrangement of points succeeded ... :-)"
				else:
					print ""
					print "rearrangement of points wasn't necessary ... ;-)"
				break

## Startpointdistribution End ##

	print ""
	print "now making the meandering paths:"

	if (meanderType == 1): # "Straight"
		print " making a straight path ..."
	elif (meanderType == 2): # "Tidy"
			print " making a tidy path ..."
	elif (meanderType == 3): # "Curvy"
			print " making an curvy path ..."
	elif (meanderType == 4 or meanderType == 5): # "Edgy", "Edgy2"
			print " making an edgy path ..."
	elif (meanderType == 6): # "Jumbled"
			print " making a jumbled path ..."
	elif (meanderType == 7 or meanderType == 8): # "Screwy", "Screwy2"
			print " making a screwy path ..."

	curveCount = 1
	for vector in startingPoints: # create the curves starting point BezierTriples
		bt = BezTriple.New(vector[0], vector[1], vector[2])
		bt.handleTypes = (BezTriple.HandleTypes.ALIGN, BezTriple.HandleTypes.ALIGN)
		cu = Curve.New("MP-Curve_" + typeNames[meanderType] + "_" + leadZeros(curveCount))
		cu.setResolu(defResolPaths.val)
		cu.appendNurb(bt)
		cu.setFlag(7) # aktiviert 3D; keine Ahnung warum, bzw. wie man das Bitfield angibt
		cu_nurb = cu[0]

		if (meanderType == 1): # "Straight"
			for vector in makeMeanderPointsStraight(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()
		elif (meanderType == 2): # "Tidy"
			for vector in makeMeanderPointsTidy(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()
		elif (meanderType == 3): # "Curvy"
			for vector in makeMeanderPointsCurvy(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()
		elif (meanderType == 4 or meanderType == 5): # "Edgy", "Edgy2"
			for vector in makeMeanderPointsEdgy(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()
		elif (meanderType == 6): # "Jumbled"
			for vector in makeMeanderPointsJumbled(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()
		elif (meanderType == 7 or meanderType == 8): # "Screwy", "Screwy2"
			for vector in makeMeanderPointsScrewy(curveCount,Vector(vector[0],vector[1],vector[2])):
				mPntBt = BezTriple.New(vector[0], vector[1], vector[2])
				cu_nurb.append(mPntBt)
				cu_nurb.recalc()

		curveCount += 1
		for cuBt in cu_nurb:
			cuBt.handleTypes = [BezTriple.HandleTypes.AUTO, BezTriple.HandleTypes.AUTO]

		cu_nurb.setType(1)
		cu_nurb.recalc()

		### don't smooth the curve if the bevelobject is not a circle; not supported by Blender 2.45 ###
		#if (bevRectToggle == 1 or bevHexToggle == 1):
		#	cu_nurb.smooth = False
		### so we'll have to wait for a future version of Blender :-( ###

		scn = Scene.GetCurrent()
		ob = scn.objects.new(cu)

		ob.setLocation(bbObjLocation)

		Draw.Redraw(1)
		if (debug):
			print " created:",cu
			print " created:",ob
			print " DefResolU is set to:",defResolPaths.val
		createdObjs.append(ob)
		lastCreatedObjs.append(ob)

		if(assignMat > 0):
			matAssList = Blender.Material.Get()
			mat2ass = Material.Get(matAssList[assignMat-1].name)
			if (debug):
				print " assigning material:",mat2ass
			cu.materials = [mat2ass]

		if (justPathsToggle == 0):
			cu.setBevOb(bvObj)

		Draw.Redraw(1)

#################################################################################
# Start of the different meander-calculations					#
#################################################################################
#################################################################################
# makeMeanderPointsStraight() -- calculate the meandering points, Straight 	#
#################################################################################
def makeMeanderPointsStraight(curveCount,startPoint):
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos
	xStepDist = baX / numbSteps.val
	xStep = 0
	while ((xStep * xStepDist) < baX):
		pX = curr_pX
		pY = curr_pY
		pZ = curr_pZ
		# point calculation start
		pX = pX + xStepDist
		pY = pY
		pZ = pZ
		if (xStep < numbPaths.val):
			pY += centerStepY[xStep + 1] - centerStepY[xStep]
			pZ += centerStepZ[xStep + 1] - centerStepZ[xStep]
		# point calculation end

		# assign values to the new point
		currPoint = Vector(pX,pY,pZ)
		meanderPoints.append(currPoint)
		if (debug):
			print "  currPoint:",currPoint

		curr_pX = pX
		curr_pY = pY
		curr_pZ = pZ
		xStep += 1
	return meanderPoints
#################################################################################
# makeMeanderPointsTidy() -- calculate the meandering points, Tidy		#
#################################################################################
def makeMeanderPointsTidy(curveCount,startPoint):
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStepDist = baX / numbSteps.val
	xStep = 0
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos
	lastDir = 0
	while ((xStep * xStepDist) < baX):
		pX = curr_pX
		pY = curr_pY
		pZ = curr_pZ
		# point calculation start
		rndDir = math.floor((Rand(1,6)))
		if (rndDir == lastDir):
			if (debug):
				print "  ... we don't want the same direction again ..."
			xStep -= 1
		else:
			if (rndDir == 1): # nach Rechts
				pX = pX + xStepDist
				pY = pY
				pZ = pZ

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
			elif (rndDir == 2): # nach Unten
				pX = pX + xStepDist
				pY = pY
				pZ = pZ - xStepDist

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
			elif (rndDir == 3): # nach Oben
				pX = pX + xStepDist
				pY = pY
				pZ = pZ + xStepDist

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
			elif (rndDir == 4): # nach Nah
				pX = pX + xStepDist
				pY = pY + xStepDist
				pZ = pZ

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
			elif (rndDir == 5): # nach Fern
				pX = pX + xStepDist
				pY = pY - xStepDist
				pZ = pZ

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
			# assign values to the new point

			lastStep = False
			if ((curr_pX + xStepDist) >= bbMaxX - selBbLocX):
				lastStep = True

			if(lastStep & oppositeToggle):
				pY = yStartPos + centerStepY[xStep + 1] - centerStepY[0]
				pZ = zStartPos + centerStepZ[xStep + 1] - centerStepZ[0]

			currPoint = Vector(pX,pY,pZ)
			meanderPoints.append(currPoint)
			if (debug):
				print "  currPoint:",currPoint

			curr_pX = pX
			curr_pY = pY
			curr_pZ = pZ
			# point calculation end

		lastDir = rndDir
		xStep += 1
	return meanderPoints
#################################################################################
# makeMeanderPointsCurvy() -- calculate the meandering points, Type Curvy	#
#################################################################################
def makeMeanderPointsCurvy(curveCount,startPoint):
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStepDist = baX / numbSteps.val
	xStep = 0
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos
	while ((xStep * xStepDist) < baX):
		pX = curr_pX
		pY = curr_pY
		pZ = curr_pZ
		# point calculation start
		rndDir = math.floor((Rand(1,6)))
		if (rndDir == 1): # nach Rechts
			pX = pX + xStepDist
			pY = pY
			pZ = pZ

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		elif (rndDir == 2): # nach Unten
			pX = pX + xStepDist
			pY = pY
			pZ = pZ - xStepDist

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		elif (rndDir == 3): # nach Oben
			pX = pX + xStepDist
			pY = pY
			pZ = pZ + xStepDist

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		elif (rndDir == 4): # nach Nah
			pX = pX + xStepDist
			pY = pY + xStepDist
			pZ = pZ

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		elif (rndDir == 5): # nach Fern
			pX = pX + xStepDist
			pY = pY - xStepDist
			pZ = pZ

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		# point calculation end

		lastStep = False
		if ((curr_pX + xStepDist) >= bbMaxX - selBbLocX):
			lastStep = True
		if(lastStep & oppositeToggle):
			pY = yStartPos + centerStepY[xStep + 1] - centerStepY[0]
			pZ = zStartPos + centerStepZ[xStep + 1] - centerStepZ[0]

		# assign values to the new point
		currPoint = Vector(pX,pY,pZ)
		meanderPoints.append(currPoint)
		if (debug):
			print "  currPoint:",currPoint

		curr_pX = pX
		curr_pY = pY
		curr_pZ = pZ
		xStep += 1
	return meanderPoints
#################################################################################
# makeMeanderPointsEdgy() -- calculate the meandering points, Type Edgy		#
#################################################################################
def makeMeanderPointsEdgy(curveCount,startPoint):
	# Edgy = meander Type = 4 | Edgy2 = meanderType = 5
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStepDist = baX / numbSteps.val
	xStep = 0
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos
	lastDir = 1
	while ((xStep * xStepDist) < baX):
		pX = curr_pX
		pY = curr_pY
		pZ = curr_pZ
		# point calculation start
		rndDir = math.floor((Rand(1,6)))
		if (rndDir == 1): # nach Rechts
			pX = pX + xStepDist
			pY = pY
			pZ = pZ

			if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
				pY = bbMinStepY[xStep + 1] + bevelSize.val
			elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
				pY = bbMaxStepY[xStep + 1] - bevelSize.val
			if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
				pZ = bbMinStepZ[xStep + 1] + bevelSize.val
			elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
				pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
		elif (rndDir == 2): # nach Unten
			if (meanderType == 4):
				pX = pX
				pY = pY
				pZ = pZ - xStepDist

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
				xStep -= 1
			else:
				if (lastDir == 3):
					if (debug):
						print "  ... ups, I just came from there ..."
					xStep -= 1
				else:
					pX = pX
					pY = pY
					pZ = pZ - xStepDist

					if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
						pY = bbMinStepY[xStep + 1] + bevelSize.val
					elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
						pY = bbMaxStepY[xStep + 1] - bevelSize.val
					if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
						pZ = bbMinStepZ[xStep + 1] + bevelSize.val
					elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
						pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
					xStep -= 1
		elif (rndDir == 3): # nach Oben
			if (meanderType == 4):
				pX = pX
				pY = pY
				pZ = pZ + xStepDist

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
				xStep -= 1
			else:
				if (lastDir == 2):
					if (debug):
						print "  ... ups, I just came from there ..."
					xStep -= 1
				else:
					pX = pX
					pY = pY
					pZ = pZ + xStepDist

					if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
						pY = bbMinStepY[xStep + 1] + bevelSize.val
					elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
						pY = bbMaxStepY[xStep + 1] - bevelSize.val
					if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
						pZ = bbMinStepZ[xStep + 1] + bevelSize.val
					elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
						pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
					xStep -= 1
		elif (rndDir == 4): # nach Nah
			if (meanderType == 4):
				pX = pX
				pY = pY + xStepDist
				pZ = pZ

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
				xStep -= 1
			else:
				if (lastDir == 5):
					if (debug):
						print "  ... ups, I just came from there ..."
					xStep -= 1
				else:
					pX = pX
					pY = pY + xStepDist
					pZ = pZ

					if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
						pY = bbMinStepY[xStep + 1] + bevelSize.val
					elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
						pY = bbMaxStepY[xStep + 1] - bevelSize.val
					if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
						pZ = bbMinStepZ[xStep + 1] + bevelSize.val
					elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
						pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
					xStep -= 1
		elif (rndDir == 5): # nach Fern
			if (meanderType == 4):
				pX = pX
				pY = pY - xStepDist
				pZ = pZ

				if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
					pY = bbMinStepY[xStep + 1] + bevelSize.val
				elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
					pY = bbMaxStepY[xStep + 1] - bevelSize.val
				if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
					pZ = bbMinStepZ[xStep + 1] + bevelSize.val
				elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
					pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
				xStep -= 1
			else:
				if (lastDir == 4):
					if (debug):
						print "  ... ups, I just came from there ..."
					xStep -= 1
				else:
					pX = pX
					pY = pY - xStepDist
					pZ = pZ

					if (pY < bbMinStepY[xStep + 1] + bevelSize.val):
						pY = bbMinStepY[xStep + 1] + bevelSize.val
					elif (pY > bbMaxStepY[xStep + 1] - bevelSize.val):
						pY = bbMaxStepY[xStep + 1] - bevelSize.val
					if (pZ < bbMinStepZ[xStep + 1] + bevelSize.val):
						pZ = bbMinStepZ[xStep + 1] + bevelSize.val
					elif (pZ > bbMaxStepZ[xStep + 1] - bevelSize.val):
						pZ = bbMaxStepZ[xStep + 1] - bevelSize.val
					xStep -= 1
		lastDir = rndDir
		# point calculation end

		lastStep = False
		if ((curr_pX + xStepDist) >= bbMaxX - selBbLocX):
			lastStep = True
		if(lastStep & oppositeToggle):
			pY = yStartPos + centerStepY[xStep + 1] - centerStepY[0]
			pZ = zStartPos + centerStepZ[xStep + 1] - centerStepZ[0]

		# assign values to the new point
		currPoint = Vector(pX,pY,pZ)
		meanderPoints.append(currPoint)
		if (debug):
			print "  currPoint:",currPoint

		curr_pX = pX
		curr_pY = pY
		curr_pZ = pZ
		xStep += 1
	return meanderPoints
#################################################################################
# makeMeanderPointsJumbled() -- calculate the meandering points, jumbled	#
#################################################################################
def makeMeanderPointsJumbled(curveCount,startPoint):
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStepDist = baX / numbSteps.val
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos
	xStep = 0
	while ((xStep * xStepDist) < baX):
		pX = xStartPos
		pY = yStartPos
		pZ = zStartPos
		# point calculation start
		rndDir = math.floor((Rand(1,6)))
		if (rndDir == 1): # nach Rechts
			pX = Rand(bbMinX - selBbLocX, bbMaxX - selBbLocX + 0.001)
			pY = pY
			pZ = pZ
			xStep += Rand()
			if (debug):
				print "xStep:",xStep
		elif (rndDir == 2): # nach Unten
			pX = Rand(bbMinX - selBbLocX, bbMaxX - selBbLocX + 0.001)
			pY = pY
			pZ = Rand(bbMinZ - selBbLocZ, bbMaxZ - selBbLocZ + 0.001)
			xStep += Rand()
		elif (rndDir == 3): # nach Oben
			pX = Rand(bbMinX - selBbLocX, bbMaxX - selBbLocX + 0.001)
			pY = pY
			pZ = Rand(bbMinZ - selBbLocZ, bbMaxZ - selBbLocZ + 0.001)
			xStep += Rand()
		elif (rndDir == 4): # nach Nah
			pX = Rand(bbMinX - selBbLocX, bbMaxX - selBbLocX + 0.001)
			pY = Rand(bbMinY - selBbLocY, bbMaxY - selBbLocY + 0.001)
			pZ = pZ
			xStep += Rand()
		elif (rndDir == 5): # nach Fern
			pX = Rand(bbMinX - selBbLocX, bbMaxX - selBbLocX + 0.001)
			pY = Rand(bbMinY - selBbLocY, bbMaxY - selBbLocY + 0.001)
			pZ = pZ
			xStep += Rand()

		lastStep = False
		if ((xStep * xStepDist) >= baX):
			lastStep = True
		if(lastStep & oppositeToggle):
			if (debug):
				print "bbMaxX:",bbMaxX - selBbLocX
			pY = yStartPos
			pZ = zStartPos
			pX = bbMaxX - selBbLocX
			xStep = 1
			xStepDist = baX
		# assign values to the new point
		currPoint = Vector(pX,pY,pZ)
		meanderPoints.append(currPoint)
		if (debug):
			print "  currPoint:",currPoint
		# point calculation end
	return meanderPoints
#################################################################################
# makeMeanderPointsScrewy() -- calculate the meandering points, screwy		#
#################################################################################
def makeMeanderPointsScrewy(curveCount,startPoint):
	print " makeMeanderCurve#:",leadZeros(curveCount)
	meanderPoints = []
	xStepDist = baX / numbSteps.val
	xStartPos = startPoint[0]
	yStartPos = startPoint[1]
	zStartPos = startPoint[2]

	if (debug):
		print "  startPoint:",startPoint
	curr_pX = xStartPos
	curr_pY = yStartPos
	curr_pZ = zStartPos

	xStep = 0
	while ((xStep * xStepDist) < baX):
		pX = curr_pX
		pY = curr_pY
		pZ = curr_pZ
		# point calculation start

		pX += xStepDist
		angle = xStep * ( (math.pi*2) / 4 )
		if (meanderType == 7):
			radius = bevelSize.val
		elif (meanderType == 8):
			radius = bevelSize.val * 2
		pY = math.cos(angle) * radius + yStartPos + centerStepY[xStep]
		pZ = math.sin(angle) * radius + zStartPos + centerStepZ[xStep]

		if (xStep < numbPaths.val):
			if (debug):
				print "xStep:",xStep
			pY += centerStepY[xStep + 1] - centerStepY[xStep]
			pZ += centerStepZ[xStep + 1] - centerStepZ[xStep]

		# assign values to the new point
		currPoint = Vector(pX,pY,pZ)
		meanderPoints.append(currPoint)
		if (debug):
			print "  currPoint:",currPoint

		# point calculation end
		curr_pX = pX
		curr_pY = pY
		curr_pZ = pZ
		xStep += 1
	return meanderPoints
#################################################################################
# End of the different meander calculations					#
#################################################################################

#################################################################################
# animatePaths() -- animated the paths with shapekeys				#
#################################################################################
def animatePaths():
	print ""
	print "making animation ..."
	keyFramePos = [] # so we'll have a list of every frame where the shapes are strongest
	frameStepSize = animStepSize.val

	animCurves = []

	for obj in lastCreatedObjs:
		if (obj.name.startswith('MP-Curve_')):
			keyFramePos = []
			print ""
			print "  animating curve:",obj.name
			cu = obj.getData()
			animCurves.append(cu)

			Blender.Set('curframe', animStart.val)
			obj.insertShapeKey()
			keyFramePos.append(animStart.val)
			print "   inserted Basis shape key at frame:",animStart.val
			i = animStart.val + frameStepSize -1
			if (i > animEnd.val):
				i = animEnd.val - 1
				if (i <= 1):
					i = 1

			while (i <= animEnd.val):
				Blender.Set('curframe', i)
				for curNurb in cu: # step through all curNurbs in curve
					pointID = 0
					pointsEnd = len(curNurb) -1
					if (oppositeToggle == 1): # if paths should end oppositely, hands-off start- & endpoint
						pointID = 1
						pointsEnd -= 1

					while (pointID <= pointsEnd): # step through all points and relocate them (animate them)
						h1, p, h2 = curNurb[pointID].vec
						pX = p[0]
						pY = p[1]
						pZ = p[2]

						if (animType == 2): # animate also the X-direction
							pX = Rand( pX - ((10 * bevelSize.val) / animDamp.val), pX + ((10 * bevelSize.val) / animDamp.val) + 0.001 )
						pY = Rand( pY - ((10 * bevelSize.val) / animDamp.val), pY + ((10 * bevelSize.val) / animDamp.val) + 0.001 )
						pZ = Rand( pZ - ((10 * bevelSize.val) / animDamp.val), pZ + ((10 * bevelSize.val) / animDamp.val) + 0.001 )

						pNew = pX, pY, pZ
						curNurb[pointID].vec = h1, pNew, h2
						pointID += 1
				curNurb.recalc()
				obj.insertShapeKey()
				keyFramePos.append(i)
				print "   inserted next shape key at frame:",i
				i += frameStepSize

	keyFramePos.append(animEnd.val)

	for curve in animCurves:
		curveKey = curve.getKey()
		curveKey.ipo = Ipo.New('Key', curve.getName())
		curveKeyIpo = curveKey.ipo
		curveKeyAllKeys = curveKeyIpo.curveConsts
		for i in range(0,len(curveKeyAllKeys)):
			curve = curveKeyIpo.getCurve(i)
			if curve == None:
				curve = curveKeyIpo.addCurve(curveKeyAllKeys[i])

			if (i == 0): # the basis-key
				curve.append((keyFramePos[i],1))
				curve.append((keyFramePos[i+1],0))
				curve.append((keyFramePos[-1] - frameStepSize,0))
				curve.append((keyFramePos[-1],1))

			curve.append((keyFramePos[i] - frameStepSize,0))
			curve.append((keyFramePos[i],1))
			if (keyFramePos[i] + frameStepSize > keyFramePos[-1]): # when the frame is beyond Endframe set it to Endframe
				ipoXpos = keyFramePos[-1]
			else:
				ipoXpos = keyFramePos[i] + frameStepSize
			curve.append((ipoXpos,0))

			curve.interpolation = IpoCurve.InterpTypes.BEZIER
			curve.recalc()
	print ""
	print "animation type was:",animType
	if (animType == 1):
		print "so I animated the Y and Z positions of the curves points."
	else:
		print "so I animated the X, Y and Z positions of the curves points."
	print "first (key)frame is at:",keyFramePos[0]
	print "last (key)frame is at :",keyFramePos[-1]
	print "I skipped every " + str(frameStepSize) + " frames and made keyframes at:"
	print keyFramePos
	print ""
	Blender.Set('curframe', animStart.val)
#################################################################################
# getBB() -- get Bounding-Box to meander within					#
#################################################################################
def getBB():
	global selBbObject, bbObjName, bbObjMesh, bbObjLocation, selBbLocX, selBbLocY, selBbLocZ
	global bbMinX, bbMaxX, bbMinY, bbMaxY, bbMinZ, bbMaxZ, baX, baY, baZ, centerX, centerY, centerZ
	selBbObject = Blender.Object.GetSelected()
	try:
		for bbObj in selBbObject:
			bbObjName = bbObj.getName()
			bbObjType = bbObj.getType()
			bbObjLocation = bbObj.getLocation()
			bbObjSize = bbObj.getSize()
			bbBoundBox = bbObj.getBoundBox()
			bbObjMesh = Blender.Mesh.Get(bbObjName)
			print ""
			print "-- get bounding-box:"
			print " Selected Object Name:",bbObjName
			print " Type:", bbObjType
			print " Location:", bbObjLocation
			print " Bounding-Box:"
			for vec in bbBoundBox:
				print "    ",vec
			print ""
		if (bbObjType != 'Mesh'):
			print ""
			print "Error:\n selected object must be a Mesh ..."
			print " ... but selected object is a:",bbObjType,"\n"
			name = "Error:%t|selected object must be a Mesh ... but is a:" + bbObjType
			Draw.PupMenu(name)

		bbMinX = bbBoundBox[0][0]
		bbMaxX = bbBoundBox[4][0]
		bbMinY = bbBoundBox[0][1]
		bbMaxY = bbBoundBox[2][1]
		bbMinZ = bbBoundBox[0][2]
		bbMaxZ = bbBoundBox[1][2]

		baX = bbMaxX - bbMinX # BoundingAreaX
		baY = bbMaxY - bbMinY # BoundingAreaY
		baZ = bbMaxZ - bbMinZ # BoundingAreaZ

		centerX = bbMinX + ( baX / 2 )
		centerY = bbMinY + ( baY / 2 )
		centerZ = bbMinZ + ( baZ / 2 )

		selBbLocX = bbObjLocation[0]
		selBbLocY = bbObjLocation[1]
		selBbLocZ = bbObjLocation[2]

		return True
	except:
		print "\nError:\n No mesh as bounding-box selected\n"
		Draw.PupMenu("Error:%t|No mesh as bounding-box selected")
		return False
#################################################################################
# makeStepsBB() -- get the BB-Values for each step				#
#################################################################################
def makeStepsBB():
	global bbMinStepY, bbMaxStepY, bbMinStepZ, bbMaxStepZ, baStepY, baStepZ, centerStepY, centerStepZ
	global verts, vertsResetted

	XDirEdges = [[] for i in range(numbSteps.val + 1)]
	intersects = [[] for x in range(numbSteps.val + 1)]
	bbMinStepY = [[] for i in range(numbSteps.val + 1)]
	bbMaxStepY = [[] for i in range(numbSteps.val + 1)]
	bbMinStepZ = [[] for i in range(numbSteps.val + 1)]
	bbMaxStepZ = [[] for i in range(numbSteps.val + 1)]
	baStepY = [[] for i in range(numbSteps.val + 1)]
	baStepZ = [[] for i in range(numbSteps.val + 1)]
	centerStepY = [[] for i in range(numbSteps.val + 1)]
	centerStepZ = [[] for i in range(numbSteps.val + 1)]

	locOffset =  Vector(bbObjLocation)

	verts = bbObjMesh.verts[:] # Store the verts of selBbObjs Mesh for restoring them afterwards
	bbObjMesh.transform(selBbObject[0].matrix) # Transform verts to world-coordinates so the intersects are correct even if selBbObj is scaled
	vertsResetted = False # as long as this as False, the cleanup in delete_last_objs() will reset them.

	#xPosStep = [] ### kann weg, nur fur Testplanes
	xPos = bbMinX - locOffset[0]
	xStepDist = baX / numbSteps.val
	xStep = 0
	while (xStep < numbSteps.val + 1):
		for edge in bbObjMesh.edges:
			vec1 = Vector(xPos,bbMinY,bbMinZ)
			vec2 = Vector(xPos,bbMinY,bbMaxZ)
			vec3 = Vector(xPos,bbMaxY,bbMaxZ)

			if ( (edge.v1.co[0] - locOffset[0] < xPos) and (edge.v2.co[0] - locOffset[0] > xPos) ):
				XDirEdges[xStep].append(edge)
				intersects[xStep].append(Intersect(vec1, vec2, vec3, (edge.v1.co - locOffset) - (edge.v2.co - locOffset), edge.v2.co - locOffset, 0))
			elif ( (edge.v1.co[0] - locOffset[0] > xPos) and (edge.v2.co[0] - locOffset[0] < xPos) ):
				XDirEdges[xStep].append(edge)
				intersects[xStep].append(Intersect(vec1, vec2, vec3, (edge.v1.co - locOffset) - (edge.v2.co - locOffset), edge.v2.co - locOffset, 0))
			elif ( (edge.v1.co[0] - locOffset[0] < xPos) and (edge.v2.co[0] - locOffset[0] == xPos) ):
				XDirEdges[xStep].append(edge)
				intersects[xStep].append(Intersect(vec1, vec2, vec3, (edge.v1.co - locOffset) - (edge.v2.co - locOffset), edge.v2.co - locOffset, 0))
			elif ( (edge.v1.co[0] - locOffset[0] == xPos) and (edge.v2.co[0] - locOffset[0] > xPos) ):
				XDirEdges[xStep].append(edge)
				intersects[xStep].append(Intersect(vec1, vec2, vec3, (edge.v1.co - locOffset) - (edge.v2.co - locOffset), edge.v2.co - locOffset, 0))

		#print ""
		#print "intersects[" + str(xStep) + "]:"
		#for inters in intersects[xStep]:
		#	print "inters:",inters
		#	#if (inters):
		#	#	inters -= locOffset

		#xPosStep.append(xPos) ### kann weg, nur fur Testplanes
		xPos += xStepDist
		xStep += 1



	i = 0
	iLast = numbSteps.val + 1
	while (i < iLast):
		MinMaxY = []
		MinMaxZ = []
		if (i == 0):
			#print "ersten, i:",i
			for edge in XDirEdges[1]:
				if (edge.v1.co[0] < edge.v2.co[0]):
					MinMaxY.append(edge.v1.co[1] - locOffset[1])
					MinMaxZ.append(edge.v1.co[2] - locOffset[2])
				else:
					MinMaxY.append(edge.v2.co[1] - locOffset[1])
					MinMaxZ.append(edge.v2.co[2] - locOffset[2])

		elif (i == iLast - 1):
			#print "letzten, i:",i
			for edge in XDirEdges[i-1]:
				if (edge.v1.co[0] > edge.v2.co[0]):
					MinMaxY.append(edge.v1.co[1])
					MinMaxZ.append(edge.v1.co[2])
				else:
					MinMaxY.append(edge.v2.co[1])
					MinMaxZ.append(edge.v2.co[2])

		else:
			#print "dazwischen, i:",i
			for obj in intersects[i]:
				MinMaxY.append(obj[1])
				MinMaxZ.append(obj[2])

		MinMaxY.sort()
		MinMaxZ.sort()
		bbMinStepY[i] = MinMaxY[0]
		bbMaxStepY[i] = MinMaxY[-1]
		bbMinStepZ[i] = MinMaxZ[0]
		bbMaxStepZ[i] = MinMaxZ[-1]
		baStepY[i] = bbMaxStepY[i] - bbMinStepY[i]
		baStepZ[i] = bbMaxStepZ[i] - bbMinStepZ[i]
		centerStepY[i] = bbMinStepY[i] + ( baStepY[i] / 2 )
		centerStepZ[i] = bbMinStepZ[i] + ( baStepZ[i] / 2 )

		### create testplanes; just for checking ###
		#me = Mesh.Primitives.Plane(1)
		#sc = Scene.GetCurrent()
		#meObj = sc.objects.new(me,'Plane_Step_' + str(i))
		#meObj.setSize(baStepY[i],baStepZ[i],1)
		#print ""
		#print "Debugplane erzeugen"
		#print "xPosStep[" + str(i) +"]:",xPosStep[i]
		#print "centerStepY[" + str(i) +"]:",centerStepY[i]
		#print "centerStepZ[" + str(i) +"]:",centerStepZ[i]
		#print "---"
		#meObj.setLocation(xPosStep[i] + locOffset[0],centerStepY[i] + locOffset[1],centerStepZ[i] + locOffset[2])
		#meObj.RotX = radians(90)
		#meObj.RotZ = radians(-90)
		#createdObjs.append(meObj)
		#lastCreatedObjs.append(meObj)
		### ###

		bbObjMesh.verts = verts # Restore verts to original state.
		vertsResetted = True # set this to true. If it's false (something went wrong) the cleanup in delete_last_objs() will reset them

		i += 1

#################################################################################
# makeBev() -- create the object for bevelling					#
#################################################################################
def makeBevObj():
	global bvObj
	if (justPathsToggle == 0):
		bevType = ""
		if (bevObjType == 1):
			print "\nmake bevObject as circle ..."
			bevType = "Circle"
			bvCurvePoints = []
			bvCurvePoints.append(Vector(0,0+(bevelSize.val/2),0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/2),0,0))
			bvCurvePoints.append(Vector(0,0-(bevelSize.val/2),0))
			bvCurvePoints.append(Vector(0-(bevelSize.val/2),0,0))
		elif (bevObjType == 2):
			print "\nmake bevObject as rectangle ..."
			bevType = "Rectangle"
			bvCurvePoints = []
			bvCurvePoints.append(Vector(0-(bevelSize.val/2),0+(bevelSize.val/2),0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/2),0+(bevelSize.val/2),0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/2),0-(bevelSize.val/2),0))
			bvCurvePoints.append(Vector(0-(bevelSize.val/2),0-(bevelSize.val/2),0))
		elif (bevObjType == 3):
			print "\nmake bevObject as hexagon"
			bevType = "Hexagon"
			bvCurvePoints = []
			bvCurvePoints.append(Vector(0-(bevelSize.val/4),0+(bevelSize.val/2.309),0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/4),0+(bevelSize.val/2.309),0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/2),0,0))
			bvCurvePoints.append(Vector(0+(bevelSize.val/4),0-(bevelSize.val/2.309),0))
			bvCurvePoints.append(Vector(0-(bevelSize.val/4),0-(bevelSize.val/2.309),0))
			bvCurvePoints.append(Vector(0-(bevelSize.val/2),0,0))

		bvCurve = Curve.New('MP-BvObj_' + bevType)
		i = 0
		for vector in bvCurvePoints:
			if (i == 0):
				bvCurveBt = BezTriple.New(vector[0], vector[1], vector[2])
				bvCurve.appendNurb(bvCurveBt)
				bvCurveNurb = bvCurve[0]
				bvCurveNurb.recalc()
			else:
				bvCurveBt = BezTriple.New(vector[0], vector[1], vector[2])
				bvCurveNurb.append(bvCurveBt)
				bvCurveNurb.recalc()
			i += 1

		if (bevObjType == 1):
			for nBt in bvCurveNurb: # set all handles to AUTO
				nBt.handleTypes = [BezTriple.HandleTypes.AUTO, BezTriple.HandleTypes.AUTO]
		if (bevObjType == 2 or bevObjType == 3):
			for nBt in bvCurveNurb: # set all handles to VECT
				nBt.handleTypes = [BezTriple.HandleTypes.VECT, BezTriple.HandleTypes.VECT]

		bvCurveNurb.setType(1) # sets the curve-points to bezier
		bvCurveNurb.setFlagU(1) # sets the curve to cyclic
		bvCurveNurb.recalc() # recalc the curve
		bvCurve.setResolu(defResolBObj.val) # set the wanted DefResolU

		scn = Scene.GetCurrent()

		bvObj = scn.objects.new(bvCurve,'MP-BvObj_' + bevType)
		bvObj.setLocation(bbMaxX+0.5,centerY,centerZ)
		bvObj.RotX = radians(90)
		bvObj.RotZ = radians(-90)

		createdObjs.append(bvObj)
		lastCreatedObjs.append(bvObj)

		print " created:",bvCurve
		print " created:",bvObj
		print " DefResolU is set to:",defResolBObj.val
		Draw.Redraw(1)
	else:
		print ""
		print "make just the paths ..."
#################################################################################
# register GUI-Functions							#
#################################################################################
Register(gui, event, bevent)
